summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorChad MILLER <chad@mysql.com>2008-07-14 16:16:37 -0400
committerChad MILLER <chad@mysql.com>2008-07-14 16:16:37 -0400
commita4e7283a9254c09057c92ec20fc145c52bea1d51 (patch)
tree6009880c2c51b3422d95a760220fb7a20ebdb3e0 /sql
parentc425bf421da9ffa55d3d568f70508fa12dd07aa0 (diff)
parent55ab1ef6951428e0be31956e152537dec670e7df (diff)
downloadmariadb-git-a4e7283a9254c09057c92ec20fc145c52bea1d51.tar.gz
Merge from 5.0 trunk.
Diffstat (limited to 'sql')
-rw-r--r--sql/examples/ha_tina.cc2
-rw-r--r--sql/field.cc54
-rw-r--r--sql/field.h3
-rw-r--r--sql/ha_berkeley.cc8
-rw-r--r--sql/ha_blackhole.cc2
-rw-r--r--sql/ha_federated.cc2
-rw-r--r--sql/ha_innodb.cc2
-rw-r--r--sql/ha_ndbcluster.cc30
-rw-r--r--sql/ha_ndbcluster_cond.cc2
-rw-r--r--sql/handler.cc6
-rw-r--r--sql/handler.h2
-rw-r--r--sql/init.cc2
-rw-r--r--sql/item.cc54
-rw-r--r--sql/item_create.cc57
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_strfunc.cc6
-rw-r--r--sql/item_subselect.cc26
-rw-r--r--sql/item_sum.cc76
-rw-r--r--sql/item_sum.h7
-rw-r--r--sql/lock.cc2
-rw-r--r--sql/log.cc153
-rw-r--r--sql/my_decimal.h13
-rw-r--r--sql/mysql_priv.h21
-rw-r--r--sql/mysqld.cc29
-rw-r--r--sql/net_serv.cc4
-rw-r--r--sql/opt_range.cc96
-rw-r--r--sql/procedure.h2
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/share/charsets/README39
-rw-r--r--sql/share/errmsg.txt64
-rw-r--r--sql/sp.cc62
-rw-r--r--sql/sp_head.cc4
-rw-r--r--sql/sp_head.h1
-rw-r--r--sql/sql_acl.cc13
-rw-r--r--sql/sql_acl.h6
-rw-r--r--sql/sql_analyse.cc26
-rw-r--r--sql/sql_analyse.h2
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_class.cc7
-rw-r--r--sql/sql_db.cc2
-rw-r--r--sql/sql_delete.cc4
-rw-r--r--sql/sql_insert.cc28
-rw-r--r--sql/sql_lex.cc3
-rw-r--r--sql/sql_lex.h11
-rw-r--r--sql/sql_load.cc58
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_prepare.cc6
-rw-r--r--sql/sql_select.cc54
-rw-r--r--sql/sql_show.cc2
-rw-r--r--sql/sql_table.cc7
-rw-r--r--sql/sql_union.cc2
-rw-r--r--sql/sql_update.cc8
-rw-r--r--sql/sql_view.cc8
-rw-r--r--sql/sql_yacc.yy53
-rw-r--r--sql/tztime.cc6
-rw-r--r--sql/unireg.h1
56 files changed, 799 insertions, 349 deletions
diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc
index 0d1d821cf17..0b57fe86e62 100644
--- a/sql/examples/ha_tina.cc
+++ b/sql/examples/ha_tina.cc
@@ -883,7 +883,7 @@ int ha_tina::delete_all_rows()
DBUG_ENTER("ha_tina::delete_all_rows");
if (!records_is_known)
- return (my_errno=HA_ERR_WRONG_COMMAND);
+ DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND);
/* Invalidate all cached mmap pages */
if (free_mmap(share))
diff --git a/sql/field.cc b/sql/field.cc
index 53eafcaf2cc..d840034f8dc 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5868,6 +5868,7 @@ check_string_copy_error(Field_str *field,
Field_longstr::report_if_important_data()
ptr - Truncated rest of string
end - End of truncated string
+ count_spaces - Treat traling spaces as important data
RETURN VALUES
0 - None was truncated (or we don't count cut fields)
@@ -5877,10 +5878,12 @@ check_string_copy_error(Field_str *field,
Check if we lost any important data (anything in a binary string,
or any non-space in others). If only trailing spaces was lost,
send a truncation note, otherwise send a truncation error.
+ Silently ignore traling spaces if the count_space parameter is FALSE.
*/
int
-Field_longstr::report_if_important_data(const char *ptr, const char *end)
+Field_longstr::report_if_important_data(const char *ptr, const char *end,
+ bool count_spaces)
{
if ((ptr < end) && table->in_use->count_cuted_fields)
{
@@ -5890,10 +5893,13 @@ Field_longstr::report_if_important_data(const char *ptr, const char *end)
set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
else
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ return 2;
}
- else /* If we lost only spaces then produce a NOTE, not a WARNING */
+ else if (count_spaces)
+ { /* If we lost only spaces then produce a NOTE, not a WARNING */
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
- return 2;
+ return 2;
+ }
}
return 0;
}
@@ -5929,7 +5935,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length))
return 2;
- return report_if_important_data(from_end_pos, from + length);
+ return report_if_important_data(from_end_pos, from + length, FALSE);
}
@@ -6388,7 +6394,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length))
return 2;
- return report_if_important_data(from_end_pos, from + length);
+ return report_if_important_data(from_end_pos, from + length, TRUE);
}
@@ -6930,6 +6936,7 @@ uint32 Field_blob::get_length(const char *pos)
return (uint32) tmp;
}
}
+ /* When expanding this, see also MAX_FIELD_BLOBLENGTH. */
return 0; // Impossible
}
@@ -7024,7 +7031,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
cannot_convert_error_pos, from + length))
return 2;
- return report_if_important_data(from_end_pos, from + length);
+ return report_if_important_data(from_end_pos, from + length, TRUE);
oom_error:
/* Fatal OOM error */
@@ -8441,8 +8448,20 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
(fld_type_modifier & NOT_NULL_FLAG) && fld_type != FIELD_TYPE_TIMESTAMP)
flags|= NO_DEFAULT_VALUE_FLAG;
- if (fld_length && !(length= (uint) atoi(fld_length)))
- fld_length= 0; /* purecov: inspected */
+ if (fld_length != NULL)
+ {
+ errno= 0;
+ length= strtoul(fld_length, NULL, 10);
+ if ((errno != 0) || (length > MAX_FIELD_BLOBLENGTH))
+ {
+ my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name, MAX_FIELD_BLOBLENGTH);
+ DBUG_RETURN(TRUE);
+ }
+
+ if (length == 0)
+ fld_length= 0; /* purecov: inspected */
+ }
+
sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
switch (fld_type) {
@@ -8590,7 +8609,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
}
break;
case FIELD_TYPE_TIMESTAMP:
- if (!fld_length)
+ if (fld_length == NULL)
{
/* Compressed date YYYYMMDDHHMMSS */
length= MAX_DATETIME_COMPRESSED_WIDTH;
@@ -8599,12 +8618,21 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
{
/*
We support only even TIMESTAMP lengths less or equal than 14
- and 19 as length of 4.1 compatible representation.
+ and 19 as length of 4.1 compatible representation. Silently
+ shrink it to MAX_DATETIME_COMPRESSED_WIDTH.
*/
- length= ((length+1)/2)*2; /* purecov: inspected */
- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH); /* purecov: inspected */
+ DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
+ if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
+ length= ((length+1)/2)*2;
+ length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
}
flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ /*
+ Since we silently rewrite down to MAX_DATETIME_COMPRESSED_WIDTH bytes,
+ the parser should not raise errors unless bizzarely large.
+ */
+ max_field_charlength= UINT_MAX;
+
if (fld_default_value)
{
/* Grammar allows only NOW() value for ON UPDATE clause */
@@ -8711,7 +8739,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
((length > max_field_charlength && fld_type != FIELD_TYPE_SET &&
fld_type != FIELD_TYPE_ENUM &&
(fld_type != MYSQL_TYPE_VARCHAR || fld_default_value)) ||
- (!length &&
+ ((length == 0) &&
fld_type != MYSQL_TYPE_STRING &&
fld_type != MYSQL_TYPE_VARCHAR && fld_type != FIELD_TYPE_GEOMETRY)))
{
diff --git a/sql/field.h b/sql/field.h
index c82d65147ac..8d771a151a7 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -455,7 +455,8 @@ public:
class Field_longstr :public Field_str
{
protected:
- int report_if_important_data(const char *ptr, const char *end);
+ int report_if_important_data(const char *ptr, const char *end,
+ bool count_spaces);
public:
Field_longstr(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 84eaa82728a..12766b42bc2 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -467,7 +467,7 @@ berkeley_cmp_packed_key(DB *file, const DBT *new_key, const DBT *saved_key)
KEY_PART_INFO *key_part= key->key_part, *end=key_part+key->key_parts;
uint key_length=new_key->size;
- DBUG_DUMP("key_in_index", saved_key_ptr, saved_key->size);
+ DBUG_DUMP("key_in_index", (uchar *)saved_key_ptr, saved_key->size);
for (; key_part != end && (int) key_length > 0; key_part++)
{
int cmp;
@@ -903,7 +903,7 @@ DBT *ha_berkeley::create_key(DBT *key, uint keynr, char *buff,
key_length-=key_part->length;
}
key->size= (u_int32_t) (buff - (char*) key->data);
- DBUG_DUMP("key",(char*) key->data, key->size);
+ DBUG_DUMP("key",(uchar*) key->data, key->size);
DBUG_RETURN(key);
}
@@ -947,7 +947,7 @@ DBT *ha_berkeley::pack_key(DBT *key, uint keynr, char *buff,
key_length-=key_part->store_length;
}
key->size= (u_int32_t) (buff - (char*) key->data);
- DBUG_DUMP("key",(char*) key->data, key->size);
+ DBUG_DUMP("key",(uchar*) key->data, key->size);
DBUG_RETURN(key);
}
@@ -1705,7 +1705,7 @@ DBT *ha_berkeley::get_pos(DBT *to, byte *pos)
pos+=key_part->field->packed_col_length((char*) pos,key_part->length);
to->size= (uint) (pos- (byte*) to->data);
}
- DBUG_DUMP("key", (char*) to->data, to->size);
+ DBUG_DUMP("key", (uchar*) to->data, to->size);
return to;
}
diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc
index e477686d18e..01ede3d3bd2 100644
--- a/sql/ha_blackhole.cc
+++ b/sql/ha_blackhole.cc
@@ -115,7 +115,7 @@ const char *ha_blackhole::index_type(uint key_number)
int ha_blackhole::write_row(byte * buf)
{
DBUG_ENTER("ha_blackhole::write_row");
- DBUG_RETURN(0);
+ DBUG_RETURN(table->next_number_field ? update_auto_increment() : 0);
}
int ha_blackhole::rnd_init(bool scan)
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index d414dc34f02..2ccfeba74cb 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -1095,7 +1095,7 @@ bool ha_federated::create_where_from_key(String *to,
uint store_length= key_part->store_length;
uint part_length= min(store_length, length);
needs_quotes= 1;
- DBUG_DUMP("key, start of loop", (char *) ptr, length);
+ DBUG_DUMP("key, start of loop", (uchar *)ptr, length);
if (key_part->null_bit)
{
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 2d2007c8fdd..1be6137460b 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -4250,7 +4250,7 @@ ha_innobase::rnd_pos(
int error;
uint keynr = active_index;
DBUG_ENTER("rnd_pos");
- DBUG_DUMP("key", (char*) pos, ref_length);
+ DBUG_DUMP("key", (uchar *)pos, ref_length);
statistic_increment(current_thd->status_var.ha_read_rnd_count,
&LOCK_status);
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index a5cdc128724..0a75b328ca0 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -677,7 +677,7 @@ int ha_ndbcluster::set_ndb_key(NdbOperation *ndb_op, Field *field,
DBUG_PRINT("enter", ("%d: %s, ndb_type: %u, len=%d",
fieldnr, field->field_name, field->type(),
pack_len));
- DBUG_DUMP("key", (char*)field_ptr, pack_len);
+ DBUG_DUMP("key", (uchar*)field_ptr, pack_len);
DBUG_ASSERT(ndb_supported_type(field->type()));
DBUG_ASSERT(! (field->flags & BLOB_FLAG));
@@ -699,7 +699,7 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field,
DBUG_PRINT("enter", ("%d: %s, type: %u, len=%d, is_null=%s",
fieldnr, field->field_name, field->type(),
pack_len, field->is_null()?"Y":"N"));
- DBUG_DUMP("value", (char*) field_ptr, pack_len);
+ DBUG_DUMP("value", (uchar*) field_ptr, pack_len);
DBUG_ASSERT(ndb_supported_type(field->type()));
{
@@ -737,7 +737,7 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field,
// Set value to NULL
DBUG_RETURN((ndb_op->setValue(fieldnr, (char*)NULL, pack_len) != 0));
DBUG_PRINT("info", ("bit field"));
- DBUG_DUMP("value", (char*)&bits, pack_len);
+ DBUG_DUMP("value", (uchar*)&bits, pack_len);
#ifdef WORDS_BIGENDIAN
/* store lsw first */
bits = ((bits >> 32) & 0x00000000FFFFFFFFLL)
@@ -768,7 +768,7 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field,
DBUG_PRINT("value", ("set blob ptr: %p len: %u",
blob_ptr, blob_len));
- DBUG_DUMP("value", (char*)blob_ptr, min(blob_len, 26));
+ DBUG_DUMP("value", (uchar*)blob_ptr, min(blob_len, 26));
if (set_blob_value)
*set_blob_value= TRUE;
@@ -1007,8 +1007,8 @@ int ha_ndbcluster::get_metadata(const char *path)
("metadata, pack_length: %d getFrmLength: %d memcmp: %d",
pack_length, tab->getFrmLength(),
memcmp(pack_data, tab->getFrmData(), pack_length)));
- DBUG_DUMP("pack_data", (char*)pack_data, pack_length);
- DBUG_DUMP("frm", (char*)tab->getFrmData(), tab->getFrmLength());
+ DBUG_DUMP("pack_data", (uchar*)pack_data, pack_length);
+ DBUG_DUMP("frm", (uchar*)tab->getFrmData(), tab->getFrmLength());
error= 3;
invalidating_ndb_table= FALSE;
}
@@ -1502,7 +1502,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
int res;
DBUG_ENTER("pk_read");
DBUG_PRINT("enter", ("key_len: %u", key_len));
- DBUG_DUMP("key", (char*)key, key_len);
+ DBUG_DUMP("key", (uchar*)key, key_len);
NdbOperation::LockMode lm=
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
@@ -1514,7 +1514,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
{
// This table has no primary key, use "hidden" primary key
DBUG_PRINT("info", ("Using hidden key"));
- DBUG_DUMP("key", (char*)key, 8);
+ DBUG_DUMP("key", (uchar*)key, 8);
if (set_hidden_key(op, no_fields, key))
ERR_RETURN(trans->getNdbError());
@@ -1797,7 +1797,7 @@ int ha_ndbcluster::unique_index_read(const byte *key,
NdbIndexOperation *op;
DBUG_ENTER("ha_ndbcluster::unique_index_read");
DBUG_PRINT("enter", ("key_len: %u, index: %u", key_len, active_index));
- DBUG_DUMP("key", (char*)key, key_len);
+ DBUG_DUMP("key", (uchar*)key, key_len);
NdbOperation::LockMode lm=
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
@@ -2126,7 +2126,7 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
{
DBUG_PRINT("info", ("key %d:%d offset=%d length=%d last=%d bound=%d",
j, i, tot_len, part_len, p.part_last, p.bound_type));
- DBUG_DUMP("info", (const char*)p.part_ptr, part_store_len);
+ DBUG_DUMP("info", (const uchar*)p.part_ptr, part_store_len);
// Set bound if not cancelled via type -1
if (p.bound_type != -1)
@@ -2644,7 +2644,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
// Require that the PK for this record has previously been
// read into m_ref
- DBUG_DUMP("key", m_ref, NDB_HIDDEN_PRIMARY_KEY_LENGTH);
+ DBUG_DUMP("key", (uchar *)m_ref, NDB_HIDDEN_PRIMARY_KEY_LENGTH);
if (set_hidden_key(op, table->s->fields, m_ref))
ERR_RETURN(op->getNdbError());
@@ -2864,8 +2864,6 @@ void ha_ndbcluster::print_results()
DBUG_ENTER("print_results");
#ifndef DBUG_OFF
- if (!_db_on_)
- DBUG_VOID_RETURN;
char buf_type[MAX_FIELD_WIDTH], buf_val[MAX_FIELD_WIDTH];
String type(buf_type, sizeof(buf_type), &my_charset_bin);
@@ -3341,7 +3339,7 @@ void ha_ndbcluster::position(const byte *record)
memcpy(ref, m_ref, ref_length);
}
- DBUG_DUMP("ref", (char*)ref, ref_length);
+ DBUG_DUMP("ref", (uchar*)ref, ref_length);
DBUG_VOID_RETURN;
}
@@ -6263,7 +6261,7 @@ static int packfrm(const void *data, uint len,
}
DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", org_len, comp_len));
- DBUG_DUMP("compressed", (char*)data, org_len);
+ DBUG_DUMP("compressed", (uchar*)data, org_len);
error= 2;
blob_len= sizeof(frm_blob_struct::frm_blob_header)+org_len;
@@ -6307,7 +6305,7 @@ static int unpackfrm(const void **unpack_data, uint *unpack_len,
DBUG_PRINT("blob",("ver: %lu complen: %lu orglen: %lu",
ver,complen,orglen));
- DBUG_DUMP("blob->data", (char*) blob->data, complen);
+ DBUG_DUMP("blob->data", (uchar*) blob->data, complen);
if (ver != 1)
{
diff --git a/sql/ha_ndbcluster_cond.cc b/sql/ha_ndbcluster_cond.cc
index f5b41959b40..37e710acff4 100644
--- a/sql/ha_ndbcluster_cond.cc
+++ b/sql/ha_ndbcluster_cond.cc
@@ -1419,7 +1419,7 @@ int ha_ndbcluster_cond::generate_scan_filter_from_key(NdbScanOperation *op,
uint32 pack_len= field->pack_length();
const byte* ptr= key;
DBUG_PRINT("info", ("Filtering value for %s", field->field_name));
- DBUG_DUMP("key", (char*)ptr, pack_len);
+ DBUG_DUMP("key", (uchar*)ptr, pack_len);
if (key_part->null_bit)
{
DBUG_PRINT("info", ("Generating ISNULL filter"));
diff --git a/sql/handler.cc b/sql/handler.cc
index bfad10f986f..0de772e366b 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1980,6 +1980,8 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt)
}
}
}
+ if (table->s->frm_version != FRM_VER_TRUE_VARCHAR)
+ return HA_ADMIN_NEEDS_ALTER;
return check_for_upgrade(check_opt);
}
@@ -2348,8 +2350,8 @@ int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
if (!key_cache->key_cache_inited)
{
pthread_mutex_lock(&LOCK_global_system_variables);
- long tmp_buff_size= (long) key_cache->param_buff_size;
- long tmp_block_size= (long) key_cache->param_block_size;
+ ulong tmp_buff_size= (ulong) key_cache->param_buff_size;
+ uint tmp_block_size= (uint) key_cache->param_block_size;
uint division_limit= key_cache->param_division_limit;
uint age_threshold= key_cache->param_age_threshold;
pthread_mutex_unlock(&LOCK_global_system_variables);
diff --git a/sql/handler.h b/sql/handler.h
index 74c09d2d9ee..aa3377c3868 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -815,7 +815,7 @@ public:
{ return HA_ADMIN_NOT_IMPLEMENTED; }
/* end of the list of admin commands */
- virtual bool check_and_repair(THD *thd) { return HA_ERR_WRONG_COMMAND; }
+ virtual bool check_and_repair(THD *thd) { return TRUE; }
virtual int dump(THD* thd, int fd = -1) { return HA_ERR_WRONG_COMMAND; }
virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
diff --git a/sql/init.cc b/sql/init.cc
index b3b68926683..2dd2031cdaa 100644
--- a/sql/init.cc
+++ b/sql/init.cc
@@ -30,7 +30,7 @@ void unireg_init(ulong options)
wild_many='%'; wild_one='_'; wild_prefix='\\'; /* Change to sql syntax */
current_pid=(ulong) getpid(); /* Save for later ref */
- init_time(); /* Init time-functions (read zone) */
+ my_init_time(); /* Init time-functions (read zone) */
#ifndef EMBEDDED_LIBRARY
my_abort_hook=unireg_abort; /* Abort with close of databases */
#endif
diff --git a/sql/item.cc b/sql/item.cc
index c5b8d7a89ef..9ff1f8c0084 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -3931,9 +3931,9 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
}
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
goto error;
- else if (!ret)
- return FALSE;
outer_fixed= TRUE;
+ if (!ret)
+ goto mark_non_agg_field;
}
else if (!from_field)
goto error;
@@ -3945,9 +3945,9 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
int ret;
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
goto error;
- else if (!ret)
- return FALSE;
outer_fixed= 1;
+ if (!ret)
+ goto mark_non_agg_field;
}
/*
@@ -4013,6 +4013,26 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
thd->lex->current_select->non_agg_fields.push_back(this);
marker= thd->lex->current_select->cur_pos_in_select_list;
}
+mark_non_agg_field:
+ if (fixed && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
+ {
+ /*
+ Mark selects according to presence of non aggregated fields.
+ Fields from outer selects added to the aggregate function
+ outer_fields list as its unknown at the moment whether it's
+ aggregated or not.
+ */
+ if (!thd->lex->in_sum_func)
+ cached_table->select_lex->full_group_by_flag|= NON_AGG_FIELD_USED;
+ else
+ {
+ if (outer_fixed)
+ thd->lex->in_sum_func->outer_fields.push_back(this);
+ else if (thd->lex->in_sum_func->nest_level !=
+ thd->lex->current_select->nest_level)
+ cached_table->select_lex->full_group_by_flag|= NON_AGG_FIELD_USED;
+ }
+ }
return FALSE;
error:
@@ -4136,9 +4156,14 @@ static void convert_zerofill_number_to_string(Item **item, Field_num *field)
String tmp(buff,sizeof(buff), field->charset()), *res;
res= (*item)->val_str(&tmp);
- field->prepend_zeros(res);
- pos= (char *) sql_strmake (res->ptr(), res->length());
- *item= new Item_string(pos, res->length(), field->charset());
+ if ((*item)->is_null())
+ *item= new Item_null();
+ else
+ {
+ field->prepend_zeros(res);
+ pos= (char *) sql_strmake (res->ptr(), res->length());
+ *item= new Item_string(pos, res->length(), field->charset());
+ }
}
@@ -5482,13 +5507,16 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(*ref);
/*
Check if this is an incorrect reference in a group function or forward
- reference. Do not issue an error if this is an unnamed reference inside an
- aggregate function.
+ reference. Do not issue an error if this is:
+ 1. outer reference (will be fixed later by the fix_inner_refs function);
+ 2. an unnamed reference inside an aggregate function.
*/
- if (((*ref)->with_sum_func && name &&
- !(current_sel->linkage != GLOBAL_OPTIONS_TYPE &&
- current_sel->having_fix_field)) ||
- !(*ref)->fixed)
+ if (!((*ref)->type() == REF_ITEM &&
+ ((Item_ref *)(*ref))->ref_type() == OUTER_REF) &&
+ (((*ref)->with_sum_func && name &&
+ !(current_sel->linkage != GLOBAL_OPTIONS_TYPE &&
+ current_sel->having_fix_field)) ||
+ !(*ref)->fixed))
{
my_error(ER_ILLEGAL_REFERENCE, MYF(0),
name, ((*ref)->with_sum_func?
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 60a17c21521..c897b7aef79 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -464,8 +464,42 @@ Item *create_func_cast(Item *a, Cast_target cast_type,
case ITEM_CAST_TIME: res= new Item_time_typecast(a); break;
case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break;
case ITEM_CAST_DECIMAL:
- len= c_len ? atoi(c_len) : 0;
- dec= c_dec ? atoi(c_dec) : 0;
+ if (c_len == NULL)
+ {
+ len= 0;
+ }
+ else
+ {
+ ulong decoded_size;
+ errno= 0;
+ decoded_size= strtoul(c_len, NULL, 10);
+ if (errno != 0)
+ {
+ my_error(ER_TOO_BIG_PRECISION, MYF(0), c_len, a->name,
+ DECIMAL_MAX_PRECISION);
+ return NULL;
+ }
+ len= decoded_size;
+ }
+
+ if (c_dec == NULL)
+ {
+ dec= 0;
+ }
+ else
+ {
+ ulong decoded_size;
+ errno= 0;
+ decoded_size= strtoul(c_dec, NULL, 10);
+ if ((errno != 0) || (decoded_size > UINT_MAX))
+ {
+ my_error(ER_TOO_BIG_SCALE, MYF(0), c_dec, a->name,
+ DECIMAL_MAX_SCALE);
+ return NULL;
+ }
+ dec= decoded_size;
+ }
+
my_decimal_trim(&len, &dec);
if (len < dec)
{
@@ -486,8 +520,25 @@ Item *create_func_cast(Item *a, Cast_target cast_type,
}
res= new Item_decimal_typecast(a, len, dec);
break;
+
case ITEM_CAST_CHAR:
- len= c_len ? atoi(c_len) : -1;
+ if (c_len == NULL)
+ {
+ len= LL(-1);
+ }
+ else
+ {
+ ulong decoded_size;
+ errno= 0;
+ decoded_size= strtoul(c_len, NULL, 10);
+ if ((errno != 0) || (decoded_size > MAX_FIELD_BLOBLENGTH))
+ {
+ my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), "cast as char", MAX_FIELD_BLOBLENGTH);
+ return NULL;
+ }
+ len= decoded_size;
+ }
+
res= new Item_char_typecast(a, len, cs ? cs :
current_thd->variables.collation_connection);
break;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 87e547d1f89..1238efbb653 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -5115,7 +5115,7 @@ double Item_func_match::val_real()
DBUG_RETURN(-1.0);
if (key != NO_SUCH_KEY && table->null_row) /* NULL row from an outer join */
- return 0.0;
+ DBUG_RETURN(0.0);
if (join_key)
{
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 4e72f117869..c443364ce52 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -294,6 +294,12 @@ String *Item_func_concat::val_str(String *str)
{
if (!(res=args[i]->val_str(str)))
goto null;
+ /*
+ CONCAT accumulates its result in the result of its the first
+ non-empty argument. Because of this we need is_const to be
+ evaluated only for it.
+ */
+ is_const= args[i]->const_item() || !args[i]->used_tables();
}
else
{
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index b3710841dfb..401751660fd 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1232,7 +1232,11 @@ Item_in_subselect::row_value_transformer(JOIN *join)
Item *item_having_part2= 0;
for (uint i= 0; i < cols_num; i++)
{
- DBUG_ASSERT(left_expr->fixed && select_lex->ref_pointer_array[i]->fixed);
+ DBUG_ASSERT(left_expr->fixed &&
+ select_lex->ref_pointer_array[i]->fixed ||
+ (select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
+ ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
+ Item_ref::OUTER_REF));
if (select_lex->ref_pointer_array[i]->
check_cols(left_expr->element_index(i)->cols()))
DBUG_RETURN(RES_ERROR);
@@ -1306,7 +1310,11 @@ Item_in_subselect::row_value_transformer(JOIN *join)
for (uint i= 0; i < cols_num; i++)
{
Item *item, *item_isnull;
- DBUG_ASSERT(left_expr->fixed && select_lex->ref_pointer_array[i]->fixed);
+ DBUG_ASSERT(left_expr->fixed &&
+ select_lex->ref_pointer_array[i]->fixed ||
+ (select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
+ ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
+ Item_ref::OUTER_REF));
if (select_lex->ref_pointer_array[i]->
check_cols(left_expr->element_index(i)->cols()))
DBUG_RETURN(RES_ERROR);
@@ -1434,6 +1442,19 @@ Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
+ {
+ /*
+ IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
+ ORDER BY clause becomes meaningless thus we drop it here.
+ */
+ SELECT_LEX *sl= current->master_unit()->first_select();
+ for (; sl; sl= sl->next_select())
+ {
+ if (sl->join)
+ sl->join->order= 0;
+ }
+ }
+
if (changed)
{
DBUG_RETURN(RES_OK);
@@ -1468,6 +1489,7 @@ Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
transformed= 1;
arena= thd->activate_stmt_arena_if_needed(&backup);
+
/*
Both transformers call fix_fields() only for Items created inside them,
and all that items do not make permanent changes in current item arena
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 3d6d46ab3f4..91320d6b56b 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -66,6 +66,7 @@ bool Item_sum::init_sum_func_check(THD *thd)
aggr_sel= NULL;
max_arg_level= -1;
max_sum_func_level= -1;
+ outer_fields.empty();
return FALSE;
}
@@ -175,6 +176,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
MYF(0));
return TRUE;
}
+
if (in_sum_func)
{
/*
@@ -195,6 +197,68 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
set_if_bigger(in_sum_func->max_sum_func_level, max_sum_func_level);
}
+
+ /*
+ Check that non-aggregated fields and sum functions aren't mixed in the
+ same select in the ONLY_FULL_GROUP_BY mode.
+ */
+ if (outer_fields.elements)
+ {
+ Item_field *field;
+ /*
+ Here we compare the nesting level of the select to which an outer field
+ belongs to with the aggregation level of the sum function. All fields in
+ the outer_fields list are checked.
+
+ If the nesting level is equal to the aggregation level then the field is
+ aggregated by this sum function.
+ If the nesting level is less than the aggregation level then the field
+ belongs to an outer select. In this case if there is an embedding sum
+ function add current field to functions outer_fields list. If there is
+ no embedding function then the current field treated as non aggregated
+ and the select it belongs to is marked accordingly.
+ If the nesting level is greater than the aggregation level then it means
+ that this field was added by an inner sum function.
+ Consider an example:
+
+ select avg ( <-- we are here, checking outer.f1
+ select (
+ select sum(outer.f1 + inner.f1) from inner
+ ) from outer)
+ from most_outer;
+
+ In this case we check that no aggregate functions are used in the
+ select the field belongs to. If there are some then an error is
+ raised.
+ */
+ List_iterator<Item_field> of(outer_fields);
+ while ((field= of++))
+ {
+ SELECT_LEX *sel= field->cached_table->select_lex;
+ if (sel->nest_level < aggr_level)
+ {
+ if (in_sum_func)
+ {
+ /*
+ Let upper function decide whether this field is a non
+ aggregated one.
+ */
+ in_sum_func->outer_fields.push_back(field);
+ }
+ else
+ sel->full_group_by_flag|= NON_AGG_FIELD_USED;
+ }
+ if (sel->nest_level > aggr_level &&
+ (sel->full_group_by_flag & SUM_FUNC_USED) &&
+ !sel->group_list.elements)
+ {
+ my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
+ ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
+ return TRUE;
+ }
+ }
+ }
+ aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
update_used_tables();
thd->lex->in_sum_func= in_sum_func;
return FALSE;
@@ -1206,7 +1270,15 @@ my_decimal *Item_sum_avg::val_decimal(my_decimal *val)
null_value=1;
return NULL;
}
- sum_dec= Item_sum_sum::val_decimal(&sum_buff);
+
+ /*
+ For non-DECIMAL hybrid_type the division will be done in
+ Item_sum_avg::val_real().
+ */
+ if (hybrid_type != DECIMAL_RESULT)
+ return val_decimal_from_real(val);
+
+ sum_dec= dec_buffs + curr_dec_buff;
int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &cnt);
my_decimal_div(E_DEC_FATAL_ERROR, val, sum_dec, &cnt, prec_increment);
return val;
@@ -3150,7 +3222,7 @@ void Item_func_group_concat::clear()
no_appended= TRUE;
if (tree)
reset_tree(tree);
- if (distinct)
+ if (unique_filter)
unique_filter->reset();
/* No need to reset the table as we never call write_row */
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index bf0abe53eea..d39fc96e254 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -239,6 +239,13 @@ public:
int8 max_arg_level; /* max level of unbound column references */
int8 max_sum_func_level;/* max level of aggregation for embedded functions */
bool quick_group; /* If incremental update of fields */
+ /*
+ This list is used by the check for mixing non aggregated fields and
+ sum functions in the ONLY_FULL_GROUP_BY_MODE. We save all outer fields
+ directly or indirectly used under this function it as it's unclear
+ at the moment of fixing outer field whether it's aggregated or not.
+ */
+ List<Item_field> outer_fields;
protected:
table_map used_tables_cache;
diff --git a/sql/lock.cc b/sql/lock.cc
index d0576202606..4927146d96b 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -703,7 +703,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
{
my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0), table_ptr[i]->s->db,
table_ptr[i]->s->table_name);
- return 0;
+ DBUG_RETURN(0);
}
}
diff --git a/sql/log.cc b/sql/log.cc
index 15e8679171c..9e112e46c65 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1180,6 +1180,8 @@ int MYSQL_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
RETURN VALUES
0 ok
LOG_INFO_EOF to_log not found
+ LOG_INFO_FATAL if any other than ENOENT error from
+ my_stat() or my_delete()
*/
int MYSQL_LOG::purge_logs(const char *to_log,
@@ -1208,33 +1210,75 @@ int MYSQL_LOG::purge_logs(const char *to_log,
while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
!log_in_use(log_info.log_file_name))
{
- ulong file_size= 0;
- if (decrease_log_space) //stat the file we want to delete
+ MY_STAT s;
+ if (!my_stat(log_info.log_file_name, &s, MYF(0)))
{
- MY_STAT s;
-
- /*
- If we could not stat, we can't know the amount
- of space that deletion will free. In most cases,
- deletion won't work either, so it's not a problem.
- */
- if (my_stat(log_info.log_file_name,&s,MYF(0)))
- file_size= s.st_size;
- else
- sql_print_information("Failed to execute my_stat on file '%s'",
+ if (my_errno == ENOENT)
+ {
+ /*
+ It's not fatal if we can't stat a log file that does not exist;
+ If we could not stat, we won't delete.
+ */
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
+ log_info.log_file_name);
+ sql_print_information("Failed to execute my_stat on file '%s'",
log_info.log_file_name);
+ my_errno= 0;
+ }
+ else
+ {
+ /*
+ Other than ENOENT are fatal
+ */
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_BINLOG_PURGE_FATAL_ERR,
+ "a problem with getting info on being purged %s; "
+ "consider examining correspondence "
+ "of your binlog index file "
+ "to the actual binlog files",
+ log_info.log_file_name);
+ error= LOG_INFO_FATAL;
+ goto err;
+ }
+ }
+ else
+ {
+ DBUG_PRINT("info",("purging %s",log_info.log_file_name));
+ if (!my_delete(log_info.log_file_name, MYF(0)))
+ {
+ if (decrease_log_space)
+ *decrease_log_space-= s.st_size;
+ }
+ else
+ {
+ if (my_errno == ENOENT)
+ {
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
+ log_info.log_file_name);
+ sql_print_information("Failed to delete file '%s'",
+ log_info.log_file_name);
+ my_errno= 0;
+ }
+ else
+ {
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_BINLOG_PURGE_FATAL_ERR,
+ "a problem with deleting %s; "
+ "consider examining correspondence "
+ "of your binlog index file "
+ "to the actual binlog files",
+ log_info.log_file_name);
+ error= LOG_INFO_FATAL;
+ goto err;
+ }
+ }
}
- /*
- It's not fatal if we can't delete a log file ;
- if we could delete it, take its size into account
- */
- DBUG_PRINT("info",("purging %s",log_info.log_file_name));
- if (!my_delete(log_info.log_file_name, MYF(0)) && decrease_log_space)
- *decrease_log_space-= file_size;
if (find_next_log(&log_info, 0) || exit_loop)
break;
}
-
+
/*
If we get killed -9 here, the sysadmin would have to edit
the log index file after restart - otherwise, this should be safe
@@ -1263,6 +1307,8 @@ err:
RETURN VALUES
0 ok
LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated
+ LOG_INFO_FATAL if any other than ENOENT error from
+ my_stat() or my_delete()
*/
int MYSQL_LOG::purge_logs_before_date(time_t purge_time)
@@ -1286,11 +1332,66 @@ int MYSQL_LOG::purge_logs_before_date(time_t purge_time)
while (strcmp(log_file_name, log_info.log_file_name) &&
!log_in_use(log_info.log_file_name))
{
- /* It's not fatal even if we can't delete a log file */
- if (!my_stat(log_info.log_file_name, &stat_area, MYF(0)) ||
- stat_area.st_mtime >= purge_time)
- break;
- my_delete(log_info.log_file_name, MYF(0));
+ if (!my_stat(log_info.log_file_name, &stat_area, MYF(0)))
+ {
+ if (my_errno == ENOENT)
+ {
+ /*
+ It's not fatal if we can't stat a log file that does not exist.
+ */
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
+ log_info.log_file_name);
+ sql_print_information("Failed to execute my_stat on file '%s'",
+ log_info.log_file_name);
+ my_errno= 0;
+ }
+ else
+ {
+ /*
+ Other than ENOENT are fatal
+ */
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_BINLOG_PURGE_FATAL_ERR,
+ "a problem with getting info on being purged %s; "
+ "consider examining correspondence "
+ "of your binlog index file "
+ "to the actual binlog files",
+ log_info.log_file_name);
+ error= LOG_INFO_FATAL;
+ goto err;
+ }
+ }
+ else
+ {
+ if (stat_area.st_mtime >= purge_time)
+ break;
+ if (my_delete(log_info.log_file_name, MYF(0)))
+ {
+ if (my_errno == ENOENT)
+ {
+ /* It's not fatal even if we can't delete a log file */
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
+ log_info.log_file_name);
+ sql_print_information("Failed to delete file '%s'",
+ log_info.log_file_name);
+ my_errno= 0;
+ }
+ else
+ {
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_BINLOG_PURGE_FATAL_ERR,
+ "a problem with deleting %s; "
+ "consider examining correspondence "
+ "of your binlog index file "
+ "to the actual binlog files",
+ log_info.log_file_name);
+ error= LOG_INFO_FATAL;
+ goto err;
+ }
+ }
+ }
if (find_next_log(&log_info, 0))
break;
}
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index c661579ea66..6a0d05921ec 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -164,14 +164,23 @@ inline int check_result_and_overflow(uint mask, int result, my_decimal *val)
inline uint my_decimal_length_to_precision(uint length, uint scale,
bool unsigned_flag)
{
- return (uint) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1));
+ /* Precision can't be negative thus ignore unsigned_flag when length is 0. */
+ DBUG_ASSERT(length || !scale);
+ return (uint) (length - (scale>0 ? 1:0) -
+ (unsigned_flag || !length ? 0:1));
}
inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
bool unsigned_flag)
{
+ /*
+ When precision is 0 it means that original length was also 0. Thus
+ unsigned_flag is ignored in this case.
+ */
+ DBUG_ASSERT(precision || !scale);
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
- return (uint32)(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1));
+ return (uint32)(precision + (scale>0 ? 1:0) +
+ (unsigned_flag || !precision ? 0:1));
}
inline
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 4f27994c13c..f3bda4e5819 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -615,8 +615,8 @@ bool check_merge_table_access(THD *thd, char *db,
bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc);
bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables);
-bool mysql_multi_update_prepare(THD *thd);
-bool mysql_multi_delete_prepare(THD *thd);
+int mysql_multi_update_prepare(THD *thd);
+int mysql_multi_delete_prepare(THD *thd);
bool mysql_insert_select_prepare(THD *thd);
bool update_precheck(THD *thd, TABLE_LIST *tables);
bool delete_precheck(THD *thd, TABLE_LIST *tables);
@@ -709,7 +709,7 @@ struct Query_cache_query_flags
uint build_table_path(char *buff, size_t bufflen, const char *db,
const char *table, const char *ext);
-bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
+int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags);
@@ -749,7 +749,7 @@ pthread_handler_t handle_one_connection(void *arg);
pthread_handler_t handle_bootstrap(void *arg);
void end_thread(THD *thd,bool put_in_cache);
void flush_thread_cache();
-bool mysql_execute_command(THD *thd);
+int mysql_execute_command(THD *thd);
bool dispatch_command(enum enum_server_command command, THD *thd,
char* packet, uint packet_length);
void log_slow_statement(THD *thd);
@@ -880,7 +880,7 @@ void prepare_triggers_for_insert_stmt(THD *thd, TABLE *table,
enum_duplicates duplic);
void mark_fields_used_by_triggers_for_insert_stmt(THD *thd, TABLE *table,
enum_duplicates duplic);
-bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds);
+int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds);
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
SQL_LIST *order, ha_rows rows, ulonglong options,
bool reset_auto_increment);
@@ -1065,6 +1065,13 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
extern Item **not_found_item;
/*
+ A set of constants used for checking non aggregated fields and sum
+ functions mixture in the ONLY_FULL_GROUP_BY_MODE.
+*/
+#define NON_AGG_FIELD_USED 1
+#define SUM_FUNC_USED 2
+
+/*
This enumeration type is used only by the function find_item_in_list
to return the info on how an item has been resolved against a list
of possibly aliased items.
@@ -1126,7 +1133,7 @@ int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
void wait_for_refresh(THD *thd);
int open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags);
int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables);
-bool open_and_lock_tables(THD *thd,TABLE_LIST *tables);
+int open_and_lock_tables(THD *thd,TABLE_LIST *tables);
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, bool *need_reopen);
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
@@ -1197,7 +1204,7 @@ inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table,
bool eval_const_cond(COND *cond);
/* sql_load.cc */
-bool mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list,
+int mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list,
List<Item> &fields_vars, List<Item> &set_fields,
List<Item> &set_values_list,
enum enum_duplicates handle_duplicates, bool ignore,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 08f881ce8ed..7edc3b91752 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -328,7 +328,7 @@ static bool lower_case_table_names_used= 0;
static bool volatile select_thread_in_use, signal_thread_in_use;
static bool volatile ready_to_exit;
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
-static my_bool opt_bdb, opt_isam, opt_ndbcluster, opt_merge;
+static my_bool opt_bdb, opt_isam, opt_ndbcluster, opt_merge, opt_federated;
static my_bool opt_short_log_format= 0;
static uint kill_cached_threads, wake_thread;
static ulong killed_threads, thread_created;
@@ -1071,12 +1071,9 @@ pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
extern "C" sig_handler print_signal_warning(int sig)
{
- if (!DBUG_IN_USE)
- {
- if (global_system_variables.log_warnings)
- sql_print_warning("Got signal %d from thread %ld",
- sig, my_thread_id());
- }
+ if (global_system_variables.log_warnings)
+ sql_print_warning("Got signal %d from thread %ld",
+ sig, my_thread_id());
#ifdef DONT_REMEMBER_SIGNAL
my_sigset(sig,print_signal_warning); /* int. thread system calls */
#endif
@@ -3623,8 +3620,6 @@ int main(int argc, char **argv)
MY_INIT(argv[0]); // init my_sys library & pthreads
/* ^^^ Nothing should be before this line! */
- DEBUGGER_OFF;
-
/* Set signal used to kill MySQL */
#if defined(SIGUSR2)
thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
@@ -4995,7 +4990,8 @@ enum options_mysqld
OPT_INNODB_ROLLBACK_ON_TIMEOUT,
OPT_SECURE_FILE_PRIV,
OPT_KEEP_FILES_ON_CREATE,
- OPT_INNODB_ADAPTIVE_HASH_INDEX
+ OPT_INNODB_ADAPTIVE_HASH_INDEX,
+ OPT_FEDERATED
};
@@ -5181,6 +5177,9 @@ Disable with --skip-external-locking.",
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"federated", OPT_FEDERATED, "Enable Federated storage engine. Disable with \
+--skip-federated.",
+ (gptr*) &opt_federated, (gptr*) &opt_federated, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
/* We must always support the next option to make scripts like mysqltest
easier to do */
{"gdb", OPT_DEBUGGING,
@@ -6956,7 +6955,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
switch(optid) {
case '#':
#ifndef DBUG_OFF
- DBUG_PUSH(argument ? argument : default_dbug_option);
+ DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
#endif
opt_endinfo=1; /* unireg: memory allocation */
break;
@@ -7335,6 +7334,14 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
else
have_merge_db= SHOW_OPTION_DISABLED;
break;
+#ifdef HAVE_FEDERATED_DB
+ case OPT_FEDERATED:
+ if (opt_federated)
+ have_federated_db= SHOW_OPTION_YES;
+ else
+ have_federated_db= SHOW_OPTION_DISABLED;
+ break;
+#endif
#ifdef HAVE_BERKELEY_DB
case OPT_BDB_NOSYNC:
/* Deprecated option */
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 017a2eb9ecd..a40764577fd 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -394,7 +394,7 @@ my_net_write(NET *net,const char *packet,ulong len)
if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE))
return 1;
#ifndef DEBUG_DATA_PACKETS
- DBUG_DUMP("packet_header",(char*) buff,NET_HEADER_SIZE);
+ DBUG_DUMP("packet_header", buff, NET_HEADER_SIZE);
#endif
return test(net_write_buff(net,packet,len));
}
@@ -892,7 +892,7 @@ my_real_read(NET *net, ulong *complen)
if (i == 0)
{ /* First parts is packet length */
ulong helping;
- DBUG_DUMP("packet_header",(char*) net->buff+net->where_b,
+ DBUG_DUMP("packet_header", net->buff+net->where_b,
NET_HEADER_SIZE);
if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
{
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index a8cf0f67635..17a4701b515 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -4405,52 +4405,70 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
field->type() == FIELD_TYPE_DATETIME))
field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
err= value->save_in_field_no_warnings(field, 1);
- if (err > 0 && field->cmp_type() != value->result_type())
+ if (err > 0)
{
- if ((type == Item_func::EQ_FUNC || type == Item_func::EQUAL_FUNC) &&
- value->result_type() == item_cmp_type(field->result_type(),
- value->result_type()))
-
- {
- tree= new (alloc) SEL_ARG(field, 0, 0);
- tree->type= SEL_ARG::IMPOSSIBLE;
- goto end;
- }
- else
+ if (field->cmp_type() != value->result_type())
{
- /*
- TODO: We should return trees of the type SEL_ARG::IMPOSSIBLE
- for the cases like int_field > 999999999999999999999999 as well.
- */
- tree= 0;
- if (err == 3 && field->type() == FIELD_TYPE_DATE &&
- (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC ||
- type == Item_func::LT_FUNC || type == Item_func::LE_FUNC) )
+ if ((type == Item_func::EQ_FUNC || type == Item_func::EQUAL_FUNC) &&
+ value->result_type() == item_cmp_type(field->result_type(),
+ value->result_type()))
+ {
+ tree= new (alloc) SEL_ARG(field, 0, 0);
+ tree->type= SEL_ARG::IMPOSSIBLE;
+ goto end;
+ }
+ else
{
/*
- We were saving DATETIME into a DATE column, the conversion went ok
- but a non-zero time part was cut off.
+ TODO: We should return trees of the type SEL_ARG::IMPOSSIBLE
+ for the cases like int_field > 999999999999999999999999 as well.
+ */
+ tree= 0;
+ if (err == 3 && field->type() == FIELD_TYPE_DATE &&
+ (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC ||
+ type == Item_func::LT_FUNC || type == Item_func::LE_FUNC) )
+ {
+ /*
+ We were saving DATETIME into a DATE column, the conversion went ok
+ but a non-zero time part was cut off.
- In MySQL's SQL dialect, DATE and DATETIME are compared as datetime
- values. Index over a DATE column uses DATE comparison. Changing
- from one comparison to the other is possible:
+ In MySQL's SQL dialect, DATE and DATETIME are compared as datetime
+ values. Index over a DATE column uses DATE comparison. Changing
+ from one comparison to the other is possible:
- datetime(date_col)< '2007-12-10 12:34:55' -> date_col<='2007-12-10'
- datetime(date_col)<='2007-12-10 12:34:55' -> date_col<='2007-12-10'
+ datetime(date_col)< '2007-12-10 12:34:55' -> date_col<='2007-12-10'
+ datetime(date_col)<='2007-12-10 12:34:55' -> date_col<='2007-12-10'
- datetime(date_col)> '2007-12-10 12:34:55' -> date_col>='2007-12-10'
- datetime(date_col)>='2007-12-10 12:34:55' -> date_col>='2007-12-10'
+ datetime(date_col)> '2007-12-10 12:34:55' -> date_col>='2007-12-10'
+ datetime(date_col)>='2007-12-10 12:34:55' -> date_col>='2007-12-10'
- but we'll need to convert '>' to '>=' and '<' to '<='. This will
- be done together with other types at the end of this function
- (grep for field_is_equal_to_item)
- */
+ but we'll need to convert '>' to '>=' and '<' to '<='. This will
+ be done together with other types at the end of this function
+ (grep for field_is_equal_to_item)
+ */
+ }
+ else
+ goto end;
}
- else
- goto end;
}
- }
- if (err < 0)
+
+ /*
+ guaranteed at this point: err > 0; field and const of same type
+ If an integer got bounded (e.g. to within 0..255 / -128..127)
+ for < or >, set flags as for <= or >= (no NEAR_MAX / NEAR_MIN)
+ */
+ else if (err == 1 && field->result_type() == INT_RESULT)
+ {
+ if (type == Item_func::LT_FUNC && (value->val_int() > 0))
+ type = Item_func::LE_FUNC;
+ else if (type == Item_func::GT_FUNC &&
+ !((Field_num*)field)->unsigned_flag &&
+ !((Item_int*)value)->unsigned_flag &&
+ (value->val_int() < 0))
+ type = Item_func::GE_FUNC;
+ }
+ }
+ else if (err < 0)
{
field->table->in_use->variables.sql_mode= orig_sql_mode;
/* This happens when we try to insert a NULL field in a not null column */
@@ -9552,8 +9570,6 @@ static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
int idx;
char buff[1024];
DBUG_ENTER("print_sel_tree");
- if (! _db_on_)
- DBUG_VOID_RETURN;
String tmp(buff,sizeof(buff),&my_charset_bin);
tmp.length(0);
@@ -9583,8 +9599,6 @@ static void print_ror_scans_arr(TABLE *table, const char *msg,
struct st_ror_scan_info **end)
{
DBUG_ENTER("print_ror_scans");
- if (! _db_on_)
- DBUG_VOID_RETURN;
char buff[1024];
String tmp(buff,sizeof(buff),&my_charset_bin);
@@ -9647,7 +9661,7 @@ static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg)
{
char buf[MAX_KEY/8+1];
DBUG_ENTER("print_quick");
- if (! _db_on_ || !quick)
+ if (!quick)
DBUG_VOID_RETURN;
DBUG_LOCK_FILE;
diff --git a/sql/procedure.h b/sql/procedure.h
index 850d5c74db4..f1fb433a6ee 100644
--- a/sql/procedure.h
+++ b/sql/procedure.h
@@ -144,7 +144,7 @@ public:
virtual int send_row(List<Item> &fields)=0;
virtual bool change_columns(List<Item> &fields)=0;
virtual void update_refs(void) {}
- virtual bool end_of_records() { return 0; }
+ virtual int end_of_records() { return 0; }
};
Procedure *setup_procedure(THD *thd,ORDER *proc_param,select_result *result,
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 71a5a26f1d7..eb381bfecf4 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -2004,7 +2004,7 @@ void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type,
{
DATE_TIME_FORMAT *old;
DBUG_ENTER("sys_var_date_time_format::update2");
- DBUG_DUMP("positions",(char*) new_value->positions,
+ DBUG_DUMP("positions", new_value->positions,
sizeof(new_value->positions));
if (type == OPT_GLOBAL)
diff --git a/sql/share/charsets/README b/sql/share/charsets/README
index 172d1ee8e1e..3c5b3206faa 100644
--- a/sql/share/charsets/README
+++ b/sql/share/charsets/README
@@ -1,28 +1,31 @@
-This directory holds configuration files which allow MySQL to work with
+This directory holds configuration files that enable MySQL to work with
different character sets. It contains:
-*.conf
- Each conf file contains four tables which describe character types,
+charset_name.xml
+ Each charset_name.xml file contains information for a simple character
+ set. The information in the file describes character types,
lower- and upper-case equivalencies and sorting orders for the
character values in the set.
-Index
- The Index file lists all of the available charset configurations.
+Index.xml
+ The Index.xml file lists all of the available charset configurations,
+ including collations.
- Each charset is paired with a number. The number is stored
- IN THE DATABASE TABLE FILES and must not be changed. Always
- add new character sets to the end of the list, so that the
- numbers of the other character sets will not be changed.
+ Each collation must have a unique number. The number is stored
+ IN THE DATABASE TABLE FILES and must not be changed.
+
+ The max-id attribute of the <charsets> element must be set to
+ the largest collation number.
Compiled in or configuration file?
When should a character set be compiled in to MySQL's string library
- (libmystrings), and when should it be placed in a configuration
- file?
+ (libmystrings), and when should it be placed in a charset_name.xml
+ configuration file?
If the character set requires the strcoll functions or is a
multi-byte character set, it MUST be compiled in to the string
library. If it does not require these functions, it should be
- placed in a configuration file.
+ placed in a charset_name.xml configuration file.
If the character set uses any one of the strcoll functions, it
must define all of them. Likewise, if the set uses one of the
@@ -30,11 +33,7 @@ Compiled in or configuration file?
more information on how to add a complex character set to MySQL.
Syntax of configuration files
- The syntax is very simple. Comments start with a '#' character and
- proceed to the end of the line. Words are separated by arbitrary
- amounts of whitespace.
-
- For the character set configuration files, every word must be a
- number in hexadecimal format. The ctype array takes up the first
- 257 words; the to_lower, to_upper and sort_order arrays take up 256
- words each after that.
+ The syntax is very simple. Words in <map> array elements are
+ separated by arbitrary amounts of whitespace. Each word must be a
+ number in hexadecimal format. The ctype array has 257 words; the
+ other arrays (lower, upper, etc.) take up 256 words each after that.
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 9e6cf462113..7d345d633c6 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -1771,30 +1771,30 @@ ER_BLOB_USED_AS_KEY 42000 S1009
swe "En BLOB '%-.64s' kan inte vara nyckel med den använda tabelltypen"
ukr "BLOB ÓÔÏ×ÂÅÃØ '%-.64s' ÎÅ ÍÏÖÅ ÂÕÔÉ ×ÉËÏÒÉÓÔÁÎÉÊ Õ ×ÉÚÎÁÞÅÎΦ ËÌÀÞÁ × ÃØÏÍÕ ÔÉЦ ÔÁÂÌÉæ"
ER_TOO_BIG_FIELDLENGTH 42000 S1009
- cze "P-Bøíli¹ velká délka sloupce '%-.64s' (nejvíce %d). Pou¾ijte BLOB"
- dan "For stor feltlængde for kolonne '%-.64s' (maks = %d). Brug BLOB i stedet"
- nla "Te grote kolomlengte voor '%-.64s' (max = %d). Maak hiervoor gebruik van het type BLOB"
- eng "Column length too big for column '%-.64s' (max = %d); use BLOB or TEXT instead"
- jps "column '%-.64s' ‚Í,Šm•Û‚·‚é column ‚Ì‘å‚«‚³‚ª‘½‚·‚¬‚Ü‚·. (Å‘å %d ‚Ü‚Å). BLOB ‚ð‚©‚í‚è‚ÉŽg—p‚µ‚Ä‚­‚¾‚³‚¢.",
- est "Tulba '%-.64s' pikkus on liiga pikk (maksimaalne pikkus: %d). Kasuta BLOB väljatüüpi"
- fre "Champ '%-.64s' trop long (max = %d). Utilisez un BLOB"
- ger "Feldlänge für Feld '%-.64s' zu groß (maximal %d). BLOB- oder TEXT-Spaltentyp verwenden!"
- greek "Ðïëý ìåãÜëï ìÞêïò ãéá ôï ðåäßï '%-.64s' (max = %d). Ðáñáêáëþ ÷ñçóéìïðïéåßóôå ôïí ôýðï BLOB"
- hun "A(z) '%-.64s' oszlop tul hosszu. (maximum = %d). Hasznaljon BLOB tipust inkabb."
- ita "La colonna '%-.64s' e` troppo grande (max=%d). Utilizza un BLOB."
- jpn "column '%-.64s' ¤Ï,³ÎÊݤ¹¤ë column ¤ÎÂ礭¤µ¤¬Â¿¤¹¤®¤Þ¤¹. (ºÇÂç %d ¤Þ¤Ç). BLOB ¤ò¤«¤ï¤ê¤Ë»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤."
- kor "Ä®·³ '%-.64s'ÀÇ Ä®·³ ±æÀÌ°¡ ³Ê¹« ±é´Ï´Ù (ÃÖ´ë = %d). ´ë½Å¿¡ BLOB¸¦ »ç¿ëÇϼ¼¿ä."
- nor "For stor nøkkellengde for kolonne '%-.64s' (maks = %d). Bruk BLOB istedenfor"
- norwegian-ny "For stor nykkellengde for felt '%-.64s' (maks = %d). Bruk BLOB istadenfor"
- pol "Zbyt du¿a d³ugo?æ kolumny '%-.64s' (maks. = %d). W zamian u¿yj typu BLOB"
- por "Comprimento da coluna '%-.64s' grande demais (max = %d); use BLOB em seu lugar"
- rum "Lungimea coloanei '%-.64s' este prea lunga (maximum = %d). Foloseste BLOB mai bine"
- rus "óÌÉÛËÏÍ ÂÏÌØÛÁÑ ÄÌÉÎÁ ÓÔÏÌÂÃÁ '%-.64s' (ÍÁËÓÉÍÕÍ = %d). éÓÐÏÌØÚÕÊÔÅ ÔÉÐ BLOB ÉÌÉ TEXT ×ÍÅÓÔÏ ÔÅËÕÝÅÇÏ"
- serbian "Previše podataka za kolonu '%-.64s' (maksimum je %d). Upotrebite BLOB polje"
- slo "Príli¹ veµká då¾ka pre pole '%-.64s' (maximum = %d). Pou¾ite BLOB"
- spa "Longitud de columna demasiado grande para la columna '%-.64s' (maximo = %d).Usar BLOB en su lugar"
- swe "För stor kolumnlängd angiven för '%-.64s' (max= %d). Använd en BLOB instället"
- ukr "úÁÄÏ×ÇÁ ÄÏ×ÖÉÎÁ ÓÔÏ×ÂÃÑ '%-.64s' (max = %d). ÷ÉËÏÒÉÓÔÁÊÔÅ ÔÉÐ BLOB"
+ cze "P-Bøíli¹ velká délka sloupce '%-.64s' (nejvíce %lu). Pou¾ijte BLOB"
+ dan "For stor feltlængde for kolonne '%-.64s' (maks = %lu). Brug BLOB i stedet"
+ nla "Te grote kolomlengte voor '%-.64s' (max = %lu). Maak hiervoor gebruik van het type BLOB"
+ eng "Column length too big for column '%-.64s' (max = %lu); use BLOB or TEXT instead"
+ jps "column '%-.64s' ‚Í,Šm•Û‚·‚é column ‚Ì‘å‚«‚³‚ª‘½‚·‚¬‚Ü‚·. (Å‘å %lu ‚Ü‚Å). BLOB ‚ð‚©‚í‚è‚ÉŽg—p‚µ‚Ä‚­‚¾‚³‚¢.",
+ est "Tulba '%-.64s' pikkus on liiga pikk (maksimaalne pikkus: %lu). Kasuta BLOB väljatüüpi"
+ fre "Champ '%-.64s' trop long (max = %lu). Utilisez un BLOB"
+ ger "Feldlänge für Feld '%-.64s' zu groß (maximal %lu). BLOB- oder TEXT-Spaltentyp verwenden!"
+ greek "Ðïëý ìåãÜëï ìÞêïò ãéá ôï ðåäßï '%-.64s' (max = %lu). Ðáñáêáëþ ÷ñçóéìïðïéåßóôå ôïí ôýðï BLOB"
+ hun "A(z) '%-.64s' oszlop tul hosszu. (maximum = %lu). Hasznaljon BLOB tipust inkabb."
+ ita "La colonna '%-.64s' e` troppo grande (max=%lu). Utilizza un BLOB."
+ jpn "column '%-.64s' ¤Ï,³ÎÊݤ¹¤ë column ¤ÎÂ礭¤µ¤¬Â¿¤¹¤®¤Þ¤¹. (ºÇÂç %lu ¤Þ¤Ç). BLOB ¤ò¤«¤ï¤ê¤Ë»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤."
+ kor "Ä®·³ '%-.64s'ÀÇ Ä®·³ ±æÀÌ°¡ ³Ê¹« ±é´Ï´Ù (ÃÖ´ë = %lu). ´ë½Å¿¡ BLOB¸¦ »ç¿ëÇϼ¼¿ä."
+ nor "For stor nøkkellengde for kolonne '%-.64s' (maks = %lu). Bruk BLOB istedenfor"
+ norwegian-ny "For stor nykkellengde for felt '%-.64s' (maks = %lu). Bruk BLOB istadenfor"
+ pol "Zbyt du¿a d³ugo?æ kolumny '%-.64s' (maks. = %lu). W zamian u¿yj typu BLOB"
+ por "Comprimento da coluna '%-.64s' grande demais (max = %lu); use BLOB em seu lugar"
+ rum "Lungimea coloanei '%-.64s' este prea lunga (maximum = %lu). Foloseste BLOB mai bine"
+ rus "óÌÉÛËÏÍ ÂÏÌØÛÁÑ ÄÌÉÎÁ ÓÔÏÌÂÃÁ '%-.64s' (ÍÁËÓÉÍÕÍ = %lu). éÓÐÏÌØÚÕÊÔÅ ÔÉÐ BLOB ÉÌÉ TEXT ×ÍÅÓÔÏ ÔÅËÕÝÅÇÏ"
+ serbian "Previše podataka za kolonu '%-.64s' (maksimum je %lu). Upotrebite BLOB polje"
+ slo "Príli¹ veµká då¾ka pre pole '%-.64s' (maximum = %lu). Pou¾ite BLOB"
+ spa "Longitud de columna demasiado grande para la columna '%-.64s' (maximo = %lu).Usar BLOB en su lugar"
+ swe "För stor kolumnlängd angiven för '%-.64s' (max= %lu). Använd en BLOB instället"
+ ukr "úÁÄÏ×ÇÁ ÄÏ×ÖÉÎÁ ÓÔÏ×ÂÃÑ '%-.64s' (max = %lu). ÷ÉËÏÒÉÓÔÁÊÔÅ ÔÉÐ BLOB"
ER_WRONG_AUTO_KEY 42000 S1009
cze "M-Bù¾ete mít pouze jedno AUTO pole a to musí být definováno jako klíè"
dan "Der kan kun specificeres eet AUTO_INCREMENT-felt, og det skal være indekseret"
@@ -5508,11 +5508,11 @@ ER_SP_NO_RECURSION
eng "Recursive stored functions and triggers are not allowed."
ger "Rekursive gespeicherte Routinen und Triggers sind nicht erlaubt"
ER_TOO_BIG_SCALE 42000 S1009
- eng "Too big scale %d specified for column '%-.64s'. Maximum is %d."
- ger "Zu großer Skalierungsfaktor %d für Feld '%-.64s' angegeben. Maximum ist %d"
+ eng "Too big scale %lu specified for column '%-.64s'. Maximum is %d."
+ ger "Zu großer Skalierungsfaktor %lu für Feld '%-.64s' angegeben. Maximum ist %d"
ER_TOO_BIG_PRECISION 42000 S1009
- eng "Too big precision %d specified for column '%-.64s'. Maximum is %d."
- ger "Zu große Genauigkeit %d für Feld '%-.64s' angegeben. Maximum ist %d"
+ eng "Too big precision %lu specified for column '%-.64s'. Maximum is %lu."
+ ger "Zu große Genauigkeit %lu für Feld '%-.64s' angegeben. Maximum ist %lu"
ER_M_BIGGER_THAN_D 42000 S1009
eng "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.64s')."
ger "Für FLOAT(M,D), DOUBLE(M,D) oder DECIMAL(M,D) muss M >= D sein (Feld '%-.64s')"
@@ -5550,8 +5550,8 @@ ER_WARN_CANT_DROP_DEFAULT_KEYCACHE
eng "Cannot drop default keycache"
ger "Der vorgabemäßige Schlüssel-Cache kann nicht gelöscht werden"
ER_TOO_BIG_DISPLAYWIDTH 42000 S1009
- eng "Display width out of range for column '%-.64s' (max = %d)"
- ger "Anzeigebreite außerhalb des zulässigen Bereichs für Spalte '%-.64s' (Maximum: %d)"
+ eng "Display width out of range for column '%-.64s' (max = %lu)"
+ ger "Anzeigebreite außerhalb des zulässigen Bereichs für Spalte '%-.64s' (Maximum: %lu)"
ER_XAER_DUPID XAE08
eng "XAER_DUPID: The XID already exists"
ger "XAER_DUPID: Die XID existiert bereits"
@@ -5641,3 +5641,7 @@ ER_NAME_BECOMES_EMPTY
eng "Name '%-.64s' has become ''"
ER_AMBIGUOUS_FIELD_TERM
eng "First character of the FIELDS TERMINATED string is ambiguous; please use non-optional and non-empty FIELDS ENCLOSED BY"
+ER_LOAD_DATA_INVALID_COLUMN
+ eng "Invalid column reference (%-.64s) in LOAD DATA"
+ER_LOG_PURGE_NO_FILE
+ eng "Being purged log %s was not found"
diff --git a/sql/sp.cc b/sql/sp.cc
index 7224d3c4f0e..2392cabb220 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -25,7 +25,8 @@
static bool
create_string(THD *thd, String *buf,
int sp_type,
- sp_name *name,
+ const char *db, ulong dblen,
+ const char *name, ulong namelen,
const char *params, ulong paramslen,
const char *returns, ulong returnslen,
const char *body, ulong bodylen,
@@ -426,12 +427,13 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
*/
if (!create_string(thd, &defstr,
- type,
- name,
- params, strlen(params),
- returns, strlen(returns),
- body, strlen(body),
- &chistics, &definer_user_name, &definer_host_name))
+ type,
+ NULL, 0,
+ name->m_name.str, name->m_name.length,
+ params, strlen(params),
+ returns, strlen(returns),
+ body, strlen(body),
+ &chistics, &definer_user_name, &definer_host_name))
{
ret= SP_INTERNAL_ERROR;
goto end;
@@ -518,6 +520,7 @@ db_create_routine(THD *thd, int type, sp_head *sp)
DBUG_ENTER("db_create_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",type,sp->m_name.length,
sp->m_name.str));
+ String retstr(64);
if (!(table= open_proc_table_for_update(thd)))
ret= SP_OPEN_TABLE_FAILED;
@@ -568,7 +571,6 @@ db_create_routine(THD *thd, int type, sp_head *sp)
store(sp->m_params.str, sp->m_params.length, system_charset_info);
if (sp->m_type == TYPE_ENUM_FUNCTION)
{
- String retstr(64);
sp_returns_type(thd, retstr, sp);
table->field[MYSQL_PROC_FIELD_RETURNS]->
store(retstr.ptr(), retstr.length(), system_charset_info);
@@ -625,13 +627,21 @@ db_create_routine(THD *thd, int type, sp_head *sp)
String log_query;
log_query.set_charset(system_charset_info);
- log_query.append(STRING_WITH_LEN("CREATE "));
- append_definer(thd, &log_query, &thd->lex->definer->user,
- &thd->lex->definer->host);
- log_query.append(thd->lex->stmt_definition_begin,
- (char *)sp->m_body_begin -
- thd->lex->stmt_definition_begin +
- sp->m_body.length);
+
+ if (!create_string(thd, &log_query,
+ sp->m_type,
+ (sp->m_explicit_name ? sp->m_db.str : NULL),
+ (sp->m_explicit_name ? sp->m_db.length : 0),
+ sp->m_name.str, sp->m_name.length,
+ sp->m_params.str, sp->m_params.length,
+ retstr.c_ptr(), retstr.length(),
+ sp->m_body.str, sp->m_body.length,
+ sp->m_chistics, &(thd->lex->definer->user),
+ &(thd->lex->definer->host)))
+ {
+ ret= SP_INTERNAL_ERROR;
+ goto done;
+ }
/* Such a statement can always go directly to binlog, no trans cache */
Query_log_event qinfo(thd, log_query.c_ptr(), log_query.length(), 0,
@@ -1797,17 +1807,18 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
*/
static bool
create_string(THD *thd, String *buf,
- int type,
- sp_name *name,
- const char *params, ulong paramslen,
- const char *returns, ulong returnslen,
- const char *body, ulong bodylen,
- st_sp_chistics *chistics,
+ int type,
+ const char *db, ulong dblen,
+ const char *name, ulong namelen,
+ const char *params, ulong paramslen,
+ const char *returns, ulong returnslen,
+ const char *body, ulong bodylen,
+ st_sp_chistics *chistics,
const LEX_STRING *definer_user,
const LEX_STRING *definer_host)
{
/* Make some room to begin with */
- if (buf->alloc(100 + name->m_qname.length + paramslen + returnslen + bodylen +
+ if (buf->alloc(100 + dblen + 1 + namelen + paramslen + returnslen + bodylen +
chistics->comment.length + 10 /* length of " DEFINER= "*/ +
USER_HOST_BUFF_SIZE))
return FALSE;
@@ -1818,7 +1829,12 @@ create_string(THD *thd, String *buf,
buf->append(STRING_WITH_LEN("FUNCTION "));
else
buf->append(STRING_WITH_LEN("PROCEDURE "));
- append_identifier(thd, buf, name->m_name.str, name->m_name.length);
+ if (dblen > 0)
+ {
+ append_identifier(thd, buf, db, dblen);
+ buf->append('.');
+ }
+ append_identifier(thd, buf, name, namelen);
buf->append('(');
buf->append(params, paramslen);
buf->append(')');
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f7119323055..4556d70e4c3 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -522,6 +522,8 @@ sp_head::init(LEX *lex)
m_qname.str= NULL;
m_qname.length= 0;
+ m_explicit_name= false;
+
m_db.str= NULL;
m_db.length= 0;
@@ -564,6 +566,8 @@ sp_head::init_sp_name(THD *thd, sp_name *spname)
m_name.str= strmake_root(thd->mem_root, spname->m_name.str,
spname->m_name.length);
+ m_explicit_name= spname->m_explicit_name;
+
if (spname->m_qname.length == 0)
spname->init_qname(thd);
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 0e710196603..11ff7160c03 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -121,6 +121,7 @@ public:
st_sp_chistics *m_chistics;
ulong m_sql_mode; // For SHOW CREATE and execution
LEX_STRING m_qname; // db.name
+ bool m_explicit_name; /**< Prepend the db name? */
/**
Key representing routine in the set of stored routines used by statement.
[routine_type]db.name\0
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index e9504f423ad..7592986ef81 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1382,7 +1382,7 @@ bool acl_check_host(const char *host, const char *ip)
1 ERROR ; In this case the error is sent to the client.
*/
-bool check_change_password(THD *thd, const char *host, const char *user,
+int check_change_password(THD *thd, const char *host, const char *user,
char *new_password, uint new_password_len)
{
if (!initialized)
@@ -2763,7 +2763,7 @@ table_error:
TRUE error
*/
-bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
+int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
List <LEX_USER> &user_list,
List <LEX_COLUMN> &columns, ulong rights,
bool revoke_grant)
@@ -2880,6 +2880,12 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
}
#endif
+ /*
+ The lock api is depending on the thd->lex variable which needs to be
+ re-initialized.
+ */
+ Query_tables_list backup;
+ thd->lex->reset_n_backup_query_tables_list(&backup);
if (simple_open_n_lock_tables(thd,tables))
{ // Should never happen
close_thread_tables(thd); /* purecov: deadcode */
@@ -3018,6 +3024,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
send_ok(thd);
/* Tables are automatically closed */
+ thd->lex->restore_backup_query_tables_list(&backup);
DBUG_RETURN(result);
}
@@ -5805,7 +5812,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
< 0 Error. Error message not yet sent.
*/
-bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
+int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc)
{
Security_context *sctx= thd->security_ctx;
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index b2007ccdf47..1efcd2e3b6b 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -183,13 +183,13 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, const char *passwd,
bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
char *ip, char *db);
bool acl_check_host(const char *host, const char *ip);
-bool check_change_password(THD *thd, const char *host, const char *user,
+int check_change_password(THD *thd, const char *host, const char *user,
char *password, uint password_len);
bool change_password(THD *thd, const char *host, const char *user,
char *password);
bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
ulong rights, bool revoke);
-bool mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
+int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
List <LEX_COLUMN> &column_list, ulong rights,
bool revoke);
bool mysql_routine_grant(THD *thd, TABLE_LIST *table, bool is_proc,
@@ -225,7 +225,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
const char *db, const char *table);
bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc);
-bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
+int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc);
bool check_routine_level_acl(THD *thd, const char *db, const char *name,
bool is_proc);
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 95a7fb3d34d..4b3264069b5 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -195,13 +195,13 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
*/
for (; str != end && my_isspace(system_charset_info, *str); str++) ;
if (str == end)
- return 0;
+ DBUG_RETURN(0);
if (*str == '-')
{
info->negative = 1;
if (++str == end || *str == '0') // converting -0 to a number
- return 0; // might lose information
+ DBUG_RETURN(0); // might lose information
}
else
info->negative = 0;
@@ -219,33 +219,33 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
int error;
info->ullval= (ulonglong) my_strtoll10(begin, &endpos, &error);
if (info->integers == 1)
- return 0; // a single number can't be zerofill
+ DBUG_RETURN(0); // a single number can't be zerofill
info->maybe_zerofill = 1;
- return 1; // a zerofill number, or an integer
+ DBUG_RETURN(1); // a zerofill number, or an integer
}
if (*str == '.' || *str == 'e' || *str == 'E')
{
if (info->zerofill) // can't be zerofill anymore
- return 0;
+ DBUG_RETURN(0);
if ((str + 1) == end) // number was something like '123[.eE]'
{
char *endpos= (char*) str;
int error;
info->ullval= (ulonglong) my_strtoll10(begin, &endpos, &error);
- return 1;
+ DBUG_RETURN(1);
}
if (*str == 'e' || *str == 'E') // number may be something like '1e+50'
{
str++;
if (*str != '-' && *str != '+')
- return 0;
+ DBUG_RETURN(0);
for (str++; str != end && my_isdigit(system_charset_info,*str); str++) ;
if (str == end)
{
info->is_float = 1; // we can't use variable decimals here
- return 1;
+ DBUG_RETURN(1);
}
- return 0;
+ DBUG_RETURN(0);
}
for (str++; *(end - 1) == '0'; end--); // jump over zeros at the end
if (str == end) // number was something like '123.000'
@@ -253,17 +253,17 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
char *endpos= (char*) str;
int error;
info->ullval= (ulonglong) my_strtoll10(begin, &endpos, &error);
- return 1;
+ DBUG_RETURN(1);
}
for (; str != end && my_isdigit(system_charset_info,*str); str++)
info->decimals++;
if (str == end)
{
info->dval = my_atof(begin);
- return 1;
+ DBUG_RETURN(1);
}
}
- return 0;
+ DBUG_RETURN(0);
}
@@ -683,7 +683,7 @@ int analyse::send_row(List<Item> &field_list __attribute__((unused)))
} // analyse::send_row
-bool analyse::end_of_records()
+int analyse::end_of_records()
{
field_info **f = f_info;
char buff[MAX_FIELD_WIDTH];
diff --git a/sql/sql_analyse.h b/sql/sql_analyse.h
index 21a37209e89..2a4226b2d95 100644
--- a/sql/sql_analyse.h
+++ b/sql/sql_analyse.h
@@ -350,7 +350,7 @@ public:
virtual bool change_columns(List<Item> &fields);
virtual int send_row(List<Item> &fields);
virtual void end_group(void) {}
- virtual bool end_of_records(void);
+ virtual int end_of_records(void);
friend Procedure *proc_analyse_init(THD *thd, ORDER *param,
select_result *result,
List<Item> &field_list);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 89c16b7e54c..9cdcc2bbb75 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -3046,7 +3046,7 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
The lock will automaticaly be freed by close_thread_tables()
*/
-bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
+int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
{
uint counter;
bool need_reopen;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 226117f4e2f..6da6925e82d 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -639,6 +639,13 @@ void THD::cleanup_after_query()
{
clear_next_insert_id= 0;
next_insert_id= 0;
+
+ /*
+ BUG#33029, if one statement in a SP set this member to 1, all
+ statment after this statement in the SP would be considered used
+ INSERT_ID value, reset this member after each query to fix this.
+ */
+ insert_id_used= 0;
}
/*
Reset rand_used so that detection of calls to rand() will save random
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 91b0c02d23b..e25ede1be03 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -449,7 +449,7 @@ bool load_db_opt_by_name(THD *thd, const char *db_name,
*/
-bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
+int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
bool silent)
{
char path[FN_REFLEN+16];
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index eeb77cef583..b9177f65ad5 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -375,7 +375,7 @@ cleanup:
FALSE OK
TRUE error
*/
-bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
+int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
{
Item *fake_conds= 0;
SELECT_LEX *select_lex= &thd->lex->select_lex;
@@ -438,7 +438,7 @@ extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
TRUE Error
*/
-bool mysql_multi_delete_prepare(THD *thd)
+int mysql_multi_delete_prepare(THD *thd)
{
LEX *lex= thd->lex;
TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxiliary_table_list.first;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index f2a539fd02b..68c402d9895 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -708,9 +708,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
error=0;
id=0;
+
thd_proc_info(thd, "update");
if (duplic != DUP_ERROR || ignore)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+
if (duplic == DUP_REPLACE)
{
if (!table->triggers || !table->triggers->has_delete_triggers())
@@ -736,8 +738,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
values_list.elements, and - if nothing else - to initialize
the code to make the call of end_bulk_insert() below safe.
*/
- if (lock_type != TL_WRITE_DELAYED && !thd->prelocked_mode)
- table->file->start_bulk_insert(values_list.elements);
+#ifndef EMBEDDED_LIBRARY
+ if (lock_type != TL_WRITE_DELAYED)
+#endif /* EMBEDDED_LIBRARY */
+ {
+ if (duplic != DUP_ERROR || ignore)
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ if (!thd->prelocked_mode)
+ table->file->start_bulk_insert(values_list.elements);
+ }
thd->abort_on_warning= (!ignore && (thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
@@ -863,6 +872,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
else if (table->next_number_field && info.copied)
id=table->next_number_field->val_int(); // Return auto_increment value
+ if (duplic != DUP_ERROR || ignore)
+ table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
+
transactional_table= table->file->has_transactions();
if ((changed= (info.copied || info.deleted || info.updated)))
@@ -942,8 +954,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
thd->next_insert_id=0; // Reset this if wrongly used
table->auto_increment_field_not_null= FALSE;
- if (duplic != DUP_ERROR || ignore)
- table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
if (duplic == DUP_REPLACE &&
(!table->triggers || !table->triggers->has_delete_triggers()))
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
@@ -1283,7 +1293,12 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds);
select_lex->first_execution= 0;
}
- if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
+ /*
+ Only call extra() handler method if we are not performing a DELAYED
+ operation. It will instead be executed by delayed insert thread.
+ */
+ if ((duplic == DUP_UPDATE || duplic == DUP_REPLACE) &&
+ (table->reginfo.lock_type != TL_WRITE_DELAYED))
table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
DBUG_RETURN(FALSE);
}
@@ -2453,6 +2468,9 @@ bool Delayed_insert::handle_inserts(void)
info.ignore= row->ignore;
info.handle_duplicates= row->dup;
+ if (info.handle_duplicates == DUP_UPDATE ||
+ info.handle_duplicates == DUP_REPLACE)
+ table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
if (info.ignore ||
info.handle_duplicates != DUP_ERROR)
{
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index b669919dba6..468bae02b13 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1253,6 +1253,7 @@ void st_select_lex::init_select()
non_agg_fields.empty();
cond_value= having_value= Item::COND_UNDEF;
inner_refs_list.empty();
+ full_group_by_flag= 0;
}
/*
@@ -1491,8 +1492,6 @@ bool st_select_lex::test_limit()
"LIMIT & IN/ALL/ANY/SOME subquery");
return(1);
}
- // no sense in ORDER BY without LIMIT
- order_list.empty();
return(0);
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 890c18121bd..6878e2a4694 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -616,7 +616,16 @@ public:
joins on the right.
*/
List<String> *prev_join_using;
-
+ /*
+ Bitmap used in the ONLY_FULL_GROUP_BY_MODE to prevent mixture of aggregate
+ functions and non aggregated fields when GROUP BY list is absent.
+ Bits:
+ 0 - non aggregated fields are used in this select,
+ defined as NON_AGG_FIELD_USED.
+ 1 - aggregate functions are used in this select,
+ defined as SUM_FUNC_USED.
+ */
+ uint8 full_group_by_flag;
void init_query();
void init_select();
st_select_lex_unit* master_unit();
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index d687ceff393..e9fd04dff15 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -110,7 +110,7 @@ static bool write_execute_load_query_log_event(THD *thd,
TRUE - error / FALSE - success
*/
-bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
+int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
List<Item> &fields_vars, List<Item> &set_fields,
List<Item> &set_values,
enum enum_duplicates handle_duplicates, bool ignore,
@@ -233,9 +233,11 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
while ((item= it++))
{
- if (item->type() == Item::FIELD_ITEM)
+ Item *real_item= item->real_item();
+
+ if (real_item->type() == Item::FIELD_ITEM)
{
- Field *field= ((Item_field*)item)->field;
+ Field *field= ((Item_field*)real_item)->field;
if (field->flags & BLOB_FLAG)
{
use_blobs= 1;
@@ -244,7 +246,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
else
tot_length+= field->field_length;
}
- else
+ else if (item->type() == Item::STRING_ITEM)
use_vars= 1;
}
if (use_blobs && !ex->line_term->length() && !field_term->length())
@@ -705,6 +707,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
{
uint length;
byte *pos;
+ Item *real_item;
if (read_info.read_field())
break;
@@ -716,14 +719,17 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
pos=read_info.row_start;
length=(uint) (read_info.row_end-pos);
+ real_item= item->real_item();
+
if (!read_info.enclosed &&
(enclosed_length && length == 4 &&
!memcmp(pos, STRING_WITH_LEN("NULL"))) ||
(length == 1 && read_info.found_null))
{
- if (item->type() == Item::FIELD_ITEM)
+
+ if (real_item->type() == Item::FIELD_ITEM)
{
- Field *field= ((Item_field *)item)->field;
+ Field *field= ((Item_field *)real_item)->field;
if (field->reset())
{
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name,
@@ -740,25 +746,39 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
ER_WARN_NULL_TO_NOTNULL, 1);
}
}
- else
+ else if (item->type() == Item::STRING_ITEM)
+ {
((Item_user_var_as_out_param *)item)->set_null_value(
read_info.read_charset);
+ }
+ else
+ {
+ my_error(ER_LOAD_DATA_INVALID_COLUMN, MYF(0), item->full_name());
+ DBUG_RETURN(1);
+ }
+
continue;
}
- if (item->type() == Item::FIELD_ITEM)
+ if (real_item->type() == Item::FIELD_ITEM)
{
-
- Field *field= ((Item_field *)item)->field;
+ Field *field= ((Item_field *)real_item)->field;
field->set_notnull();
read_info.row_end[0]=0; // Safe to change end marker
if (field == table->next_number_field)
table->auto_increment_field_not_null= TRUE;
field->store((char*) pos, length, read_info.read_charset);
}
- else
+ else if (item->type() == Item::STRING_ITEM)
+ {
((Item_user_var_as_out_param *)item)->set_value((char*) pos, length,
- read_info.read_charset);
+ read_info.read_charset);
+ }
+ else
+ {
+ my_error(ER_LOAD_DATA_INVALID_COLUMN, MYF(0), item->full_name());
+ DBUG_RETURN(1);
+ }
}
if (read_info.error)
break;
@@ -774,9 +794,10 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
break;
for (; item ; item= it++)
{
- if (item->type() == Item::FIELD_ITEM)
+ Item *real_item= item->real_item();
+ if (real_item->type() == Item::FIELD_ITEM)
{
- Field *field= ((Item_field *)item)->field;
+ Field *field= ((Item_field *)real_item)->field;
if (field->reset())
{
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name,
@@ -796,9 +817,16 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
ER_WARN_TOO_FEW_RECORDS,
ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
}
- else
+ else if (item->type() == Item::STRING_ITEM)
+ {
((Item_user_var_as_out_param *)item)->set_null_value(
read_info.read_charset);
+ }
+ else
+ {
+ my_error(ER_LOAD_DATA_INVALID_COLUMN, MYF(0), item->full_name());
+ DBUG_RETURN(1);
+ }
}
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index dee3f2b5b22..ccd131e5f90 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2538,10 +2538,10 @@ static void reset_one_shot_variables(THD *thd)
TRUE Error
*/
-bool
+int
mysql_execute_command(THD *thd)
{
- bool res= FALSE;
+ int res= FALSE;
bool need_start_waiting= FALSE; // have protection against global read lock
int up_result= 0;
LEX *lex= thd->lex;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 33eeff03d0a..ae6764254cd 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1403,7 +1403,7 @@ error:
*/
static bool select_like_stmt_test(Prepared_statement *stmt,
- bool (*specific_prepare)(THD *thd),
+ int (*specific_prepare)(THD *thd),
ulong setup_tables_done_option)
{
DBUG_ENTER("select_like_stmt_test");
@@ -1441,7 +1441,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt,
static bool
select_like_stmt_test_with_open_n_lock(Prepared_statement *stmt,
TABLE_LIST *tables,
- bool (*specific_prepare)(THD *thd),
+ int (*specific_prepare)(THD *thd),
ulong setup_tables_done_option)
{
DBUG_ENTER("select_like_stmt_test_with_open_n_lock");
@@ -1630,7 +1630,7 @@ error:
because mysql_handle_derived uses local tables lists.
*/
-static bool mysql_insert_select_prepare_tester(THD *thd)
+static int mysql_insert_select_prepare_tester(THD *thd)
{
SELECT_LEX *first_select= &thd->lex->select_lex;
TABLE_LIST *second_table= ((TABLE_LIST*)first_select->table_list.first)->
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index d6e1582544e..9492fd5337a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -568,37 +568,13 @@ JOIN::prepare(Item ***rref_pointer_array,
/*
Check if there are references to un-aggregated columns when computing
aggregate functions with implicit grouping (there is no GROUP BY).
- TODO: Add check of calculation of GROUP functions and fields:
- SELECT COUNT(*)+table.col1 from table1;
*/
- if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
+ if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !group_list &&
+ select_lex->full_group_by_flag == (NON_AGG_FIELD_USED | SUM_FUNC_USED))
{
- if (!group_list)
- {
- uint flag=0;
- List_iterator_fast<Item> it(fields_list);
- Item *item;
- while ((item= it++))
- {
- if (item->with_sum_func)
- flag|=1;
- else if (!(flag & 2) && !item->const_during_execution())
- flag|=2;
- }
- if (having)
- {
- if (having->with_sum_func)
- flag |= 1;
- else if (!having->const_during_execution())
- flag |= 2;
- }
- if (flag == 3)
- {
- my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
- ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
- DBUG_RETURN(-1);
- }
- }
+ my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
+ ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
+ DBUG_RETURN(-1);
}
{
/* Caclulate the number of groups */
@@ -857,6 +833,7 @@ JOIN::optimize()
"Impossible HAVING" : "Impossible WHERE"));
zero_result_cause= having_value == Item::COND_FALSE ?
"Impossible HAVING" : "Impossible WHERE";
+ tables= 0;
error= 0;
DBUG_RETURN(0);
}
@@ -2138,11 +2115,12 @@ JOIN::exec()
/*
With EXPLAIN EXTENDED we have to restore original ref_array
for a derived table which is always materialized.
- Otherwise we would not be able to print the query correctly.
+ We also need to do this when we have temp table(s).
+ Otherwise we would not be able to print the query correctly.
*/
- if (items0 &&
- (thd->lex->describe & DESCRIBE_EXTENDED) &&
- select_lex->linkage == DERIVED_TABLE_TYPE)
+ if (items0 && (thd->lex->describe & DESCRIBE_EXTENDED) &&
+ (select_lex->linkage == DERIVED_TABLE_TYPE ||
+ exec_tmp_table1 || exec_tmp_table2))
set_items_ref_array(items0);
DBUG_VOID_RETURN;
@@ -14482,7 +14460,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
ifield->db_name= iref->db_name;
}
#ifndef DBUG_OFF
- if (_db_on_ && !item_field->name)
+ if (!item_field->name)
{
char buff[256];
String str(buff,sizeof(buff),&my_charset_bin);
@@ -15818,6 +15796,14 @@ void st_select_lex::print(THD *thd, String *str)
/* go through join tree */
print_join(thd, str, &top_join_list);
}
+ else if (where)
+ {
+ /*
+ "SELECT 1 FROM DUAL WHERE 2" should not be printed as
+ "SELECT 1 WHERE 2": the 1st syntax is valid, but the 2nd is not.
+ */
+ str->append(STRING_WITH_LEN(" from DUAL "));
+ }
// Where
Item *cur_where= where;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1eb6838d98e..1230e8df494 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -4105,9 +4105,11 @@ bool get_schema_tables_result(JOIN *join,
{
result= 1;
join->error= 1;
+ tab->read_record.file= table_list->table->file;
table_list->schema_table_state= executed_place;
break;
}
+ tab->read_record.file= table_list->table->file;
table_list->schema_table_state= executed_place;
}
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 48bdfd87f9f..accd943a05b 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2118,6 +2118,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
const char **ext= table->file->bas_ext();
MY_STAT stat_info;
+ if (table->s->frm_version != FRM_VER_TRUE_VARCHAR)
+ {
+ error= send_check_errmsg(thd, table_list, "repair",
+ "Failed reparing incompatible .FRM file");
+ goto end;
+ }
+
/*
Check if this is a table type that stores index and data separately,
like ISAM or MyISAM. We assume fixed order of engine file name
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 25a0540e4dd..da5e118b069 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -444,7 +444,9 @@ bool st_select_lex_unit::exec()
}
/* re-enabling indexes for next subselect iteration */
if (union_distinct && table->file->enable_indexes(HA_KEY_SWITCH_ALL))
+ {
DBUG_ASSERT(0);
+ }
}
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
{
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index e4965748e24..7c619092df1 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -716,7 +716,7 @@ static table_map get_table_map(List<Item> *items)
TRUE Error
*/
-bool mysql_multi_update_prepare(THD *thd)
+int mysql_multi_update_prepare(THD *thd)
{
LEX *lex= thd->lex;
TABLE_LIST *table_list= lex->query_tables;
@@ -1440,6 +1440,12 @@ bool multi_update::send_data(List<Item> &not_used_values)
tbl->file->position(tbl->record[0]);
memcpy((char*) tmp_table->field[field_num]->ptr,
(char*) tbl->file->ref, tbl->file->ref_length);
+ /*
+ For outer joins a rowid field may have no NOT_NULL_FLAG,
+ so we have to reset NULL bit for this field.
+ (set_notnull() resets NULL bit only if available).
+ */
+ tmp_table->field[field_num]->set_notnull();
field_num++;
} while ((tbl= tbl_it++));
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 3056109e86b..fee71e01c78 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -649,7 +649,11 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
buff.append(')');
}
buff.append(STRING_WITH_LEN(" AS "));
- buff.append(views->source.str, views->source.length);
+ buff.append(views->query.str, views->query.length);
+ if (views->with_check == VIEW_CHECK_LOCAL)
+ buff.append(STRING_WITH_LEN(" WITH LOCAL CHECK OPTION"));
+ else if (views->with_check == VIEW_CHECK_CASCADED)
+ buff.append(STRING_WITH_LEN(" WITH CASCADED CHECK OPTION"));
Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE);
mysql_bin_log.write(&qinfo);
@@ -926,8 +930,6 @@ loop_out:
}
DBUG_RETURN(0);
err:
- view->query.str= NULL;
- view->query.length= 0;
view->md5.str= NULL;
view->md5.length= 0;
DBUG_RETURN(error);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 6eae98e14db..02692855c4d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1187,7 +1187,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
single_multi table_wild_list table_wild_one opt_wild
union_clause union_list
precision subselect_start opt_and charset
- subselect_end select_var_list select_var_list_init help opt_len
+ subselect_end select_var_list select_var_list_init help opt_field_length field_length
opt_extended_describe
prepare prepare_src execute deallocate
statement sp_suid
@@ -3144,45 +3144,38 @@ field_spec:
};
type:
- int_type opt_len field_options { $$=$1; }
+ int_type opt_field_length field_options { $$=$1; }
| real_type opt_precision field_options { $$=$1; }
| FLOAT_SYM float_options field_options { $$=FIELD_TYPE_FLOAT; }
| BIT_SYM { Lex->length= (char*) "1";
$$=FIELD_TYPE_BIT; }
- | BIT_SYM '(' NUM ')' { Lex->length= $3.str;
- $$=FIELD_TYPE_BIT; }
+ | BIT_SYM field_length { $$=FIELD_TYPE_BIT; }
| BOOL_SYM { Lex->length=(char*) "1";
$$=FIELD_TYPE_TINY; }
| BOOLEAN_SYM { Lex->length=(char*) "1";
$$=FIELD_TYPE_TINY; }
- | char '(' NUM ')' opt_binary { Lex->length=$3.str;
- $$=FIELD_TYPE_STRING; }
+ | char field_length opt_binary { $$=FIELD_TYPE_STRING; }
| char opt_binary { Lex->length=(char*) "1";
$$=FIELD_TYPE_STRING; }
- | nchar '(' NUM ')' opt_bin_mod { Lex->length=$3.str;
- $$=FIELD_TYPE_STRING;
+ | nchar field_length opt_bin_mod { $$=FIELD_TYPE_STRING;
Lex->charset=national_charset_info; }
| nchar opt_bin_mod { Lex->length=(char*) "1";
$$=FIELD_TYPE_STRING;
Lex->charset=national_charset_info; }
- | BINARY '(' NUM ')' { Lex->length=$3.str;
- Lex->charset=&my_charset_bin;
+ | BINARY field_length { Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_STRING; }
| BINARY { Lex->length= (char*) "1";
Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_STRING; }
- | varchar '(' NUM ')' opt_binary { Lex->length=$3.str;
- $$= MYSQL_TYPE_VARCHAR; }
- | nvarchar '(' NUM ')' opt_bin_mod { Lex->length=$3.str;
- $$= MYSQL_TYPE_VARCHAR;
+ | varchar field_length opt_binary { $$= MYSQL_TYPE_VARCHAR; }
+ | nvarchar field_length opt_bin_mod { $$= MYSQL_TYPE_VARCHAR;
Lex->charset=national_charset_info; }
- | VARBINARY '(' NUM ')' { Lex->length=$3.str;
- Lex->charset=&my_charset_bin;
+ | VARBINARY field_length { Lex->charset=&my_charset_bin;
$$= MYSQL_TYPE_VARCHAR; }
- | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; }
+ | YEAR_SYM opt_field_length field_options { $$=FIELD_TYPE_YEAR; }
| DATE_SYM { $$=FIELD_TYPE_DATE; }
| TIME_SYM { $$=FIELD_TYPE_TIME; }
- | TIMESTAMP opt_len
+ | TIMESTAMP opt_field_length
{
if (YYTHD->variables.sql_mode & MODE_MAXDB)
$$=FIELD_TYPE_DATETIME;
@@ -3198,7 +3191,7 @@ type:
| DATETIME { $$=FIELD_TYPE_DATETIME; }
| TINYBLOB { Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_TINY_BLOB; }
- | BLOB_SYM opt_len { Lex->charset=&my_charset_bin;
+ | BLOB_SYM opt_field_length { Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_BLOB; }
| spatial_type
{
@@ -3220,7 +3213,7 @@ type:
$$=FIELD_TYPE_MEDIUM_BLOB; }
| LONG_SYM varchar opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; }
| TINYTEXT opt_binary { $$=FIELD_TYPE_TINY_BLOB; }
- | TEXT_SYM opt_len opt_binary { $$=FIELD_TYPE_BLOB; }
+ | TEXT_SYM opt_field_length opt_binary { $$=FIELD_TYPE_BLOB; }
| MEDIUMTEXT opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; }
| LONGTEXT opt_binary { $$=FIELD_TYPE_LONG_BLOB; }
| DECIMAL_SYM float_options field_options
@@ -3293,7 +3286,7 @@ real_type:
float_options:
/* empty */ { Lex->dec=Lex->length= (char*)0; }
- | '(' NUM ')' { Lex->length=$2.str; Lex->dec= (char*)0; }
+ | field_length { Lex->dec= (char*)0; }
| precision {};
precision:
@@ -3316,9 +3309,15 @@ field_option:
| UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
| ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; };
-opt_len:
- /* empty */ { Lex->length=(char*) 0; } /* use default length */
- | '(' NUM ')' { Lex->length= $2.str; };
+opt_field_length:
+ /* empty */ { Lex->length=(char*) NULL; } /* use default length */
+ | field_length {};
+
+field_length:
+ '(' LONG_NUM ')' { Lex->length= $2.str; }
+ | '(' ULONGLONG_NUM ')' { Lex->length= $2.str; }
+ | '(' DECIMAL_NUM ')' { Lex->length= $2.str; }
+ | '(' NUM ')' { Lex->length= $2.str; };
opt_precision:
/* empty */ {}
@@ -5587,9 +5586,9 @@ in_sum_expr:
};
cast_type:
- BINARY opt_len { $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; }
- | CHAR_SYM opt_len opt_binary { $$=ITEM_CAST_CHAR; Lex->dec= 0; }
- | NCHAR_SYM opt_len { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; }
+ BINARY opt_field_length { $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; }
+ | CHAR_SYM opt_field_length opt_binary { $$=ITEM_CAST_CHAR; Lex->dec= 0; }
+ | NCHAR_SYM opt_field_length { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; }
| SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
| SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
| UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
diff --git a/sql/tztime.cc b/sql/tztime.cc
index bedbf921cae..709e3b64752 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1035,7 +1035,7 @@ public:
return lowest possible my_time_t in case of ambiguity or if we
provide time corresponding to the time-gap.
- You should call init_time() function before using this function.
+ You should call my_init_time() function before using this function.
RETURN VALUE
Corresponding my_time_t value or 0 in case of error
@@ -2278,7 +2278,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
DBUG_ENTER("my_tz_find");
DBUG_PRINT("enter", ("time zone name='%s'",
- name ? ((String *)name)->c_ptr() : "NULL"));
+ name ? ((String *)name)->c_ptr_safe() : "NULL"));
DBUG_ASSERT(!time_zone_tables_exist || tz_tables || current_thd->slave_thread);
@@ -2757,7 +2757,7 @@ main(int argc, char **argv)
}
printf("gmt_sec_to_TIME = localtime for time_t in [1000000000,1100000000) range\n");
- init_time();
+ my_init_time();
/*
Be careful here! my_system_gmt_sec doesn't fully handle unnormalized
diff --git a/sql/unireg.h b/sql/unireg.h
index d8301060cc4..1326b22c8c9 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -60,6 +60,7 @@
#define MAX_MBWIDTH 3 /* Max multibyte sequence */
#define MAX_FIELD_CHARLENGTH 255
#define MAX_FIELD_VARCHARLENGTH 65535
+#define MAX_FIELD_BLOBLENGTH UINT_MAX32 /* cf field_blob::get_length() */
#define CONVERT_IF_BIGGER_TO_BLOB 512 /* Used for CREATE ... SELECT */
/* Max column width +1 */