diff options
author | Konstantin Osipov <kostja@sun.com> | 2009-11-20 17:18:37 +0300 |
---|---|---|
committer | Konstantin Osipov <kostja@sun.com> | 2009-11-20 17:18:37 +0300 |
commit | 34b11fb627df93e395158a27f48baa1c049ddf85 (patch) | |
tree | 126efa7bce0c3c70a1d3c3cb0099c6615f951e39 /sql | |
parent | 3937a79886f9c3a1e0c998e66565a71b4a87d984 (diff) | |
parent | 5aeeaaf507ac87f6ff56806fe8a356cea7d4a48f (diff) | |
download | mariadb-git-34b11fb627df93e395158a27f48baa1c049ddf85.tar.gz |
Merge with next-mr
Diffstat (limited to 'sql')
-rw-r--r-- | sql/event_data_objects.cc | 2 | ||||
-rw-r--r-- | sql/field.cc | 350 | ||||
-rw-r--r-- | sql/field.h | 42 | ||||
-rw-r--r-- | sql/ha_partition.cc | 3 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 3 | ||||
-rw-r--r-- | sql/item_func.cc | 81 | ||||
-rw-r--r-- | sql/item_subselect.cc | 7 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 18 | ||||
-rw-r--r-- | sql/mysql_priv.h | 4 | ||||
-rw-r--r-- | sql/opt_sum.cc | 6 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 1 | ||||
-rw-r--r-- | sql/sp.cc | 3 | ||||
-rw-r--r-- | sql/sp_head.cc | 4 | ||||
-rw-r--r-- | sql/sql_cache.cc | 10 | ||||
-rw-r--r-- | sql/sql_class.h | 14 | ||||
-rw-r--r-- | sql/sql_insert.cc | 14 | ||||
-rw-r--r-- | sql/sql_list.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 126 | ||||
-rw-r--r-- | sql/sql_partition.cc | 8 | ||||
-rw-r--r-- | sql/sql_select.cc | 8 | ||||
-rw-r--r-- | sql/sql_servers.cc | 4 | ||||
-rw-r--r-- | sql/sql_show.cc | 60 | ||||
-rw-r--r-- | sql/sql_string.cc | 17 | ||||
-rw-r--r-- | sql/sql_string.h | 4 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 4 | ||||
-rw-r--r-- | sql/sql_update.cc | 18 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 36 | ||||
-rw-r--r-- | sql/table.h | 6 | ||||
-rw-r--r-- | sql/tztime.cc | 2 |
29 files changed, 241 insertions, 616 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 23eec749a30..b2bbd340e14 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -196,7 +196,7 @@ Event_basic::Event_basic() { DBUG_ENTER("Event_basic::Event_basic"); /* init memory root */ - init_alloc_root(&mem_root, 256, 512); + init_sql_alloc(&mem_root, 256, 512); dbname.str= name.str= NULL; dbname.length= name.length= 0; time_zone= NULL; diff --git a/sql/field.cc b/sql/field.cc index dc32624db10..615d081918b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6819,86 +6819,6 @@ int Field_string::do_save_field_metadata(uchar *metadata_ptr) } -/* - Compare two packed keys - - SYNOPSIS - pack_cmp() - a New key - b Original key - length Key length - insert_or_update 1 if this is an insert or update - - RETURN - < 0 a < b - 0 a = b - > 0 a > b -*/ - -int Field_string::pack_cmp(const uchar *a, const uchar *b, uint length, - my_bool insert_or_update) -{ - uint a_length, b_length; - if (length > 255) - { - a_length= uint2korr(a); - b_length= uint2korr(b); - a+= 2; - b+= 2; - } - else - { - a_length= (uint) *a++; - b_length= (uint) *b++; - } - return field_charset->coll->strnncollsp(field_charset, - a, a_length, - b, b_length, - insert_or_update); -} - - -/** - Compare a packed key against row. - - @param key Original key - @param length Key length. (May be less than field length) - @param insert_or_update 1 if this is an insert or update - - @return - < 0 row < key - @return - 0 row = key - @return - > 0 row > key -*/ - -int Field_string::pack_cmp(const uchar *key, uint length, - my_bool insert_or_update) -{ - uint row_length, local_key_length; - uchar *end; - if (length > 255) - { - local_key_length= uint2korr(key); - key+= 2; - } - else - local_key_length= (uint) *key++; - - /* Only use 'length' of key, not field_length */ - end= ptr + length; - while (end > ptr && end[-1] == ' ') - end--; - row_length= (uint) (end - ptr); - - return field_charset->coll->strnncollsp(field_charset, - ptr, row_length, - key, local_key_length, - insert_or_update); -} - - uint Field_string::packed_col_length(const uchar *data_ptr, uint length) { if (length > 255) @@ -7258,90 +7178,6 @@ uchar *Field_varstring::pack(uchar *to, const uchar *from, } -uchar * -Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length, - bool low_byte_first __attribute__((unused))) -{ - uint length= length_bytes == 1 ? (uint) *key : uint2korr(key); - uint local_char_length= ((field_charset->mbmaxlen > 1) ? - max_length/field_charset->mbmaxlen : max_length); - key+= length_bytes; - if (length > local_char_length) - { - local_char_length= my_charpos(field_charset, key, key+length, - local_char_length); - set_if_smaller(length, local_char_length); - } - *to++= (char) (length & 255); - if (max_length > 255) - *to++= (char) (length >> 8); - if (length) - memcpy(to, key, length); - return to+length; -} - - -/** - Unpack a key into a record buffer. - - A VARCHAR key has a maximum size of 64K-1. - In its packed form, the length field is one or two bytes long, - depending on 'max_length'. - - @param to Pointer into the record buffer. - @param key Pointer to the packed key. - @param max_length Key length limit from key description. - - @return - Pointer to end of 'key' (To the next key part if multi-segment key) -*/ - -const uchar * -Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length, - bool low_byte_first __attribute__((unused))) -{ - /* get length of the blob key */ - uint32 length= *key++; - if (max_length > 255) - length+= (*key++) << 8; - - /* put the length into the record buffer */ - if (length_bytes == 1) - *ptr= (uchar) length; - else - int2store(ptr, length); - memcpy(ptr + length_bytes, key, length); - return key + length; -} - -/** - Create a packed key that will be used for storage in the index tree. - - @param to Store packed key segment here - @param from Key segment (as given to index_read()) - @param max_length Max length of key - - @return - end of key storage -*/ - -uchar * -Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length, - bool low_byte_first __attribute__((unused))) -{ - /* Key length is always stored as 2 bytes */ - uint length= uint2korr(from); - if (length > max_length) - length= max_length; - *to++= (char) (length & 255); - if (max_length > 255) - *to++= (char) (length >> 8); - if (length) - memcpy(to, from+HA_KEY_BLOB_LENGTH, length); - return to+length; -} - - /** Unpack a varstring field from row data. @@ -7384,59 +7220,6 @@ Field_varstring::unpack(uchar *to, const uchar *from, } -int Field_varstring::pack_cmp(const uchar *a, const uchar *b, - uint key_length_arg, - my_bool insert_or_update) -{ - uint a_length, b_length; - if (key_length_arg > 255) - { - a_length=uint2korr(a); a+= 2; - b_length=uint2korr(b); b+= 2; - } - else - { - a_length= (uint) *a++; - b_length= (uint) *b++; - } - return field_charset->coll->strnncollsp(field_charset, - a, a_length, - b, b_length, - insert_or_update); -} - - -int Field_varstring::pack_cmp(const uchar *b, uint key_length_arg, - my_bool insert_or_update) -{ - uchar *a= ptr+ length_bytes; - uint a_length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr); - uint b_length; - uint local_char_length= ((field_charset->mbmaxlen > 1) ? - key_length_arg / field_charset->mbmaxlen : - key_length_arg); - - if (key_length_arg > 255) - { - b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH; - } - else - b_length= (uint) *b++; - - if (a_length > local_char_length) - { - local_char_length= my_charpos(field_charset, a, a+a_length, - local_char_length); - set_if_smaller(a_length, local_char_length); - } - - return field_charset->coll->strnncollsp(field_charset, - a, a_length, - b, b_length, - insert_or_update); -} - - uint Field_varstring::packed_col_length(const uchar *data_ptr, uint length) { if (length > 255) @@ -8135,139 +7918,6 @@ const uchar *Field_blob::unpack(uchar *to, DBUG_RETURN(from + master_packlength + length); } -/* Keys for blobs are like keys on varchars */ - -int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg, - my_bool insert_or_update) -{ - uint a_length, b_length; - if (key_length_arg > 255) - { - a_length=uint2korr(a); a+=2; - b_length=uint2korr(b); b+=2; - } - else - { - a_length= (uint) *a++; - b_length= (uint) *b++; - } - return field_charset->coll->strnncollsp(field_charset, - a, a_length, - b, b_length, - insert_or_update); -} - - -int Field_blob::pack_cmp(const uchar *b, uint key_length_arg, - my_bool insert_or_update) -{ - uchar *a; - uint a_length, b_length; - memcpy_fixed(&a,ptr+packlength,sizeof(char*)); - if (!a) - return key_length_arg > 0 ? -1 : 0; - - a_length= get_length(ptr); - if (key_length_arg > 255) - { - b_length= uint2korr(b); b+=2; - } - else - b_length= (uint) *b++; - return field_charset->coll->strnncollsp(field_charset, - a, a_length, - b, b_length, - insert_or_update); -} - -/** Create a packed key that will be used for storage from a MySQL row. */ - -uchar * -Field_blob::pack_key(uchar *to, const uchar *from, uint max_length, - bool low_byte_first __attribute__((unused))) -{ - uchar *save= ptr; - ptr= (uchar*) from; - uint32 length=get_length(); // Length of from string - uint local_char_length= ((field_charset->mbmaxlen > 1) ? - max_length/field_charset->mbmaxlen : max_length); - if (length) - get_ptr((uchar**) &from); - if (length > local_char_length) - local_char_length= my_charpos(field_charset, from, from+length, - local_char_length); - set_if_smaller(length, local_char_length); - *to++= (uchar) length; - if (max_length > 255) // 2 byte length - *to++= (uchar) (length >> 8); - memcpy(to, from, length); - ptr=save; // Restore org row pointer - return to+length; -} - - -/** - Unpack a blob key into a record buffer. - - A blob key has a maximum size of 64K-1. - In its packed form, the length field is one or two bytes long, - depending on 'max_length'. - Depending on the maximum length of a blob, its length field is - put into 1 to 4 bytes. This is a property of the blob object, - described by 'packlength'. - Blobs are internally stored apart from the record buffer, which - contains a pointer to the blob buffer. - - - @param to Pointer into the record buffer. - @param from Pointer to the packed key. - @param max_length Key length limit from key description. - - @return - Pointer into 'from' past the last byte copied from packed key. -*/ - -const uchar * -Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length, - bool low_byte_first __attribute__((unused))) -{ - /* get length of the blob key */ - uint32 length= *from++; - if (max_length > 255) - length+= *from++ << 8; - - /* put the length into the record buffer */ - put_length(to, length); - - /* put the address of the blob buffer or NULL */ - if (length) - memcpy_fixed(to + packlength, &from, sizeof(from)); - else - bzero(to + packlength, sizeof(from)); - - /* point to first byte of next field in 'from' */ - return from + length; -} - - -/** Create a packed key that will be used for storage from a MySQL key. */ - -uchar * -Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length, - bool low_byte_first __attribute__((unused))) -{ - uint length=uint2korr(from); - if (length > max_length) - length=max_length; - *to++= (char) (length & 255); - if (max_length > 255) - *to++= (char) (length >> 8); - if (length) - memcpy(to, from+HA_KEY_BLOB_LENGTH, length); - return to+length; -} - - uint Field_blob::packed_col_length(const uchar *data_ptr, uint length) { if (length > 255) diff --git a/sql/field.h b/sql/field.h index 7235115a888..fb6ca34e88e 100644 --- a/sql/field.h +++ b/sql/field.h @@ -25,7 +25,6 @@ #pragma interface /* gcc class implementation */ #endif -#define NOT_FIXED_DEC 31 #define DATETIME_DEC 6 const uint32 max_field_size= (uint32) 4294967295U; @@ -410,32 +409,11 @@ public: DBUG_RETURN(result); } - virtual uchar *pack_key(uchar* to, const uchar *from, - uint max_length, bool low_byte_first) - { - return pack(to, from, max_length, low_byte_first); - } - virtual uchar *pack_key_from_key_image(uchar* to, const uchar *from, - uint max_length, bool low_byte_first) - { - return pack(to, from, max_length, low_byte_first); - } - virtual const uchar *unpack_key(uchar* to, const uchar *from, - uint max_length, bool low_byte_first) - { - return unpack(to, from, max_length, low_byte_first); - } virtual uint packed_col_length(const uchar *to, uint length) { return length;} virtual uint max_packed_col_length(uint max_length) { return max_length;} - virtual int pack_cmp(const uchar *a,const uchar *b, uint key_length_arg, - my_bool insert_or_update) - { return cmp(a,b); } - virtual int pack_cmp(const uchar *b, uint key_length_arg, - my_bool insert_or_update) - { return cmp(ptr,b); } uint offset(uchar *record) { return (uint) (ptr - record); @@ -1503,9 +1481,6 @@ public: int compatible_field_size(uint field_metadata, const Relay_log_info *rli); uint row_pack_length() { return (field_length + 1); } - int pack_cmp(const uchar *a,const uchar *b,uint key_length, - my_bool insert_or_update); - int pack_cmp(const uchar *b,uint key_length,my_bool insert_or_update); uint packed_col_length(const uchar *to, uint length); uint max_packed_col_length(uint max_length); uint size_of() const { return sizeof(*this); } @@ -1579,16 +1554,8 @@ public: void sql_type(String &str) const; virtual uchar *pack(uchar *to, const uchar *from, uint max_length, bool low_byte_first); - uchar *pack_key(uchar *to, const uchar *from, uint max_length, bool low_byte_first); - uchar *pack_key_from_key_image(uchar* to, const uchar *from, - uint max_length, bool low_byte_first); virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data, bool low_byte_first); - const uchar *unpack_key(uchar* to, const uchar *from, - uint max_length, bool low_byte_first); - int pack_cmp(const uchar *a, const uchar *b, uint key_length, - my_bool insert_or_update); - int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update); int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L); int key_cmp(const uchar *,const uchar*); int key_cmp(const uchar *str, uint length); @@ -1764,17 +1731,8 @@ public: } virtual uchar *pack(uchar *to, const uchar *from, uint max_length, bool low_byte_first); - uchar *pack_key(uchar *to, const uchar *from, - uint max_length, bool low_byte_first); - uchar *pack_key_from_key_image(uchar* to, const uchar *from, - uint max_length, bool low_byte_first); virtual const uchar *unpack(uchar *to, const uchar *from, uint param_data, bool low_byte_first); - const uchar *unpack_key(uchar* to, const uchar *from, - uint max_length, bool low_byte_first); - int pack_cmp(const uchar *a, const uchar *b, uint key_length, - my_bool insert_or_update); - int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update); uint packed_col_length(const uchar *col_ptr, uint length); uint max_packed_col_length(uint max_length); void free() { value.free(); } diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 7e5eccb2374..0d5fc454a0c 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1980,8 +1980,7 @@ partition_element *ha_partition::find_partition_element(uint part_id) return part_elem; } DBUG_ASSERT(0); - my_error(ER_OUT_OF_RESOURCES, MYF(0)); - current_thd->fatal_error(); // Abort + my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR)); return NULL; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index c6b88cd8188..981b4bf0b92 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -855,7 +855,8 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg, else { *is_null= item->get_time(<ime); - value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(<ime) : 0; + value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(<ime) * + (ltime.neg ? -1 : 1) : 0; } /* Do not cache GET_USER_VAR() function as its const_item() may return TRUE diff --git a/sql/item_func.cc b/sql/item_func.cc index 23af528c256..ccb55feff81 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3474,6 +3474,48 @@ void debug_sync_point(const char* lock_name, uint lock_timeout) #endif + +/** + Wait for a given condition to be signaled within the specified timeout. + + @param cond the condition variable to wait on + @param lock the associated mutex + @param abstime the amount of time in seconds to wait + + @retval return value from pthread_cond_timedwait +*/ + +#define INTERRUPT_INTERVAL (5 * ULL(1000000000)) + +static int interruptible_wait(THD *thd, pthread_cond_t *cond, + pthread_mutex_t *lock, double time) +{ + int error; + struct timespec abstime; + ulonglong slice, timeout= (ulonglong) (time * 1000000000.0); + + do + { + /* Wait for a fixed interval. */ + if (timeout > INTERRUPT_INTERVAL) + slice= INTERRUPT_INTERVAL; + else + slice= timeout; + + timeout-= slice; + set_timespec_nsec(abstime, slice); + error= pthread_cond_timedwait(cond, lock, &abstime); + if (error == ETIMEDOUT || error == ETIME) + { + /* Return error if timed out or connection is broken. */ + if (!timeout || !thd->is_connected()) + break; + } + } while (error && timeout); + + return error; +} + /** Get a user level lock. If the thread has an old lock this is first released. @@ -3489,8 +3531,7 @@ longlong Item_func_get_lock::val_int() { DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); - longlong timeout=args[1]->val_int(); - struct timespec abstime; + double timeout= args[1]->val_real(); THD *thd=current_thd; User_level_lock *ull; int error; @@ -3554,12 +3595,11 @@ longlong Item_func_get_lock::val_int() thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_cond= &ull->cond; - set_timespec(abstime,timeout); error= 0; while (ull->locked && !thd->killed) { DBUG_PRINT("info", ("waiting on lock")); - error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime); + error= interruptible_wait(thd, &ull->cond, &LOCK_user_locks, timeout); if (error == ETIMEDOUT || error == ETIME) { DBUG_PRINT("info", ("lock wait timeout")); @@ -3754,13 +3794,13 @@ void Item_func_benchmark::print(String *str, enum_query_type query_type) longlong Item_func_sleep::val_int() { THD *thd= current_thd; - struct timespec abstime; pthread_cond_t cond; + double timeout; int error; DBUG_ASSERT(fixed == 1); - double time= args[0]->val_real(); + timeout= args[0]->val_real(); /* On 64-bit OSX pthread_cond_timedwait() waits forever if passed abstime time has already been exceeded by @@ -3770,10 +3810,8 @@ longlong Item_func_sleep::val_int() We assume that the lines between this test and the call to pthread_cond_timedwait() will be executed in less than 0.00001 sec. */ - if (time < 0.00001) + if (timeout < 0.00001) return 0; - - set_timespec_nsec(abstime, (ulonglong)(time * ULL(1000000000))); pthread_cond_init(&cond, NULL); pthread_mutex_lock(&LOCK_user_locks); @@ -3785,7 +3823,7 @@ longlong Item_func_sleep::val_int() error= 0; while (!thd->killed) { - error= pthread_cond_timedwait(&cond, &LOCK_user_locks, &abstime); + error= interruptible_wait(thd, &cond, &LOCK_user_locks, timeout); if (error == ETIMEDOUT || error == ETIME) break; error= 0; @@ -3817,7 +3855,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size; if (!my_hash_inited(hash)) return 0; - if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME)))) + if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME | ME_FATALERROR)))) return 0; entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+ extra_size; @@ -3955,6 +3993,8 @@ bool Item_func_set_user_var::register_field_in_read_map(uchar *arg) @param dv derivation for new value @param unsigned_arg indiates if a value of type INT_RESULT is unsigned + @note Sets error and fatal error if allocation fails. + @retval false success @retval @@ -3998,7 +4038,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, if (entry->value == pos) entry->value=0; entry->value= (char*) my_realloc(entry->value, length, - MYF(MY_ALLOW_ZERO_PTR | MY_WME)); + MYF(MY_ALLOW_ZERO_PTR | MY_WME | + ME_FATALERROR)); if (!entry->value) return 1; } @@ -4035,7 +4076,6 @@ Item_func_set_user_var::update_hash(void *ptr, uint length, if (::update_hash(entry, (null_value= args[0]->null_value), ptr, length, res_type, cs, dv, unsigned_arg)) { - current_thd->fatal_error(); // Probably end of memory null_value= 1; return 1; } @@ -4768,11 +4808,6 @@ void Item_func_get_user_var::fix_length_and_dec() m_cached_result_type= STRING_RESULT; max_length= MAX_BLOB_WIDTH; } - - if (error) - thd->fatal_error(); - - return; } @@ -4843,18 +4878,16 @@ bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref) void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs) { - if (::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs, - DERIVATION_IMPLICIT, 0 /* unsigned_arg */)) - current_thd->fatal_error(); // Probably end of memory + ::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs, + DERIVATION_IMPLICIT, 0 /* unsigned_arg */); } void Item_user_var_as_out_param::set_value(const char *str, uint length, CHARSET_INFO* cs) { - if (::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs, - DERIVATION_IMPLICIT, 0 /* unsigned_arg */)) - current_thd->fatal_error(); // Probably end of memory + ::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs, + DERIVATION_IMPLICIT, 0 /* unsigned_arg */); } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 0ce9c555fea..a619827b2d3 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1740,8 +1740,6 @@ subselect_union_engine::subselect_union_engine(st_select_lex_unit *u, :subselect_engine(item_arg, result_arg) { unit= u; - if (!result_arg) //out of memory - current_thd->fatal_error(); unit->item= item_arg; } @@ -1753,10 +1751,7 @@ int subselect_single_select_engine::prepare() join= new JOIN(thd, select_lex->item_list, select_lex->options | SELECT_NO_UNLOCK, result); if (!join || !result) - { - thd->fatal_error(); //out of memory - return 1; - } + return 1; /* Fatal error is set already. */ prepared= 1; SELECT_LEX *save_select= thd->lex->current_select; thd->lex->current_select= select_lex; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 84ddc88487d..3009c48cac7 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -865,6 +865,8 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, { const char *end=str+length; uint i; + long msec_length= 0; + while (str != end && !my_isdigit(cs,*str)) str++; @@ -874,12 +876,7 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, const char *start= str; for (value=0; str != end && my_isdigit(cs,*str) ; str++) value= value*LL(10) + (longlong) (*str - '0'); - if (transform_msec && i == count - 1) // microseconds always last - { - long msec_length= 6 - (uint) (str - start); - if (msec_length > 0) - value*= (long) log_10_int[msec_length]; - } + msec_length= 6 - (str - start); values[i]= value; while (str != end && !my_isdigit(cs,*str)) str++; @@ -893,6 +890,10 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, break; } } + + if (transform_msec && msec_length > 0) + values[count - 1] *= (long) log_10_int[msec_length]; + return (str != end); } @@ -1854,7 +1855,7 @@ longlong Item_func_sec_to_time::val_int() sec_to_time(arg_val, args[0]->unsigned_flag, <ime); return (ltime.neg ? -1 : 1) * - ((ltime.hour)*10000 + ltime.minute*100 + ltime.second); + (longlong) ((ltime.hour)*10000 + ltime.minute*100 + ltime.second); } @@ -2666,7 +2667,8 @@ longlong Item_time_typecast::val_int() null_value= 1; return 0; } - return ltime.hour * 10000L + ltime.minute * 100 + ltime.second; + return (ltime.neg ? -1 : 1) * + (longlong) ((ltime.hour)*10000 + ltime.minute*100 + ltime.second); } String *Item_time_typecast::val_str(String *str) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 3cb26c30e13..821b03fc17d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1076,9 +1076,9 @@ inline bool check_access(THD *thd, ulong access, const char *db, return false; } inline bool check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables, - bool no_errors, bool any_combination_of_privileges_will_do, - uint number) + uint number, + bool no_errors) { return false; } #endif /*NO_EMBEDDED_ACCESS_CHECKS*/ diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 13b10ac2e8f..d85e976e9c8 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -175,8 +175,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); if(error) { - tl->table->file->print_error(error, MYF(0)); - tl->table->in_use->fatal_error(); + tl->table->file->print_error(error, MYF(ME_FATALERROR)); return error; } count*= tl->table->file->stats.records; @@ -427,8 +426,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE) return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE /* HA_ERR_LOCK_DEADLOCK or some other error */ - table->file->print_error(error, MYF(0)); - table->in_use->fatal_error(); + table->file->print_error(error, MYF(ME_FATALERROR)); return(error); } removed_tables|= table->map; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 034f987e0e7..b0ea4774a29 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -4880,6 +4880,7 @@ ER_ZLIB_Z_DATA_ERROR spa "ZLIB: Dato de entrada fué corrompido para zlib" ER_CUT_VALUE_GROUP_CONCAT eng "Row %u was cut by GROUP_CONCAT()" + por "Linha %u foi cortada por GROUP_CONCAT()" ER_WARN_TOO_FEW_RECORDS 01000 eng "Row %ld doesn't contain data for all columns" ger "Zeile %ld enthält nicht für alle Felder Daten" diff --git a/sql/sp.cc b/sql/sp.cc index f756e8ddb18..23cdb1ac7a7 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1716,6 +1716,9 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, ret= SP_OK; break; default: + /* Query might have been killed, don't set error. */ + if (thd->killed) + break; /* Any error when loading an existing routine is either some problem with the mysql.proc table, or a parse error because the contents diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 3d2486cd98f..a2f3e03ad57 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1086,7 +1086,6 @@ sp_head::execute(THD *thd) Item_change_list old_change_list; String old_packet; Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer; - Object_creation_ctx *saved_creation_ctx; Warning_info *saved_warning_info, warning_info(thd->warning_info->warn_id()); @@ -4017,10 +4016,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex, TABLE_LIST *table; if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST)))) - { - thd->fatal_error(); return NULL; - } table->db_length= strlen(db); table->db= thd->strmake(db, table->db_length); table->table_name_length= strlen(name); diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 35d2c886119..ed6f593cc2e 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1331,12 +1331,12 @@ end: @param thd Pointer to the thread handler @param sql A pointer to the sql statement * @param query_length Length of the statement in characters - + @return status code - @retval 1 Query was not cached. - @retval 0 The query was cached and user was sent the result. - @retval -1 The query was cached but we didn't have rights to use it. - + @retval 0 Query was not cached. + @retval 1 The query was cached and user was sent the result. + @retval -1 The query was cached but we didn't have rights to use it. + In case of -1, no error is sent to the client. *) The buffer must be allocated memory of size: diff --git a/sql/sql_class.h b/sql/sql_class.h index 5359cabde6b..c0780bc39f7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1982,9 +1982,15 @@ public: DBUG_VOID_RETURN; } inline bool vio_ok() const { return net.vio != 0; } + /** Return FALSE if connection to client is broken. */ + bool is_connected() + { + return vio_ok() ? vio_is_connected(net.vio) : FALSE; + } #else void clear_error(); - inline bool vio_ok() const { return true; } + inline bool vio_ok() const { return TRUE; } + inline bool is_connected() { return TRUE; } #endif /** Mark the current error as fatal. Warning: this does not @@ -1993,6 +1999,7 @@ public: */ inline void fatal_error() { + DBUG_ASSERT(main_da.is_error()); is_fatal_error= 1; DBUG_PRINT("error",("Fatal error set")); } @@ -2158,7 +2165,10 @@ public: else { x_free(db); - db= new_db ? my_strndup(new_db, new_db_len, MYF(MY_WME)) : NULL; + if (new_db) + db= my_strndup(new_db, new_db_len, MYF(MY_WME | ME_FATALERROR)); + else + db= NULL; } db_length= db ? new_db_len : 0; return new_db && !db; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 7edd3b496da..64218ce8657 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1922,20 +1922,17 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) if (! (di= find_handler(thd, table_list))) { if (!(di= new Delayed_insert())) - { - thd->fatal_error(); goto end_create; - } pthread_mutex_lock(&LOCK_thread_count); thread_count++; pthread_mutex_unlock(&LOCK_thread_count); di->thd.set_db(table_list->db, (uint) strlen(table_list->db)); - di->thd.set_query(my_strdup(table_list->table_name, MYF(MY_WME)), 0); + di->thd.set_query(my_strdup(table_list->table_name, + MYF(MY_WME | ME_FATALERROR)), 0); if (di->thd.db == NULL || di->thd.query() == NULL) { /* The error is reported */ delete di; - thd->fatal_error(); goto end_create; } di->table_list= *table_list; // Needed to open table @@ -1953,8 +1950,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) pthread_mutex_unlock(&di->mutex); di->unlock(); delete di; - my_error(ER_CANT_CREATE_THREAD, MYF(0), error); - thd->fatal_error(); + my_error(ER_CANT_CREATE_THREAD, MYF(ME_FATALERROR), error); goto end_create; } @@ -2325,8 +2321,8 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di) } if (!(di->table->file->ha_table_flags() & HA_CAN_INSERT_DELAYED)) { - thd->fatal_error(); - my_error(ER_DELAYED_NOT_SUPPORTED, MYF(0), di->table_list.table_name); + my_error(ER_DELAYED_NOT_SUPPORTED, MYF(ME_FATALERROR), + di->table_list.table_name); goto err; } if (di->table->triggers) diff --git a/sql/sql_list.h b/sql/sql_list.h index 74f4cc0ec0d..e1bf05fff23 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -458,7 +458,7 @@ struct ilink struct ilink **prev,*next; static void *operator new(size_t size) throw () { - return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE)); + return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE | ME_FATALERROR)); } static void operator delete(void* ptr_arg, size_t size) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 094a715902f..a906978ef1f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1369,54 +1369,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->stmt_da->disable_status(); // Don't send anything back error=TRUE; // End server break; - -#ifdef REMOVED - case COM_CREATE_DB: // QQ: To be removed - { - LEX_STRING db, alias; - HA_CREATE_INFO create_info; - - status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]); - if (thd->make_lex_string(&db, packet, packet_length, FALSE) || - thd->make_lex_string(&alias, db.str, db.length, FALSE) || - check_db_name(&db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL"); - break; - } - if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0, - is_schema_db(db.str))) - break; - general_log_print(thd, command, "%.*s", db.length, db.str); - bzero(&create_info, sizeof(create_info)); - mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str), - &create_info, 0); - break; - } - case COM_DROP_DB: // QQ: To be removed - { - status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]); - LEX_STRING db; - - if (thd->make_lex_string(&db, packet, packet_length, FALSE) || - check_db_name(&db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL"); - break; - } - if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, is_schema_db(db.str))) - break; - if (thd->locked_tables || thd->active_transaction()) - { - my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, - ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); - break; - } - general_log_write(thd, command, "%.*s", db.length, db.str); - mysql_rm_db(thd, db.str, 0, 0); - break; - } -#endif #ifndef EMBEDDED_LIBRARY case COM_BINLOG_DUMP: { @@ -2073,7 +2025,6 @@ mysql_execute_command(THD *thd) A better approach would be to reset this for any commands that is not a SHOW command or a select that only access local variables, but for now this is probably good enough. - Don't reset warnings when executing a stored routine. */ if ((sql_command_flags[lex->sql_command] & CF_DIAGNOSTIC_STMT) != 0) thd->warning_info->set_read_only(TRUE); @@ -2276,7 +2227,7 @@ mysql_execute_command(THD *thd) privileges_requested, all_tables, FALSE, UINT_MAX, FALSE); else - res= check_access(thd, privileges_requested, any_db, 0, 0, 0, UINT_MAX); + res= check_access(thd, privileges_requested, any_db, 0, 0, 0, 0); if (res) break; @@ -5830,7 +5781,6 @@ bool check_stack_overrun(THD *thd, long margin, my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE), stack_used, my_thread_stack_size, margin); my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR)); - thd->fatal_error(); return 1; } #ifndef DBUG_OFF @@ -6494,13 +6444,17 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, DBUG_RETURN(0); /* purecov: inspected */ if (table->db.str) { + ptr->is_fqtn= TRUE; ptr->db= table->db.str; ptr->db_length= table->db.length; } else if (lex->copy_db_to(&ptr->db, &ptr->db_length)) DBUG_RETURN(0); + else + ptr->is_fqtn= FALSE; ptr->alias= alias_str; + ptr->is_alias= alias ? TRUE : FALSE; if (lower_case_table_names && table->table.length) table->table.length= my_casedn_str(files_charset_info, table->table.str); ptr->table_name=table->table.str; @@ -7546,6 +7500,63 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables) } +/* + Given a table in the source list, find a correspondent table in the + table references list. + + @param lex Pointer to LEX representing multi-delete. + @param src Source table to match. + @param ref Table references list. + + @remark The source table list (tables listed before the FROM clause + or tables listed in the FROM clause before the USING clause) may + contain table names or aliases that must match unambiguously one, + and only one, table in the target table list (table references list, + after FROM/USING clause). + + @return Matching table, NULL otherwise. +*/ + +static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl, + TABLE_LIST *tables) +{ + TABLE_LIST *match= NULL; + DBUG_ENTER("multi_delete_table_match"); + + for (TABLE_LIST *elem= tables; elem; elem= elem->next_local) + { + int cmp; + + if (tbl->is_fqtn && elem->is_alias) + continue; /* no match */ + if (tbl->is_fqtn && elem->is_fqtn) + cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) || + strcmp(tbl->db, elem->db); + else if (elem->is_alias) + cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias); + else + cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) || + strcmp(tbl->db, elem->db); + + if (cmp) + continue; + + if (match) + { + my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias); + DBUG_RETURN(NULL); + } + + match= elem; + } + + if (!match) + my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE"); + + DBUG_RETURN(match); +} + + /** Link tables in auxilary table list of multi-delete with corresponding elements in main table list, and set proper locks for them. @@ -7571,20 +7582,9 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex) { lex->table_count++; /* All tables in aux_tables must be found in FROM PART */ - TABLE_LIST *walk; - for (walk= tables; walk; walk= walk->next_local) - { - if (!my_strcasecmp(table_alias_charset, - target_tbl->alias, walk->alias) && - !strcmp(walk->db, target_tbl->db)) - break; - } + TABLE_LIST *walk= multi_delete_table_match(lex, target_tbl, tables); if (!walk) - { - my_error(ER_UNKNOWN_TABLE, MYF(0), - target_tbl->table_name, "MULTI DELETE"); DBUG_RETURN(TRUE); - } if (!walk->derived) { target_tbl->table_name= walk->table_name; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index a05e8fbf3ab..c4a6f294718 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2440,8 +2440,7 @@ char *generate_partition_syntax(partition_info *part_info, default: DBUG_ASSERT(0); /* We really shouldn't get here, no use in continuing from here */ - my_error(ER_OUT_OF_RESOURCES, MYF(0)); - current_thd->fatal_error(); + my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR)); DBUG_RETURN(NULL); } if (part_info->part_expr) @@ -5503,10 +5502,7 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) &lpt->deleted, lpt->pack_frm_data, lpt->pack_frm_len))) { - if (error != ER_OUTOFMEMORY) - file->print_error(error, MYF(0)); - else - lpt->thd->fatal_error(); + file->print_error(error, MYF(error != ER_OUTOFMEMORY ? 0 : ME_FATALERROR)); DBUG_RETURN(TRUE); } DBUG_RETURN(FALSE); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 13197d44ce2..52e66ca8b50 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9760,7 +9760,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item_sum *item_sum=(Item_sum*) item; result= item_sum->create_tmp_field(group, table, convert_blob_length); if (!result) - thd->fatal_error(); + my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR)); return result; } case Item::FIELD_ITEM: @@ -10904,8 +10904,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, We don't want this error to be converted to a warning, e.g. in case of INSERT IGNORE ... SELECT. */ - thd->fatal_error(); - table->file->print_error(error,MYF(0)); + table->file->print_error(error, MYF(ME_FATALERROR)); DBUG_RETURN(1); } @@ -15111,8 +15110,7 @@ calc_group_buffer(JOIN *join,ORDER *group) default: /* This case should never be choosen */ DBUG_ASSERT(0); - my_error(ER_OUT_OF_RESOURCES, MYF(0)); - join->thd->fatal_error(); + my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR)); } } parts++; diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index 8432b68a1d1..b711a273ae8 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -128,7 +128,7 @@ bool servers_init(bool dont_read_servers_table) } /* Initialize the mem root for data */ - init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0); if (dont_read_servers_table) goto end; @@ -179,7 +179,7 @@ static bool servers_load(THD *thd, TABLE_LIST *tables) my_hash_reset(&servers_cache); free_root(&mem, MYF(0)); - init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0); init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0, FALSE); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index b9f5015f8f0..3af0df73079 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1705,6 +1705,32 @@ public: template class I_List<thread_info>; #endif +static const char *thread_state_info(THD *tmp) +{ + if (tmp->locked) + return "Locked"; +#ifndef EMBEDDED_LIBRARY + if (tmp->net.reading_or_writing) + { + if (tmp->net.reading_or_writing == 2) + return "Writing to net"; + else if (tmp->command == COM_SLEEP) + return ""; + else + return "Reading from net"; + } + else +#endif + { + if (tmp->proc_info) + return tmp->proc_info; + else if (tmp->mysys_var && tmp->mysys_var->current_cond) + return "Waiting on cond"; + else + return NULL; + } +} + void mysqld_list_processes(THD *thd,const char *user, bool verbose) { Item *field; @@ -1766,20 +1792,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) if ((mysys_var= tmp->mysys_var)) pthread_mutex_lock(&mysys_var->mutex); thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0); -#ifndef EMBEDDED_LIBRARY - thd_info->state_info= (char*) (tmp->locked ? "Locked" : - tmp->net.reading_or_writing ? - (tmp->net.reading_or_writing == 2 ? - "Writing to net" : - thd_info->command == COM_SLEEP ? "" : - "Reading from net") : - tmp->proc_info ? tmp->proc_info : - tmp->mysys_var && - tmp->mysys_var->current_cond ? - "Waiting on cond" : NullS); -#else - thd_info->state_info= (char*)"Writing to net"; -#endif + thd_info->state_info= thread_state_info(tmp); if (mysys_var) pthread_mutex_unlock(&mysys_var->mutex); @@ -1891,21 +1904,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) table->field[5]->store((longlong)(tmp->start_time ? now - tmp->start_time : 0), FALSE); /* STATE */ -#ifndef EMBEDDED_LIBRARY - val= (char*) (tmp->locked ? "Locked" : - tmp->net.reading_or_writing ? - (tmp->net.reading_or_writing == 2 ? - "Writing to net" : - tmp->command == COM_SLEEP ? "" : - "Reading from net") : - tmp->proc_info ? tmp->proc_info : - tmp->mysys_var && - tmp->mysys_var->current_cond ? - "Waiting on cond" : NullS); -#else - val= (char *) (tmp->proc_info ? tmp->proc_info : NullS); -#endif - if (val) + if ((val= thread_state_info(tmp))) { table->field[6]->store(val, strlen(val), cs); table->field[6]->set_notnull(); @@ -5071,8 +5070,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables, break; default: DBUG_ASSERT(0); - my_error(ER_OUT_OF_RESOURCES, MYF(0)); - current_thd->fatal_error(); + my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR)); DBUG_RETURN(1); } table->field[7]->set_notnull(); diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 593450cacd5..a0ea75a0b0a 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -23,6 +23,7 @@ #include <my_sys.h> #include <m_string.h> #include <m_ctype.h> +#include <mysql_com.h> #ifdef HAVE_FCONVERT #include <floatingpoint.h> #endif @@ -499,22 +500,6 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs) return FALSE; } - -#ifdef TO_BE_REMOVED -bool String::append(FILE* file, uint32 arg_length, myf my_flags) -{ - if (realloc(str_length+arg_length)) - return TRUE; - if (my_fread(file, (uchar*) Ptr + str_length, arg_length, my_flags)) - { - shrink(str_length); - return TRUE; - } - str_length+=arg_length; - return FALSE; -} -#endif - bool String::append(IO_CACHE* file, uint32 arg_length) { if (realloc(str_length+arg_length)) diff --git a/sql/sql_string.h b/sql/sql_string.h index 75dc1163eec..38f843e7e8f 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -22,10 +22,6 @@ #pragma interface /* gcc class implementation */ #endif -#ifndef NOT_FIXED_DEC -#define NOT_FIXED_DEC 31 -#endif - class String; int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 61da4617610..d5c03d902e0 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1660,7 +1660,7 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name) DBUG_ENTER("drop_all_triggers"); bzero(&table, sizeof(table)); - init_alloc_root(&table.mem_root, 8192, 0); + init_sql_alloc(&table.mem_root, 8192, 0); if (Table_triggers_list::check_n_load(thd, db, name, &table, 1)) { @@ -1871,7 +1871,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, DBUG_ENTER("change_table_name"); bzero(&table, sizeof(table)); - init_alloc_root(&table.mem_root, 8192, 0); + init_sql_alloc(&table.mem_root, 8192, 0); /* This method interfaces the mysql server code protected by diff --git a/sql/sql_update.cc b/sql/sql_update.cc index e7b4eb22e78..4ab46107f2c 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -662,11 +662,13 @@ int mysql_update(THD *thd, If (ignore && error is ignorable) we don't have to do anything; otherwise... */ + myf flags= 0; + if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) - thd->fatal_error(); /* Other handler errors are fatal */ + flags|= ME_FATALERROR; /* Other handler errors are fatal */ prepare_record_for_error_message(error, table); - table->file->print_error(error,MYF(0)); + table->file->print_error(error,MYF(flags)); error= 1; break; } @@ -763,9 +765,8 @@ int mysql_update(THD *thd, */ { /* purecov: begin inspected */ - thd->fatal_error(); prepare_record_for_error_message(loc_error, table); - table->file->print_error(loc_error,MYF(0)); + table->file->print_error(loc_error,MYF(ME_FATALERROR)); error= 1; /* purecov: end */ } @@ -1742,11 +1743,13 @@ bool multi_update::send_data(List<Item> ¬_used_values) If (ignore && error == is ignorable) we don't have to do anything; otherwise... */ + myf flags= 0; + if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) - thd->fatal_error(); /* Other handler errors are fatal */ + flags|= ME_FATALERROR; /* Other handler errors are fatal */ prepare_record_for_error_message(error, table); - table->file->print_error(error,MYF(0)); + table->file->print_error(error,MYF(flags)); DBUG_RETURN(1); } } @@ -2029,9 +2032,8 @@ int multi_update::do_updates() err: { - thd->fatal_error(); prepare_record_for_error_message(local_error, table); - table->file->print_error(local_error,MYF(0)); + table->file->print_error(local_error,MYF(ME_FATALERROR)); } err2: diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6ff70bf8a8a..7b264796b30 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1276,7 +1276,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <item> literal text_literal insert_ident order_ident - simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr + simple_ident expr opt_expr opt_else sum_expr in_sum_expr variable variable_aux bool_pri predicate bit_expr table_wild simple_expr udf_expr @@ -1438,7 +1438,7 @@ END_OF_INPUT %type <NONE> '-' '+' '*' '/' '%' '(' ')' ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM - THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM + THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM %% /* @@ -7069,7 +7069,14 @@ select_item_list: ; select_item: - remember_name select_item2 remember_end select_alias + remember_name table_wild remember_end + { + THD *thd= YYTHD; + + if (add_item_to_list(thd, $2)) + MYSQL_YYABORT; + } + | remember_name expr remember_end select_alias { THD *thd= YYTHD; DBUG_ASSERT($1 < $3); @@ -7106,11 +7113,6 @@ remember_end: } ; -select_item2: - table_wild { $$=$1; /* table.* */ } - | expr { $$=$1; } - ; - select_alias: /* empty */ { $$=null_lex_str;} | AS ident { $$=$2; } @@ -10267,7 +10269,7 @@ delete: lex->ignore= 0; lex->select_lex.init_order(); } - opt_delete_options single_multi {} + opt_delete_options single_multi ; single_multi: @@ -10282,45 +10284,45 @@ single_multi: | table_wild_list { mysql_init_multi_delete(Lex); } FROM join_table_list where_clause - { + { if (multi_delete_set_locks_and_link_aux_tables(Lex)) MYSQL_YYABORT; } | FROM table_alias_ref_list { mysql_init_multi_delete(Lex); } USING join_table_list where_clause - { + { if (multi_delete_set_locks_and_link_aux_tables(Lex)) MYSQL_YYABORT; } ; table_wild_list: - table_wild_one {} - | table_wild_list ',' table_wild_one {} + table_wild_one + | table_wild_list ',' table_wild_one ; table_wild_one: - ident opt_wild opt_table_alias + ident opt_wild { Table_ident *ti= new Table_ident($1); if (ti == NULL) MYSQL_YYABORT; if (!Select->add_table_to_list(YYTHD, ti, - $3, + NULL, TL_OPTION_UPDATING | TL_OPTION_ALIAS, Lex->lock_option)) MYSQL_YYABORT; } - | ident '.' ident opt_wild opt_table_alias + | ident '.' ident opt_wild { Table_ident *ti= new Table_ident(YYTHD, $1, $3, 0); if (ti == NULL) MYSQL_YYABORT; if (!Select->add_table_to_list(YYTHD, ti, - $5, + NULL, TL_OPTION_UPDATING | TL_OPTION_ALIAS, Lex->lock_option)) MYSQL_YYABORT; diff --git a/sql/table.h b/sql/table.h index 49a97958807..76bebd3fdaa 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1332,6 +1332,12 @@ struct TABLE_LIST */ bool create; bool internal_tmp_table; + /** TRUE if an alias for this table was specified in the SQL. */ + bool is_alias; + /** TRUE if the table is referred to in the statement using a fully + qualified name (<db_name>.<table_name>). + */ + bool is_fqtn; /* View creation context. */ diff --git a/sql/tztime.cc b/sql/tztime.cc index d4b7ae4b73a..8740a8ec906 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1593,7 +1593,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) my_hash_free(&tz_names); goto end; } - init_alloc_root(&tz_storage, 32 * 1024, 0); + init_sql_alloc(&tz_storage, 32 * 1024, 0); VOID(pthread_mutex_init(&tz_LOCK, MY_MUTEX_INIT_FAST)); tz_inited= 1; |