diff options
-rw-r--r-- | Docs/manual.texi | 5 | ||||
-rw-r--r-- | mysql-test/r/variables.result | 11 | ||||
-rw-r--r-- | mysql-test/t/variables.test | 13 | ||||
-rw-r--r-- | sql/item_func.cc | 38 | ||||
-rw-r--r-- | sql/item_func.h | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 |
6 files changed, 72 insertions, 1 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index f3f3cdec961..101aa22a883 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46888,6 +46888,11 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.47 @itemize @bullet @item +Fixed in when using the following construct: +@code{SELECT ... WHERE key=@@var_name OR $key=@@var_name2} +@item +Restrict InnoDB keys to 500 bytes. +@item InnoDB now supports @code{NULL} in keys. @item Fixed shutdown problem on HPUX. (Introduced in 3.23.46) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index f852378e6a1..ab60d5042b0 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -12,3 +12,14 @@ NULL NULL NULL NULL 5 5 1 4 @t5 1.23456 +@min_cid:=min(c_id) @max_cid:=max(c_id) +1 4 +c_id c_name c_country +1 Bozo USA +4 Mr. Floppy GB +c_id c_name c_country +1 Bozo USA +4 Mr. Floppy GB +c_id c_name c_country +1 Bozo USA +4 Mr. Floppy GB diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index d5ff64d199b..0499263467c 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -1,6 +1,7 @@ # # test variables # +drop table if exists t1; set @`test`=1,@TEST=3,@select=2,@t5=1.23456; select @test,@`select`,@TEST,@not_used; set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL; @@ -14,3 +15,15 @@ select @test_int,@test_double,@test_string,@test_string2; select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3; select @t5; +# +# Test problem with WHERE and variables +# + +CREATE TABLE t1 (c_id INT(4) NOT NULL, c_name CHAR(20), c_country CHAR(3), PRIMARY KEY(c_id)); +INSERT INTO t1 VALUES (1,'Bozo','USA'),(2,'Ronald','USA'),(3,'Kinko','IRE'),(4,'Mr. Floppy','GB'); +SELECT @min_cid:=min(c_id), @max_cid:=max(c_id) from t1; +SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid; +SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid OR c_id=666; +ALTER TABLE t1 DROP PRIMARY KEY; +select * from t1 where c_id=@min_cid OR c_id=@max_cid; +drop table t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 94464bdc594..e7e8964b07a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1772,6 +1772,16 @@ Item_func_set_user_var::val_str(String *str) } +void Item_func_set_user_var::print(String *str) +{ + str->append('('); + str->append(name.str,name.length); + str->append(":=",2); + args[0]->print(str); + str->append(')'); +} + + user_var_entry *Item_func_get_user_var::get_entry() { if (!entry || ! entry->value) @@ -1864,6 +1874,34 @@ enum Item_result Item_func_get_user_var::result_type() const return entry->type; } + +void Item_func_get_user_var::print(String *str) +{ + str->append('@'); + str->append(name.str,name.length); + str->append(')'); +} + +bool Item_func_get_user_var::eq(const Item *item) const +{ + /* Assume we don't have rtti */ + if (this == item) + return 1; // Same item is same. + /* Check if other type is also a get_user_var() object */ +#ifdef FIX_THIS + if (item->eq == &Item_func_get_user_var::eq) + return 0; +#else + if (item->type() != FUNC_ITEM || + ((Item_func*) item)->func_name() != func_name()) + return 0; +#endif + Item_func_get_user_var *other=(Item_func_get_user_var*) item; + return (name.length == other->name.length && + !memcmp(name.str, other->name.str, name.length)); +} + + longlong Item_func_inet_aton::val_int() { uint byte_result = 0; diff --git a/sql/item_func.h b/sql/item_func.h index ac4c230f312..4a8f808de57 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -817,6 +817,7 @@ public: enum Item_result result_type () const { return cached_result_type; } bool fix_fields(THD *thd,struct st_table_list *tables); void fix_length_and_dec(); + void print(String *str); const char *func_name() const { return "set_user_var"; } }; @@ -835,13 +836,16 @@ public: longlong val_int(); String *val_str(String* str); void fix_length_and_dec(); + void print(String *str); enum Item_result result_type() const; const char *func_name() const { return "get_user_var"; } bool const_item() const { return const_var_flag; } table_map used_tables() const { return const_var_flag ? 0 : RAND_TABLE_BIT; } + bool eq(const Item *item) const; }; + class Item_func_inet_aton : public Item_int_func { public: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 330df610b46..9ff64780bdd 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -35,7 +35,7 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref", "MAYBE_REF","ALL","range","index","fulltext" }; static bool make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, - DYNAMIC_ARRAY *keyuse); + DYNAMIC_ARRAY *keyuse); static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse, JOIN_TAB *join_tab, uint tables,COND *conds,table_map table_map); |