diff options
-rw-r--r-- | mysql-test/r/func_str.result | 4 | ||||
-rw-r--r-- | mysql-test/t/func_str.test | 4 | ||||
-rw-r--r-- | sql/item.h | 27 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 4 |
6 files changed, 35 insertions, 8 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 94fb570381a..00642e1a570 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1136,12 +1136,12 @@ ALTER TABLE t1 ADD INDEX (code); CREATE TABLE t2 (id varchar(10) PRIMARY KEY); INSERT INTO t2 VALUES ('a11'), ('a12'), ('a13'), ('a14'); SELECT * FROM t1 INNER JOIN t2 ON t1.code=t2.id -WHERE t2.id='a12' AND (code < 'a00' OR LENGTH(code)=5); +WHERE t2.id='a12' AND (LENGTH(code)=5 OR code < 'a00'); code id A12 a12 EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN t2 ON code=id -WHERE id='a12' AND (code < 'a00' OR LENGTH(code)=5); +WHERE id='a12' AND (LENGTH(code)=5 OR code < 'a00'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref code code 13 const 3 Using where; Using index 1 SIMPLE t2 ref PRIMARY PRIMARY 12 const 1 Using where; Using index diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 415c6d2a44e..45415882ac7 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -773,10 +773,10 @@ CREATE TABLE t2 (id varchar(10) PRIMARY KEY); INSERT INTO t2 VALUES ('a11'), ('a12'), ('a13'), ('a14'); SELECT * FROM t1 INNER JOIN t2 ON t1.code=t2.id - WHERE t2.id='a12' AND (code < 'a00' OR LENGTH(code)=5); + WHERE t2.id='a12' AND (LENGTH(code)=5 OR code < 'a00'); EXPLAIN EXTENDED SELECT * FROM t1 INNER JOIN t2 ON code=id - WHERE id='a12' AND (code < 'a00' OR LENGTH(code)=5); + WHERE id='a12' AND (LENGTH(code)=5 OR code < 'a00'); DROP TABLE t1,t2; diff --git a/sql/item.h b/sql/item.h index f6145d6e20c..cdd0f863aea 100644 --- a/sql/item.h +++ b/sql/item.h @@ -411,6 +411,17 @@ public: typedef bool (Item::*Item_processor) (byte *arg); +/* + Analyzer function + SYNOPSIS + argp in/out IN: Analysis parameter + OUT: Parameter to be passed to the transformer + + RETURN + TRUE Invoke the transformer + FALSE Don't do it + +*/ typedef bool (Item::*Item_analyzer) (byte **argp); typedef Item* (Item::*Item_transformer) (byte *arg); typedef void (*Cond_traverser) (const Item *item, void *arg); @@ -740,6 +751,22 @@ public: return (this->*transformer)(arg); } + /* + This function performs a generic "compilation" of the Item tree. + The process of compilation is assumed to go as follows: + + compile() + { + if (this->*some_analyzer(...)) + { + compile children if any; + this->*some_transformer(...); + } + } + + i.e. analysis is performed top-down while transformation is done + bottom-up. + */ virtual Item* compile(Item_analyzer analyzer, byte **arg_p, Item_transformer transformer, byte *arg_t) { diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index fa01ae65b0d..3694c01d0aa 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2811,7 +2811,6 @@ Item *Item_cond::compile(Item_analyzer analyzer, byte **arg_p, if (!(this->*analyzer)(arg_p)) return 0; - byte *arg_v= *arg_p; List_iterator<Item> li(list); Item *item; while ((item= li++)) @@ -2820,6 +2819,7 @@ Item *Item_cond::compile(Item_analyzer analyzer, byte **arg_p, The same parameter value of arg_p must be passed to analyze any argument of the condition formula. */ + byte *arg_v= *arg_p; Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t); if (new_item && new_item != item) li.replace(new_item); diff --git a/sql/item_func.cc b/sql/item_func.cc index acd6ec19470..c5588e43b49 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -304,7 +304,6 @@ Item *Item_func::compile(Item_analyzer analyzer, byte **arg_p, { if (!(this->*analyzer)(arg_p)) return 0; - byte *arg_v= *arg_p; if (arg_count) { Item **arg,**arg_end; @@ -314,6 +313,7 @@ Item *Item_func::compile(Item_analyzer analyzer, byte **arg_p, The same parameter value of arg_p must be passed to analyze any argument of the condition formula. */ + byte *arg_v= *arg_p; Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t); if (new_item && *arg != new_item) current_thd->change_item_tree(arg, new_item); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4d2b3cac254..8ba11195c87 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6919,9 +6919,9 @@ static COND *build_equal_items_for_cond(COND *cond, as soon the field is not of a string type or the field reference is an argument of a comparison predicate. */ - byte *dummy; + byte *is_subst_valid= (byte *) 1; cond= cond->compile(&Item::subst_argument_checker, - &dummy, + &is_subst_valid, &Item::equal_fields_propagator, (byte *) inherited); cond->update_used_tables(); |