summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2009-11-20 17:18:37 +0300
committerKonstantin Osipov <kostja@sun.com>2009-11-20 17:18:37 +0300
commit34b11fb627df93e395158a27f48baa1c049ddf85 (patch)
tree126efa7bce0c3c70a1d3c3cb0099c6615f951e39 /sql
parent3937a79886f9c3a1e0c998e66565a71b4a87d984 (diff)
parent5aeeaaf507ac87f6ff56806fe8a356cea7d4a48f (diff)
downloadmariadb-git-34b11fb627df93e395158a27f48baa1c049ddf85.tar.gz
Merge with next-mr
Diffstat (limited to 'sql')
-rw-r--r--sql/event_data_objects.cc2
-rw-r--r--sql/field.cc350
-rw-r--r--sql/field.h42
-rw-r--r--sql/ha_partition.cc3
-rw-r--r--sql/item_cmpfunc.cc3
-rw-r--r--sql/item_func.cc81
-rw-r--r--sql/item_subselect.cc7
-rw-r--r--sql/item_timefunc.cc18
-rw-r--r--sql/mysql_priv.h4
-rw-r--r--sql/opt_sum.cc6
-rw-r--r--sql/share/errmsg.txt1
-rw-r--r--sql/sp.cc3
-rw-r--r--sql/sp_head.cc4
-rw-r--r--sql/sql_cache.cc10
-rw-r--r--sql/sql_class.h14
-rw-r--r--sql/sql_insert.cc14
-rw-r--r--sql/sql_list.h2
-rw-r--r--sql/sql_parse.cc126
-rw-r--r--sql/sql_partition.cc8
-rw-r--r--sql/sql_select.cc8
-rw-r--r--sql/sql_servers.cc4
-rw-r--r--sql/sql_show.cc60
-rw-r--r--sql/sql_string.cc17
-rw-r--r--sql/sql_string.h4
-rw-r--r--sql/sql_trigger.cc4
-rw-r--r--sql/sql_update.cc18
-rw-r--r--sql/sql_yacc.yy36
-rw-r--r--sql/table.h6
-rw-r--r--sql/tztime.cc2
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(&ltime);
- value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(&ltime) : 0;
+ value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(&ltime) *
+ (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, &ltime);
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> &not_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;