diff options
author | unknown <kroki@mysql.com> | 2006-04-12 19:31:00 +0400 |
---|---|---|
committer | unknown <kroki@mysql.com> | 2006-04-12 19:31:00 +0400 |
commit | 886a35bd82c153253007040202116b5f634705f4 (patch) | |
tree | 79c3147160f25f4c191b0d31943796b18cc50c8d /sql | |
parent | daac388624f52f9d95c43d186e9a759ff15fff18 (diff) | |
download | mariadb-git-886a35bd82c153253007040202116b5f634705f4.tar.gz |
Bug#16461: connection_id() does not work properly inside trigger
CONNECTION_ID() was implemented as a constant Item, i.e. an instance of
Item_static_int_func class holding value computed at creation time.
Since Items are created on parsing, and trigger statements are parsed
on table open, the first connection to open a particular table would
effectively set its own CONNECTION_ID() inside trigger statements for
that table.
Re-implement CONNECTION_ID() as a class derived from Item_int_func, and
compute connection_id on every call to fix_fields().
mysql-test/r/trigger.result:
Add result for bug#16461.
mysql-test/t/trigger.test:
Add test case for bug#16461.
sql/item.cc:
Remove now unused class Item_static_int_func.
sql/item.h:
Remove now unused class Item_static_int_func.
sql/item_create.cc:
Use new implementation of CONNECTION_ID().
sql/item_func.cc:
Re-implement CONNECTION_ID() as Item_func_connection_id
(was Item_static_int_func). Set max_length to 10, as it was before.
Compute connection_id dynamically on every call to fix_fields().
sql/item_func.h:
Re-implement CONNECTION_ID() as Item_func_connection_id
(was Item_static_int_func).
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 16 | ||||
-rw-r--r-- | sql/item.h | 12 | ||||
-rw-r--r-- | sql/item_create.cc | 10 | ||||
-rw-r--r-- | sql/item_func.cc | 25 | ||||
-rw-r--r-- | sql/item_func.h | 12 |
5 files changed, 39 insertions, 36 deletions
diff --git a/sql/item.cc b/sql/item.cc index 45a6b0cef31..4d3ce6071eb 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -644,22 +644,6 @@ Item *Item_num::safe_charset_converter(CHARSET_INFO *tocs) } -Item *Item_static_int_func::safe_charset_converter(CHARSET_INFO *tocs) -{ - Item_string *conv; - char buf[64]; - String *s, tmp(buf, sizeof(buf), &my_charset_bin); - s= val_str(&tmp); - if ((conv= new Item_static_string_func(func_name, s->ptr(), s->length(), - s->charset()))) - { - conv->str_value.copy(); - conv->str_value.mark_as_const(); - } - return conv; -} - - Item *Item_static_float_func::safe_charset_converter(CHARSET_INFO *tocs) { Item_string *conv; diff --git a/sql/item.h b/sql/item.h index 3b96091af38..d33e0ae34be 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1387,18 +1387,6 @@ public: }; -class Item_static_int_func :public Item_int -{ - const char *func_name; -public: - Item_static_int_func(const char *str_arg, longlong i, uint length) - :Item_int(NullS, i, length), func_name(str_arg) - {} - Item *safe_charset_converter(CHARSET_INFO *tocs); - void print(String *str) { str->append(func_name); } -}; - - class Item_uint :public Item_int { public: diff --git a/sql/item_create.cc b/sql/item_create.cc index 342ef245a76..bfcb2101d60 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -71,14 +71,8 @@ Item *create_func_ceiling(Item* a) Item *create_func_connection_id(void) { - THD *thd=current_thd; - thd->lex->safe_to_cache_query= 0; - return new Item_static_int_func("connection_id()", - (longlong) - ((thd->slave_thread) ? - thd->variables.pseudo_thread_id : - thd->thread_id), - 10); + current_thd->lex->safe_to_cache_query= 0; + return new Item_func_connection_id(); } Item *create_func_conv(Item* a, Item *b, Item *c) diff --git a/sql/item_func.cc b/sql/item_func.cc index f40f868f75f..d4a0e607fc2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -559,6 +559,31 @@ String *Item_int_func::val_str(String *str) } +void Item_func_connection_id::fix_length_and_dec() +{ + Item_int_func::fix_length_and_dec(); + max_length= 10; +} + + +bool Item_func_connection_id::fix_fields(THD *thd, Item **ref) +{ + if (Item_int_func::fix_fields(thd, ref)) + return TRUE; + + /* + To replicate CONNECTION_ID() properly we should use + pseudo_thread_id on slave, which contains the value of thread_id + on master. + */ + value= ((thd->slave_thread) ? + thd->variables.pseudo_thread_id : + thd->thread_id); + + return FALSE; +} + + /* Check arguments here to determine result's type for a numeric function of two arguments. diff --git a/sql/item_func.h b/sql/item_func.h index ccbbbab1df4..ed5924e8fe1 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -279,6 +279,18 @@ public: }; +class Item_func_connection_id :public Item_int_func +{ + longlong value; + +public: + const char *func_name() const { return "connection_id"; } + void fix_length_and_dec(); + bool fix_fields(THD *thd, Item **ref); + longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } +}; + + class Item_func_signed :public Item_int_func { public: |