summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_str.result4
-rw-r--r--mysql-test/t/func_str.test4
-rw-r--r--sql/item.h27
-rw-r--r--sql/item_cmpfunc.cc2
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/sql_select.cc4
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();