diff options
-rw-r--r-- | mysql-test/r/derived_cond_pushdown.result | 6436 | ||||
-rw-r--r-- | mysql-test/t/derived_cond_pushdown.test | 812 | ||||
-rw-r--r-- | sql/item.cc | 204 | ||||
-rw-r--r-- | sql/item.h | 121 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 40 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 104 | ||||
-rw-r--r-- | sql/item_func.cc | 3 | ||||
-rw-r--r-- | sql/item_func.h | 158 | ||||
-rw-r--r-- | sql/item_geofunc.h | 69 | ||||
-rw-r--r-- | sql/item_inetfunc.h | 16 | ||||
-rw-r--r-- | sql/item_row.cc | 18 | ||||
-rw-r--r-- | sql/item_row.h | 3 | ||||
-rw-r--r-- | sql/item_strfunc.h | 137 | ||||
-rw-r--r-- | sql/item_subselect.h | 3 | ||||
-rw-r--r-- | sql/item_sum.h | 38 | ||||
-rw-r--r-- | sql/item_timefunc.h | 90 | ||||
-rw-r--r-- | sql/item_windowfunc.h | 17 | ||||
-rw-r--r-- | sql/item_xmlfunc.cc | 34 | ||||
-rw-r--r-- | sql/item_xmlfunc.h | 4 | ||||
-rw-r--r-- | sql/procedure.h | 1 | ||||
-rw-r--r-- | sql/sql_derived.cc | 134 | ||||
-rw-r--r-- | sql/sql_derived.h | 8 | ||||
-rw-r--r-- | sql/sql_lex.cc | 188 | ||||
-rw-r--r-- | sql/sql_lex.h | 23 | ||||
-rw-r--r-- | sql/sql_priv.h | 5 | ||||
-rw-r--r-- | sql/sql_select.cc | 89 | ||||
-rw-r--r-- | sql/sql_select.h | 2 | ||||
-rw-r--r-- | sql/sys_vars.cc | 1 | ||||
-rw-r--r-- | sql/table.cc | 176 | ||||
-rw-r--r-- | sql/table.h | 2 |
30 files changed, 8923 insertions, 13 deletions
diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result new file mode 100644 index 00000000000..3acf1965323 --- /dev/null +++ b/mysql-test/r/derived_cond_pushdown.result @@ -0,0 +1,6436 @@ +create table t1 (a int, b int, c int); +create table t2 (a int, b int, c int, d decimal); +insert into t1 values +(1,21,345), (1,33,7), (8,33,114), (1,21,500), (1,19,107), (5,14,787), +(8,33,123), (9,10,211), (5,16,207), (1,33,988), (5,27,132), (1,21,104), +(6,20,309), (6,20,315), (1,21,101), (8,33,404), (9,10,800), (1,21,123), +(7,11,708), (6,20,214); +insert into t2 values +(2,3,207,207.0000), (1,21,909,12.0000), (7,13,312,406.0000), +(8,64,248,107.0000), (6,20,315,279.3333), (1,19,203,107.0000), +(8,80,800,314.0000), (3,12,231,190.0000), (6,23,303,909.0000); +Warnings: +Note 1265 Data truncated for column 'd' at row 5 +create table t1_double(a int, b double, c double); +insert into t1_double values +(1,23.4,14.3333), (1,12.5,18.9), (3,12.5,18.9), +(4,33.4,14.3333), (4,14.3333,13.65), (5,17.89,7.22), +(6,33.4,14.3), (10,33.4,13.65), (11,33.4,13.65); +create table t2_double(a int, b double, c double); +insert into t2_double values +(1,22.4,14.3333), (1,12.5,18.9), (2,22.4,18.9), +(4,33.4,14.3333), (5,22.4,13.65), (7,17.89,18.9), +(6,33.4,14.3333), (10,31.4,13.65), (12,33.4,13.65); +create table t1_char(a char, b char(8), c int); +insert into t1_char values +('a','Ivan',1), ('b','Vika',2), ('b','Inga',6), ('c','Vika',7), +('b','Ivan',7), ('a','Alex',6), ('b','Inga',5), ('d','Ron',9), +('d','Harry',2), ('d','Hermione',3), ('c','Ivan',3), ('c','Harry',4); +create table t2_char(a char, b char(8), c int); +insert into t2_char values +('b','Ivan',1), ('c','Vinny',3), ('c','Inga',9), ('a','Vika',1), +('c','Ivan',2), ('b','Ali',6), ('c','Inga',2), ('a','Ron',9), +('d','Harry',1), ('b','Hermes',3), ('b','Ivan',11), ('b','Harry',4); +create table t1_decimal (a decimal(3,1), b decimal(3,1), c int); +insert into t1_decimal values +(1,1,23),(2,2,11),(3,3,16), +(1,1,12),(1,1,14),(2,3,15), +(2,1,13),(2,3,11),(3,3,16); +create table t2_decimal (a decimal(3,1), b decimal(3,1), c int); +insert into t2_decimal values +(2,1,13),(2,2,11),(3,3,16), +(1,3,22),(1,3,14),(2,2,15), +(2,1,43),(2,3,11),(2,3,16); +create view v1 as select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707; +create view v2 as select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707; +create view v3 as select a, b, min(c) as min_c from t1 +where t1.a<10 group by a,b having min_c > 109; +create view v4 as +select a, b, min(max_c) as min_c from v1 +where (v1.a<15) group by a,b; +create view v_union as +select a, b, min(c) as c from t1 +where t1.a<10 group by a,b having c > 109 +union +select a, b, max(c) as c from t1 +where t1.b>10 group by a,b having c < 300; +create view v2_union as +select a, b, min(c) as c from t1 +where t1.a<10 group by a,b having c > 109 +union +select a, b, max(c) as c from t1 +where t1.b>10 group by a,b having c < 300 +union +select a, b, avg(c) as c from t1 +where t1.c>300 group by a,b having c < 707; +create view v_double as +select a, avg(a/4) as avg_a, b, c from t1_double +where (b>12.2) group by b,c having (avg_a<22.333); +create view v_char as +select a, b, max(c) as max_c from t1_char +group by a,b having max_c < 9; +create view v_decimal as +select a, b, avg(c) as avg_c from t1_decimal +group by a,b having (avg_c>12); +# conjunctive subformula : pushing into HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.max_c>214) and (t2.a>v1.a); +a b max_c avg_c a b c d +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +6 20 315 279.3333 7 13 312 406 +6 20 315 279.3333 8 64 248 107 +6 20 315 279.3333 8 80 800 314 +select * from v1,t2 where (v1.max_c>214) and (t2.a>v1.a); +a b max_c avg_c a b c d +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +6 20 315 279.3333 7 13 312 406 +6 20 315 279.3333 8 64 248 107 +6 20 315 279.3333 8 80 800 314 +explain select * from v1,t2 where (v1.max_c>214) and (t2.a>v1.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,t2 where (v1.max_c>214) and (t2.a>v1.a); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(v1.max_c > 214)" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(t2.a > v1.a)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c > 214))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +8 33 404 213.6667 8 64 248 107 +6 20 315 279.3333 6 20 315 279 +1 21 500 234.6000 1 19 203 107 +8 33 404 213.6667 8 80 800 314 +6 20 315 279.3333 6 23 303 909 +select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +8 33 404 213.6667 8 64 248 107 +6 20 315 279.3333 6 20 315 279 +1 21 500 234.6000 1 19 203 107 +8 33 404 213.6667 8 80 800 314 +6 20 315 279.3333 6 23 303 909 +explain select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.a is not null)" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v1.max_c > 300)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c > 300))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +# extracted or formula : pushing into HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a)); +a b max_c avg_c a b c d +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +5 27 132 132.0000 2 3 207 207 +5 27 132 132.0000 1 21 909 12 +5 27 132 132.0000 1 19 203 107 +5 27 132 132.0000 3 12 231 190 +select * from v1,t2 where +((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a)); +a b max_c avg_c a b c d +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +5 27 132 132.0000 2 3 207 207 +5 27 132 132.0000 1 21 909 12 +5 27 132 132.0000 1 19 203 107 +5 27 132 132.0000 3 12 231 190 +explain select * from v1,t2 where +((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,t2 where +((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.max_c > 400) or (v1.max_c < 135))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.max_c > 400) and (t2.a > v1.a)) or ((v1.max_c < 135) and (t2.a < v1.a)))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and ((max_c > 400) or (max_c < 135)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +((v1.max_c>300) and (v1.avg_c>t2.d) and (v1.b=t2.b)) or +((v1.max_c<135) and (v1.max_c<t2.c) and (v1.a=t2.a)); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +1 21 500 234.6000 1 21 909 12 +6 20 315 279.3333 6 20 315 279 +select * from v1,t2 where +((v1.max_c>300) and (v1.avg_c>t2.d) and (v1.b=t2.b)) or +((v1.max_c<135) and (v1.max_c<t2.c) and (v1.a=t2.a)); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +1 21 500 234.6000 1 21 909 12 +6 20 315 279.3333 6 20 315 279 +explain select * from v1,t2 where +((v1.max_c>300) and (v1.avg_c>t2.d) and (v1.b=t2.b)) or +((v1.max_c<135) and (v1.max_c<t2.c) and (v1.a=t2.a)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,t2 where +((v1.max_c>300) and (v1.avg_c>t2.d) and (v1.b=t2.b)) or +((v1.max_c<135) and (v1.max_c<t2.c) and (v1.a=t2.a)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.max_c > 300) or (v1.max_c < 135))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.b = t2.b) and (v1.max_c > 300) and (v1.avg_c > t2.d)) or ((v1.a = t2.a) and (v1.max_c < 135) and (v1.max_c < t2.c)))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and ((max_c > 300) or (max_c < 135)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +# conjunctive subformula : pushing into WHERE +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a>6) and (t2.b>v1.b); +a b max_c avg_c a b c d +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 8 80 800 314 +select * from v1,t2 where (v1.a>6) and (t2.b>v1.b); +a b max_c avg_c a b c d +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 8 80 800 314 +explain select * from v1,t2 where (v1.a>6) and (t2.b>v1.b); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where (v1.a>6) and (t2.b>v1.b); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(v1.a > 6)" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(t2.b > v1.b)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 6)" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v2,t2 where (v2.b>25) and (t2.a<v2.a); +a b max_c avg_c a b c d +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +select * from v2,t2 where (v2.b>25) and (t2.a<v2.a); +a b max_c avg_c a b c d +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +explain select * from v2,t2 where (v2.b>25) and (t2.a<v2.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v2,t2 where (v2.b>25) and (t2.a<v2.a); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(v2.b > 25)" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(t2.a < v2.a)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and (t1.b > 25))" + } + } + } + } + } + } + } +} +# extracted or formula : pushing into WHERE +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +((v1.a>7) and (t2.c<v1.max_c)) or ((v1.a<2) and (t2.b<v1.b)); +a b max_c avg_c a b c d +1 19 107 107.0000 2 3 207 207 +1 19 107 107.0000 7 13 312 406 +1 19 107 107.0000 3 12 231 190 +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 1 19 203 107 +1 21 500 234.6000 3 12 231 190 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +select * from v1,t2 where +((v1.a>7) and (t2.c<v1.max_c)) or ((v1.a<2) and (t2.b<v1.b)); +a b max_c avg_c a b c d +1 19 107 107.0000 2 3 207 207 +1 19 107 107.0000 7 13 312 406 +1 19 107 107.0000 3 12 231 190 +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 1 19 203 107 +1 21 500 234.6000 3 12 231 190 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +explain select * from v1,t2 where +((v1.a>7) and (t2.c<v1.max_c)) or ((v1.a<2) and (t2.b<v1.b)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where +((v1.a>7) and (t2.c<v1.max_c)) or ((v1.a<2) and (t2.b<v1.b)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a > 7) or (v1.a < 2))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.a > 7) and (t2.c < v1.max_c)) or ((v1.a < 2) and (t2.b < v1.b)))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 7) or (t1.a < 2))" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v2,t2 where +((v2.a>7) and (t2.c<v2.max_c)) or ((v2.a>5) and (t2.b<v2.b)); +a b max_c avg_c a b c d +6 20 315 279.3333 2 3 207 207 +6 20 315 279.3333 7 13 312 406 +6 20 315 279.3333 1 19 203 107 +6 20 315 279.3333 3 12 231 190 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +select * from v2,t2 where +((v2.a>7) and (t2.c<v2.max_c)) or ((v2.a>5) and (t2.b<v2.b)); +a b max_c avg_c a b c d +6 20 315 279.3333 2 3 207 207 +6 20 315 279.3333 7 13 312 406 +6 20 315 279.3333 1 19 203 107 +6 20 315 279.3333 3 12 231 190 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +explain select * from v2,t2 where +((v2.a>7) and (t2.c<v2.max_c)) or ((v2.a>5) and (t2.b<v2.b)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v2,t2 where +((v2.a>7) and (t2.c<v2.max_c)) or ((v2.a>5) and (t2.b<v2.b)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v2.a > 7) or (v2.a > 5))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v2.a > 7) and (t2.c < v2.max_c)) or ((v2.a > 5) and (t2.b < v2.b)))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and ((t1.a > 7) or (t1.a > 5)))" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +((v1.a>4) and (v1.b>t2.b) and (v1.max_c=t2.d)) or +((v1.a<2) and (v1.max_c<t2.c) and (v1.max_c=t2.d)); +a b max_c avg_c a b c d +1 19 107 107.0000 8 64 248 107 +1 19 107 107.0000 1 19 203 107 +5 16 207 207.0000 2 3 207 207 +select * from v1,t2 where +((v1.a>4) and (v1.b>t2.b) and (v1.max_c=t2.d)) or +((v1.a<2) and (v1.max_c<t2.c) and (v1.max_c=t2.d)); +a b max_c avg_c a b c d +1 19 107 107.0000 8 64 248 107 +1 19 107 107.0000 1 19 203 107 +5 16 207 207.0000 2 3 207 207 +explain select * from v1,t2 where +((v1.a>4) and (v1.b>t2.b) and (v1.max_c=t2.d)) or +((v1.a<2) and (v1.max_c<t2.c) and (v1.max_c=t2.d)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where +((v1.a>4) and (v1.b>t2.b) and (v1.max_c=t2.d)) or +((v1.a<2) and (v1.max_c<t2.c) and (v1.max_c=t2.d)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a > 4) or (v1.a < 2))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.a > 4) and (v1.b > t2.b) and (v1.max_c = t2.d)) or ((v1.a < 2) and (v1.max_c < t2.c) and (v1.max_c = t2.d)))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 4) or (t1.a < 2))" + } + } + } + } + } + } + } +} +# conjunctive subformulas : pushing into HAVING and WHERE +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a<2) and (v1.max_c>400) and (t2.b>v1.b); +a b max_c avg_c a b c d +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 6 23 303 909 +select * from v1,t2 where (v1.a<2) and (v1.max_c>400) and (t2.b>v1.b); +a b max_c avg_c a b c d +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 6 23 303 909 +explain select * from v1,t2 where (v1.a<2) and (v1.max_c>400) and (t2.b>v1.b); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where (v1.a<2) and (v1.max_c>400) and (t2.b>v1.b); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a < 2) and (v1.max_c > 400))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(t2.b > v1.b)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c > 400))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a < 2)" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_double as v,t2_double as t where +(v.a=t.a) and (v.avg_a>0.45) and (v.b>10); +a avg_a b c a b c +1 0.50000000 12.5 18.9 1 22.4 14.3333 +1 0.50000000 12.5 18.9 1 12.5 18.9 +4 1.00000000 33.4 14.3333 4 33.4 14.3333 +4 1.00000000 14.3333 13.65 4 33.4 14.3333 +5 1.25000000 17.89 7.22 5 22.4 13.65 +6 1.50000000 33.4 14.3 6 33.4 14.3333 +10 2.62500000 33.4 13.65 10 31.4 13.65 +select * from v_double as v,t2_double as t where +(v.a=t.a) and (v.avg_a>0.45) and (v.b>10); +a avg_a b c a b c +1 0.50000000 12.5 18.9 1 22.4 14.3333 +1 0.50000000 12.5 18.9 1 12.5 18.9 +4 1.00000000 33.4 14.3333 4 33.4 14.3333 +4 1.00000000 14.3333 13.65 4 33.4 14.3333 +5 1.25000000 17.89 7.22 5 22.4 13.65 +6 1.50000000 33.4 14.3 6 33.4 14.3333 +10 2.62500000 33.4 13.65 10 31.4 13.65 +explain select * from v_double as v,t2_double as t where +(v.a=t.a) and (v.avg_a>0.45) and (v.b>10); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t.a 2 Using where +2 DERIVED t1_double ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort +explain format=json select * from v_double as v,t2_double as t where +(v.a=t.a) and (v.avg_a>0.45) and (v.b>10); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t.a is not null)" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v.avg_a > 0.45) and (v.b > 10))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((avg_a < 22.333) and (avg_a > 0.45))", + "filesort": { + "sort_key": "t1_double.b, t1_double.c", + "temporary_table": { + "table": { + "table_name": "t1_double", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t1_double.b > 12.2) and (t1_double.b > 10))" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_decimal as v,t2_decimal as t where +(v.a=t.a) and (v.avg_c>15) and (v.b>1); +a b avg_c a b c +3.0 3.0 16.0000 3.0 3.0 16 +select * from v_decimal as v,t2_decimal as t where +(v.a=t.a) and (v.avg_c>15) and (v.b>1); +a b avg_c a b c +3.0 3.0 16.0000 3.0 3.0 16 +explain select * from v_decimal as v,t2_decimal as t where +(v.a=t.a) and (v.avg_c>15) and (v.b>1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 3 test.t.a 2 Using where +2 DERIVED t1_decimal ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort +explain format=json select * from v_decimal as v,t2_decimal as t where +(v.a=t.a) and (v.avg_c>15) and (v.b>1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t.a is not null)" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "3", + "used_key_parts": ["a"], + "ref": ["test.t.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v.avg_c > 15) and (v.b > 1))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((avg_c > 12) and (avg_c > 15))", + "filesort": { + "sort_key": "t1_decimal.a, t1_decimal.b", + "temporary_table": { + "table": { + "table_name": "t1_decimal", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t1_decimal.b > 1)" + } + } + } + } + } + } + } +} +# extracted or formula : pushing into HAVING and WHERE +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +((v1.a>7) and (v1.max_c>300) and (t2.c<v1.max_c)) or +((v1.a<4) and (v1.max_c<500) and (t2.b<v1.b)); +a b max_c avg_c a b c d +1 19 107 107.0000 2 3 207 207 +1 19 107 107.0000 7 13 312 406 +1 19 107 107.0000 3 12 231 190 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +select * from v1,t2 where +((v1.a>7) and (v1.max_c>300) and (t2.c<v1.max_c)) or +((v1.a<4) and (v1.max_c<500) and (t2.b<v1.b)); +a b max_c avg_c a b c d +1 19 107 107.0000 2 3 207 207 +1 19 107 107.0000 7 13 312 406 +1 19 107 107.0000 3 12 231 190 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +explain select * from v1,t2 where +((v1.a>7) and (v1.max_c>300) and (t2.c<v1.max_c)) or +((v1.a<4) and (v1.max_c<500) and (t2.b<v1.b)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where +((v1.a>7) and (v1.max_c>300) and (t2.c<v1.max_c)) or +((v1.a<4) and (v1.max_c<500) and (t2.b<v1.b)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(((v1.a > 7) and (v1.max_c > 300)) or ((v1.a < 4) and (v1.max_c < 500)))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.a > 7) and (v1.max_c > 300) and (t2.c < v1.max_c)) or ((v1.a < 4) and (v1.max_c < 500) and (t2.b < v1.b)))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (((t1.a > 7) and (max_c > 300)) or ((t1.a < 4) and (max_c < 500))))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 7) or (t1.a < 4))" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where ((v1.a<2) and (v1.max_c>120)) or (v1.a>7); +a b max_c avg_c a b c d +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 1 21 909 12 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 1 19 203 107 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 8 80 800 314 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +select * from v1,t2 where ((v1.a<2) and (v1.max_c>120)) or (v1.a>7); +a b max_c avg_c a b c d +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 1 21 909 12 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 1 19 203 107 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 8 80 800 314 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +explain select * from v1,t2 where ((v1.a<2) and (v1.max_c>120)) or (v1.a>7); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where ((v1.a<2) and (v1.max_c>120)) or (v1.a>7); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(((v1.a < 2) and (v1.max_c > 120)) or (v1.a > 7))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.a < 2) and (v1.max_c > 120)) or (v1.a > 7))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (((t1.a < 2) and (max_c > 120)) or (t1.a > 7)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 2) or (t1.a > 7))" + } + } + } + } + } + } + } +} +# extracted or formulas : pushing into WHERE and HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +((v1.a<2) and (v1.max_c>120) and (v1.b=t2.b)) or (v1.a>7); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 8 80 800 314 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +select * from v1,t2 where +((v1.a<2) and (v1.max_c>120) and (v1.b=t2.b)) or (v1.a>7); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 8 80 800 314 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +explain select * from v1,t2 where +((v1.a<2) and (v1.max_c>120) and (v1.b=t2.b)) or (v1.a>7); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where +((v1.a<2) and (v1.max_c>120) and (v1.b=t2.b)) or (v1.a>7); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(((v1.a < 2) and (v1.max_c > 120)) or (v1.a > 7))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.b = t2.b) and (v1.a < 2) and (v1.max_c > 120)) or (v1.a > 7))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (((t1.a < 2) and (max_c > 120)) or (t1.a > 7)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 2) or (t1.a > 7))" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +((v1.a<2) and (v1.max_c<200) and (t2.c>v1.max_c) and (v1.max_c=t2.d)) or +((v1.a>4) and (v1.max_c<500) and (t2.b<v1.b) and (v1.max_c=t2.c)); +a b max_c avg_c a b c d +1 19 107 107.0000 8 64 248 107 +1 19 107 107.0000 1 19 203 107 +5 16 207 207.0000 2 3 207 207 +select * from v1,t2 where +((v1.a<2) and (v1.max_c<200) and (t2.c>v1.max_c) and (v1.max_c=t2.d)) or +((v1.a>4) and (v1.max_c<500) and (t2.b<v1.b) and (v1.max_c=t2.c)); +a b max_c avg_c a b c d +1 19 107 107.0000 8 64 248 107 +1 19 107 107.0000 1 19 203 107 +5 16 207 207.0000 2 3 207 207 +explain select * from v1,t2 where +((v1.a<2) and (v1.max_c<200) and (t2.c>v1.max_c) and (v1.max_c=t2.d)) or +((v1.a>4) and (v1.max_c<500) and (t2.b<v1.b) and (v1.max_c=t2.c)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where +((v1.a<2) and (v1.max_c<200) and (t2.c>v1.max_c) and (v1.max_c=t2.d)) or +((v1.a>4) and (v1.max_c<500) and (t2.b<v1.b) and (v1.max_c=t2.c)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(((v1.a < 2) and (v1.max_c < 200)) or (v1.a > 4))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.a < 2) and (v1.max_c < 200) and (t2.c > v1.max_c) and (v1.max_c = t2.d)) or ((v1.max_c = t2.c) and (v1.a > 4) and (t2.c < 500) and (t2.b < v1.b)))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (((t1.a < 2) and (max_c < 200)) or ((t1.a > 4) and (max_c < 500))))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 2) or (t1.a > 4))" + } + } + } + } + } + } + } +} +# prepare of a query containing extracted or formula +prepare stmt from "select * from v1,t2 where + ((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a));"; +execute stmt; +a b max_c avg_c a b c d +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +5 27 132 132.0000 2 3 207 207 +5 27 132 132.0000 1 21 909 12 +5 27 132 132.0000 1 19 203 107 +5 27 132 132.0000 3 12 231 190 +execute stmt; +a b max_c avg_c a b c d +1 21 500 234.6000 2 3 207 207 +5 27 132 132.0000 2 3 207 207 +5 27 132 132.0000 1 21 909 12 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +5 27 132 132.0000 1 19 203 107 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +5 27 132 132.0000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +deallocate prepare stmt; +prepare stmt from +"explain format=json select * from v1,t2 where + ((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a));"; +execute stmt; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.max_c > 400) or (v1.max_c < 135))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.max_c > 400) and (t2.a > v1.a)) or ((v1.max_c < 135) and (t2.a < v1.a)))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and ((max_c > 400) or (max_c < 135)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +execute stmt; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.max_c > 400) or (v1.max_c < 135))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.max_c > 400) and (t2.a > v1.a)) or ((v1.max_c < 135) and (t2.a < v1.a)))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and ((max_c > 400) or (max_c < 135)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +deallocate prepare stmt; +# conjunctive subformula : pushing into WHERE +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (t2.a=v1.a) and (v1.b=t2.b) and (v1.a=1); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +select * from v1,t2 where (t2.a=v1.a) and (v1.b=t2.b) and (v1.a=1); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +explain select * from v1,t2 where (t2.a=v1.a) and (v1.b=t2.b) and (v1.a=1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.b 2 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where (t2.a=v1.a) and (v1.b=t2.b) and (v1.a=1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a = 1) and (t2.b is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["b"], + "ref": ["test.t2.b"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v1.a = 1)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a = 1)" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=5) and (v1.max_c=t2.d); +a b max_c avg_c a b c d +5 16 207 207.0000 2 3 207 207 +select * from v1,t2 where (v1.a=5) and (v1.max_c=t2.d); +a b max_c avg_c a b c d +5 16 207 207.0000 2 3 207 207 +explain select * from v1,t2 where (v1.a=5) and (v1.max_c=t2.d); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.d 2 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where (v1.a=5) and (v1.max_c=t2.d); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.d is not null)" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["max_c"], + "ref": ["test.t2.d"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v1.a = 5) and (v1.max_c = t2.d))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a = 5)" + } + } + } + } + } + } + } +} +# conjunctive subformula : pushing into WHERE using equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (t2.a<5) and (v1.a=t2.a); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +1 19 107 107.0000 1 21 909 12 +1 21 500 234.6000 1 19 203 107 +1 19 107 107.0000 1 19 203 107 +select * from v1,t2 where (t2.a<5) and (v1.a=t2.a); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +1 19 107 107.0000 1 21 909 12 +1 21 500 234.6000 1 19 203 107 +1 19 107 107.0000 1 19 203 107 +explain select * from v1,t2 where (t2.a<5) and (v1.a=t2.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where (t2.a<5) and (v1.a=t2.a); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a < 5) and (t2.a is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a < 5)" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a); +a b max_c avg_c a b c d +select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a); +a b max_c avg_c a b c d +explain select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 10 test.t2.a,test.t2.a 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a is not null) and (t2.a is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "10", + "used_key_parts": ["a", "b"], + "ref": ["test.t2.a", "test.t2.a"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.b = t1.a)" + } + } + } + } + } + } + } +} +# conjunctive subformula : pushing into HAVING using equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (t2.c>150) and (v1.max_c=t2.c); +a b max_c avg_c a b c d +5 16 207 207.0000 2 3 207 207 +6 20 315 279.3333 6 20 315 279 +select * from v1,t2 where (t2.c>150) and (v1.max_c=t2.c); +a b max_c avg_c a b c d +5 16 207 207.0000 2 3 207 207 +6 20 315 279.3333 6 20 315 279 +explain select * from v1,t2 where (t2.c>150) and (v1.max_c=t2.c); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,t2 where (t2.c>150) and (v1.max_c=t2.c); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.c > 150) and (t2.c is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["max_c"], + "ref": ["test.t2.c"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c > 150))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +# extracted and formula : pushing into WHERE +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a) and (v1.a=3); +a b max_c avg_c a b c d +select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a) and (v1.a=3); +a b max_c avg_c a b c d +explain select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a) and (v1.a=3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where +explain format=json select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a) and (v1.a=3); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.a = 3)" + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a = 3) and (v1.b = 3))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a = 3) and (t1.b = 3))" + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=1) and (v1.b=21) and (t2.a=2); +a b max_c avg_c a b c d +1 21 500 234.6000 2 3 207 207 +select * from v1,t2 where (v1.a=1) and (v1.b=21) and (t2.a=2); +a b max_c avg_c a b c d +1 21 500 234.6000 2 3 207 207 +explain select * from v1,t2 where (v1.a=1) and (v1.b=21) and (t2.a=2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where +explain format=json select * from v1,t2 where (v1.a=1) and (v1.b=21) and (t2.a=2); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.a = 2)" + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a = 1) and (v1.b = 21))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a = 1) and (t1.b = 21))" + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_char as v,t2_char as t where +(v.a='c') and (v.b<'Hermes') and ((v.b=t.b) or (v.max_c>20)); +a b max_c a b c +c Harry 4 d Harry 1 +c Harry 4 b Harry 4 +select * from v_char as v,t2_char as t where +(v.a='c') and (v.b<'Hermes') and ((v.b=t.b) or (v.max_c>20)); +a b max_c a b c +c Harry 4 d Harry 1 +c Harry 4 b Harry 4 +explain select * from v_char as v,t2_char as t where +(v.a='c') and (v.b<'Hermes') and ((v.b=t.b) or (v.max_c>20)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 12 Using where +1 PRIMARY t ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1_char ALL NULL NULL NULL NULL 12 Using where; Using temporary; Using filesort +explain format=json select * from v_char as v,t2_char as t where +(v.a='c') and (v.b<'Hermes') and ((v.b=t.b) or (v.max_c>20)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 12, + "filtered": 100, + "attached_condition": "((v.a = 'c') and (v.b < 'Hermes'))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 9)", + "filesort": { + "sort_key": "t1_char.b", + "temporary_table": { + "table": { + "table_name": "t1_char", + "access_type": "ALL", + "rows": 12, + "filtered": 100, + "attached_condition": "((t1_char.a = 'c') and (t1_char.b < 'Hermes'))" + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 12, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((t.b = v.b) or (v.max_c > 20))" + } + } +} +# extracted and formula : pushing into WHERE using equalities +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_decimal as v,t2_decimal as t where +(v.a=v.b) and (v.b=t.b) and ((t.b>1) or (v.a=1)); +a b avg_c a b c +1.0 1.0 16.3333 2.0 1.0 13 +3.0 3.0 16.0000 3.0 3.0 16 +3.0 3.0 16.0000 1.0 3.0 22 +3.0 3.0 16.0000 1.0 3.0 14 +1.0 1.0 16.3333 2.0 1.0 43 +3.0 3.0 16.0000 2.0 3.0 11 +3.0 3.0 16.0000 2.0 3.0 16 +select * from v_decimal as v,t2_decimal as t where +(v.a=v.b) and (v.b=t.b) and ((t.b>1) or (v.a=1)); +a b avg_c a b c +1.0 1.0 16.3333 2.0 1.0 13 +3.0 3.0 16.0000 3.0 3.0 16 +3.0 3.0 16.0000 1.0 3.0 22 +3.0 3.0 16.0000 1.0 3.0 14 +1.0 1.0 16.3333 2.0 1.0 43 +3.0 3.0 16.0000 2.0 3.0 11 +3.0 3.0 16.0000 2.0 3.0 16 +explain select * from v_decimal as v,t2_decimal as t where +(v.a=v.b) and (v.b=t.b) and ((t.b>1) or (v.a=1)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 6 test.t.b,test.t.b 2 +2 DERIVED t1_decimal ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort +explain format=json select * from v_decimal as v,t2_decimal as t where +(v.a=v.b) and (v.b=t.b) and ((t.b>1) or (v.a=1)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(((t.b > 1) or (t.b = 1)) and (t.b is not null) and (t.b is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "6", + "used_key_parts": ["a", "b"], + "ref": ["test.t.b", "test.t.b"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(avg_c > 12)", + "filesort": { + "sort_key": "t1_decimal.a, t1_decimal.b", + "temporary_table": { + "table": { + "table_name": "t1_decimal", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t1_decimal.b = t1_decimal.a) and ((t1_decimal.a > 1) or (t1_decimal.a = 1)))" + } + } + } + } + } + } + } +} +# extracted or formula : pushing into HAVING using equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 +where ((t2.a<4) and (v1.a=t2.a)) or ((t2.c>150) and (v1.max_c=t2.c)); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +1 21 500 234.6000 1 21 909 12 +1 21 500 234.6000 1 19 203 107 +5 16 207 207.0000 2 3 207 207 +6 20 315 279.3333 6 20 315 279 +select * from v1,t2 +where ((t2.a<4) and (v1.a=t2.a)) or ((t2.c>150) and (v1.max_c=t2.c)); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +1 21 500 234.6000 1 21 909 12 +1 21 500 234.6000 1 19 203 107 +5 16 207 207.0000 2 3 207 207 +6 20 315 279.3333 6 20 315 279 +explain select * from v1,t2 +where ((t2.a<4) and (v1.a=t2.a)) or ((t2.c>150) and (v1.max_c=t2.c)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,t2 +where ((t2.a<4) and (v1.a=t2.a)) or ((t2.c>150) and (v1.max_c=t2.c)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a < 4) or (t2.c > 150))" + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.a = t2.a) and (t2.a < 4)) or ((v1.max_c = t2.c) and (t2.c > 150)))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and ((t1.a < 4) or (max_c > 150)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +# conjunctive subformulas : pushing into WHERE and HAVING using equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 +where ((t2.a>5) and (v1.a=t2.a)) and ((t2.c>250) and (v1.max_c=t2.c)); +a b max_c avg_c a b c d +6 20 315 279.3333 6 20 315 279 +select * from v1,t2 +where ((t2.a>5) and (v1.a=t2.a)) and ((t2.c>250) and (v1.max_c=t2.c)); +a b max_c avg_c a b c d +6 20 315 279.3333 6 20 315 279 +explain select * from v1,t2 +where ((t2.a>5) and (v1.a=t2.a)) and ((t2.c>250) and (v1.max_c=t2.c)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 10 test.t2.a,test.t2.c 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 +where ((t2.a>5) and (v1.a=t2.a)) and ((t2.c>250) and (v1.max_c=t2.c)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a > 5) and (t2.c > 250) and (t2.a is not null) and (t2.c is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "10", + "used_key_parts": ["a", "max_c"], + "ref": ["test.t2.a", "test.t2.c"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c > 250))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + } + } +} +# conjunctive subformulas : pushing into WHERE and HAVING +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where (v1.a=8) and (v1.a=t2.a) and (v1.max_c=404); +a b max_c avg_c a b c d +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 8 80 800 314 +select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where (v1.a=8) and (v1.a=t2.a) and (v1.max_c=404); +a b max_c avg_c a b c d +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 8 80 800 314 +explain select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where (v1.a=8) and (v1.a=t2.a) and (v1.max_c=404); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where (v1.a=8) and (v1.a=t2.a) and (v1.max_c=404); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.a = 8)" + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a = 8) and (v1.max_c = 404))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c = 404)", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a = 8)" + } + } + } + } + } + } + } +} +# conjunctive subformulas : pushing into WHERE and HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +(v1.a>3) and (v1.max_c>200) and (t2.b<v1.b) and (t2.d=v1.max_c); +a b max_c avg_c a b c d +5 16 207 207.0000 2 3 207 207 +select * from v1,t2 where +(v1.a>3) and (v1.max_c>200) and (t2.b<v1.b) and (t2.d=v1.max_c); +a b max_c avg_c a b c d +5 16 207 207.0000 2 3 207 207 +explain select * from v1,t2 where +(v1.a>3) and (v1.max_c>200) and (t2.b<v1.b) and (t2.d=v1.max_c); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.d 2 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,t2 where +(v1.a>3) and (v1.max_c>200) and (t2.b<v1.b) and (t2.d=v1.max_c); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.d is not null)" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["max_c"], + "ref": ["test.t2.d"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v1.a > 3) and (v1.max_c > 200) and (t2.b < v1.b) and (t2.d = v1.max_c))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c > 200))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 3)" + } + } + } + } + } + } + } +} +# conjunctive subformula : pushing into WHERE +# extracted or formula : pushing into HAVING using equalities +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_double as v,t2_double as t where +(v.b=v.c) and (v.c=t.c) and ((t.c>10) or (v.a=1)); +a avg_a b c a b c +select * from v_double as v,t2_double as t where +(v.b=v.c) and (v.c=t.c) and ((t.c>10) or (v.a=1)); +a avg_a b c a b c +explain select * from v_double as v,t2_double as t where +(v.b=v.c) and (v.c=t.c) and ((t.c>10) or (v.a=1)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 18 test.t.c,test.t.c 2 Using where +2 DERIVED t1_double ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort +explain format=json select * from v_double as v,t2_double as t where +(v.b=v.c) and (v.c=t.c) and ((t.c>10) or (v.a=1)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t.c is not null) and (t.c is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "18", + "used_key_parts": ["b", "c"], + "ref": ["test.t.c", "test.t.c"], + "rows": 2, + "filtered": 100, + "attached_condition": "((t.c > 10) or (v.a = 1))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((avg_a < 22.333) and ((t1_double.b > 10) or (t1_double.a = 1)))", + "filesort": { + "sort_key": "t1_double.b, t1_double.c", + "temporary_table": { + "table": { + "table_name": "t1_double", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t1_double.c = t1_double.b) and (t1_double.b > 12.2))" + } + } + } + } + } + } + } +} +# conjunctive subformula : pushing into WHERE +# extracted or formula : pushing into HAVING using equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_double as v,t2_double as t where +(((v.a>0.2) or (v.b<17)) or (t.c>17)) and (t.c=v.c) and (v.c>18); +a avg_a b c a b c +1 0.50000000 12.5 18.9 1 12.5 18.9 +1 0.50000000 12.5 18.9 2 22.4 18.9 +1 0.50000000 12.5 18.9 7 17.89 18.9 +select * from v_double as v,t2_double as t where +(((v.a>0.2) or (v.b<17)) or (t.c>17)) and (t.c=v.c) and (v.c>18); +a avg_a b c a b c +1 0.50000000 12.5 18.9 1 12.5 18.9 +1 0.50000000 12.5 18.9 2 22.4 18.9 +1 0.50000000 12.5 18.9 7 17.89 18.9 +explain select * from v_double as v,t2_double as t where +(((v.a>0.2) or (v.b<17)) or (t.c>17)) and (t.c=v.c) and (v.c>18); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 9 test.t.c 2 Using where +2 DERIVED t1_double ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort +explain format=json select * from v_double as v,t2_double as t where +(((v.a>0.2) or (v.b<17)) or (t.c>17)) and (t.c=v.c) and (v.c>18); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t.c > 18) and (t.c is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "9", + "used_key_parts": ["c"], + "ref": ["test.t.c"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v.a > 0.2) or (v.b < 17) or (t.c > 17))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((avg_a < 22.333) and ((t1_double.a > 0.2) or (t1_double.b < 17) or (t1_double.c > 17)))", + "filesort": { + "sort_key": "t1_double.b, t1_double.c", + "temporary_table": { + "table": { + "table_name": "t1_double", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t1_double.b > 12.2) and (t1_double.c > 18))" + } + } + } + } + } + } + } +} +# extracted or formula : pushing into WHERE +# conjunctive subformula : pushing into HAVING +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_decimal as v,t2_decimal as t where +(((v.a>4) or (v.a=2)) or (v.b>3)) and (v.avg_c=13); +a b avg_c a b c +2.0 1.0 13.0000 2.0 1.0 13 +2.0 3.0 13.0000 2.0 1.0 13 +2.0 1.0 13.0000 2.0 2.0 11 +2.0 3.0 13.0000 2.0 2.0 11 +2.0 1.0 13.0000 3.0 3.0 16 +2.0 3.0 13.0000 3.0 3.0 16 +2.0 1.0 13.0000 1.0 3.0 22 +2.0 3.0 13.0000 1.0 3.0 22 +2.0 1.0 13.0000 1.0 3.0 14 +2.0 3.0 13.0000 1.0 3.0 14 +2.0 1.0 13.0000 2.0 2.0 15 +2.0 3.0 13.0000 2.0 2.0 15 +2.0 1.0 13.0000 2.0 1.0 43 +2.0 3.0 13.0000 2.0 1.0 43 +2.0 1.0 13.0000 2.0 3.0 11 +2.0 3.0 13.0000 2.0 3.0 11 +2.0 1.0 13.0000 2.0 3.0 16 +2.0 3.0 13.0000 2.0 3.0 16 +select * from v_decimal as v,t2_decimal as t where +(((v.a>4) or (v.a=2)) or (v.b>3)) and (v.avg_c=13); +a b avg_c a b c +2.0 1.0 13.0000 2.0 1.0 13 +2.0 3.0 13.0000 2.0 1.0 13 +2.0 1.0 13.0000 2.0 2.0 11 +2.0 3.0 13.0000 2.0 2.0 11 +2.0 1.0 13.0000 3.0 3.0 16 +2.0 3.0 13.0000 3.0 3.0 16 +2.0 1.0 13.0000 1.0 3.0 22 +2.0 3.0 13.0000 1.0 3.0 22 +2.0 1.0 13.0000 1.0 3.0 14 +2.0 3.0 13.0000 1.0 3.0 14 +2.0 1.0 13.0000 2.0 2.0 15 +2.0 3.0 13.0000 2.0 2.0 15 +2.0 1.0 13.0000 2.0 1.0 43 +2.0 3.0 13.0000 2.0 1.0 43 +2.0 1.0 13.0000 2.0 3.0 11 +2.0 3.0 13.0000 2.0 3.0 11 +2.0 1.0 13.0000 2.0 3.0 16 +2.0 3.0 13.0000 2.0 3.0 16 +explain select * from v_decimal as v,t2_decimal as t where +(((v.a>4) or (v.a=2)) or (v.b>3)) and (v.avg_c=13); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY t ALL NULL NULL NULL NULL 9 Using join buffer (flat, BNL join) +2 DERIVED t1_decimal ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort +explain format=json select * from v_decimal as v,t2_decimal as t where +(((v.a>4) or (v.a=2)) or (v.b>3)) and (v.avg_c=13); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(((v.a > 4) or (v.a = 2) or (v.b > 3)) and (v.avg_c = 13))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((avg_c > 12) and (avg_c = 13))", + "filesort": { + "sort_key": "t1_decimal.a, t1_decimal.b", + "temporary_table": { + "table": { + "table_name": "t1_decimal", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t1_decimal.a > 4) or (t1_decimal.a = 2) or (t1_decimal.b > 3))" + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL" + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.a=v1.b); +a b max_c avg_c a b c d +select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.a=v1.b); +a b max_c avg_c a b c d +explain select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.a=v1.b); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 10 test.t2.a,test.t2.a 2 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.a=v1.b); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a is not null) and (t2.a is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "10", + "used_key_parts": ["a", "b"], + "ref": ["test.t2.a", "test.t2.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v1.max_c > 300)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c > 300))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.b = t1.a) and (t1.a > 5))" + } + } + } + } + } + } + } +} +# nothing to push +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (t2.a<2) and (t2.c>900); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 21 500 234.6000 1 21 909 12 +5 16 207 207.0000 1 21 909 12 +5 27 132 132.0000 1 21 909 12 +6 20 315 279.3333 1 21 909 12 +8 33 404 213.6667 1 21 909 12 +select * from v1,t2 where (t2.a<2) and (t2.c>900); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 21 500 234.6000 1 21 909 12 +5 16 207 207.0000 1 21 909 12 +5 27 132 132.0000 1 21 909 12 +6 20 315 279.3333 1 21 909 12 +8 33 404 213.6667 1 21 909 12 +explain select * from v1,t2 where (t2.a<2) and (t2.c>900); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,t2 where (t2.a<2) and (t2.c>900); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a < 2) and (t2.c > 900))" + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=t2.a) and (v1.b=t2.b); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +6 20 315 279.3333 6 20 315 279 +1 19 107 107.0000 1 19 203 107 +select * from v1,t2 where (v1.a=t2.a) and (v1.b=t2.b); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +6 20 315 279.3333 6 20 315 279 +1 19 107 107.0000 1 19 203 107 +explain select * from v1,t2 where (v1.a=t2.a) and (v1.b=t2.b); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 10 test.t2.a,test.t2.b 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.b=t2.b); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a is not null) and (t2.b is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "10", + "used_key_parts": ["a", "b"], + "ref": ["test.t2.a", "test.t2.b"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +(t2.a=v1.a) or (v1.b=t2.b) and ((v1.a=1) or (v1.a=6)); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +1 21 500 234.6000 1 21 909 12 +1 21 500 234.6000 1 19 203 107 +6 20 315 279.3333 6 20 315 279 +6 20 315 279.3333 6 23 303 909 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 8 80 800 314 +select * from v1,t2 where +(t2.a=v1.a) or (v1.b=t2.b) and ((v1.a=1) or (v1.a=6)); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +1 21 500 234.6000 1 21 909 12 +1 21 500 234.6000 1 19 203 107 +6 20 315 279.3333 6 20 315 279 +6 20 315 279.3333 6 23 303 909 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 8 80 800 314 +explain select * from v1,t2 where +(t2.a=v1.a) or (v1.b=t2.b) and ((v1.a=1) or (v1.a=6)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,t2 where +(t2.a=v1.a) or (v1.b=t2.b) and ((v1.a=1) or (v1.a=6)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((v1.a = t2.a) or ((v1.b = t2.b) and ((v1.a = 1) or (v1.a = 6))))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a=1) or (v1.b=21) or (t2.a=2); +a b max_c avg_c a b c d +1 19 107 107.0000 2 3 207 207 +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 7 13 312 406 +1 19 107 107.0000 8 64 248 107 +1 19 107 107.0000 6 20 315 279 +1 19 107 107.0000 1 19 203 107 +1 19 107 107.0000 8 80 800 314 +1 19 107 107.0000 3 12 231 190 +1 19 107 107.0000 6 23 303 909 +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 1 21 909 12 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 1 19 203 107 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +5 16 207 207.0000 2 3 207 207 +5 27 132 132.0000 2 3 207 207 +6 20 315 279.3333 2 3 207 207 +8 33 404 213.6667 2 3 207 207 +select * from v1,t2 where (v1.a=1) or (v1.b=21) or (t2.a=2); +a b max_c avg_c a b c d +1 19 107 107.0000 2 3 207 207 +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 7 13 312 406 +1 19 107 107.0000 8 64 248 107 +1 19 107 107.0000 6 20 315 279 +1 19 107 107.0000 1 19 203 107 +1 19 107 107.0000 8 80 800 314 +1 19 107 107.0000 3 12 231 190 +1 19 107 107.0000 6 23 303 909 +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 1 21 909 12 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 1 19 203 107 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +5 16 207 207.0000 2 3 207 207 +5 27 132 132.0000 2 3 207 207 +6 20 315 279.3333 2 3 207 207 +8 33 404 213.6667 2 3 207 207 +explain select * from v1,t2 where (v1.a=1) or (v1.b=21) or (t2.a=2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,t2 where (v1.a=1) or (v1.b=21) or (t2.a=2); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((v1.a = 1) or (v1.b = 21) or (t2.a = 2))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +(t2.a<2) and (t2.c>900) and ((v1.a<t2.a) or (t2.a<11)); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 21 500 234.6000 1 21 909 12 +5 16 207 207.0000 1 21 909 12 +5 27 132 132.0000 1 21 909 12 +6 20 315 279.3333 1 21 909 12 +8 33 404 213.6667 1 21 909 12 +select * from v1,t2 where +(t2.a<2) and (t2.c>900) and ((v1.a<t2.a) or (t2.a<11)); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 21 500 234.6000 1 21 909 12 +5 16 207 207.0000 1 21 909 12 +5 27 132 132.0000 1 21 909 12 +6 20 315 279.3333 1 21 909 12 +8 33 404 213.6667 1 21 909 12 +explain select * from v1,t2 where +(t2.a<2) and (t2.c>900) and ((v1.a<t2.a) or (t2.a<11)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,t2 where +(t2.a<2) and (t2.c>900) and ((v1.a<t2.a) or (t2.a<11)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a < 2) and (t2.c > 900))" + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((v1.a < t2.a) or (t2.a < 11))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +# using several derived tables : nothing to push +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,v2,t2 where +(v1.a=v2.a) and (v1.a=t2.a) and (v2.b<50); +a b max_c avg_c a b max_c avg_c a b c d +8 33 404 213.6667 8 33 404 213.6667 8 64 248 107 +6 20 315 279.3333 6 20 315 279.3333 6 20 315 279 +8 33 404 213.6667 8 33 404 213.6667 8 80 800 314 +6 20 315 279.3333 6 20 315 279.3333 6 23 303 909 +select * from v1,v2,t2 where +(v1.a=v2.a) and (v1.a=t2.a) and (v2.b<50); +a b max_c avg_c a b max_c avg_c a b c d +8 33 404 213.6667 8 33 404 213.6667 8 64 248 107 +6 20 315 279.3333 6 20 315 279.3333 6 20 315 279 +8 33 404 213.6667 8 33 404 213.6667 8 80 800 314 +6 20 315 279.3333 6 20 315 279.3333 6 23 303 909 +explain select * from v1,v2,t2 where +(v1.a=v2.a) and (v1.a=t2.a) and (v2.b<50); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key1 key1 5 test.t2.a 2 +1 PRIMARY <derived3> ref key0 key0 5 test.t2.a 2 Using where +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,v2,t2 where +(v1.a=v2.a) and (v1.a=t2.a) and (v2.b<50); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a is not null) and (t2.a is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key1"], + "key": "key1", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + }, + "table": { + "table_name": "<derived3>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v2.b < 50)", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and (t1.b < 50))" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,v2,t2 where +((v1.a=v2.a) or (v1.a=t2.a)) and (t2.b<50) and (v1.b=v2.b); +a b max_c avg_c a b max_c avg_c a b c d +6 20 315 279.3333 6 20 315 279.3333 2 3 207 207 +6 20 315 279.3333 6 20 315 279.3333 1 21 909 12 +6 20 315 279.3333 6 20 315 279.3333 7 13 312 406 +6 20 315 279.3333 6 20 315 279.3333 6 20 315 279 +6 20 315 279.3333 6 20 315 279.3333 1 19 203 107 +6 20 315 279.3333 6 20 315 279.3333 3 12 231 190 +6 20 315 279.3333 6 20 315 279.3333 6 23 303 909 +8 33 404 213.6667 8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 8 33 404 213.6667 6 23 303 909 +select * from v1,v2,t2 where +((v1.a=v2.a) or (v1.a=t2.a)) and (t2.b<50) and (v1.b=v2.b); +a b max_c avg_c a b max_c avg_c a b c d +6 20 315 279.3333 6 20 315 279.3333 2 3 207 207 +6 20 315 279.3333 6 20 315 279.3333 1 21 909 12 +6 20 315 279.3333 6 20 315 279.3333 7 13 312 406 +6 20 315 279.3333 6 20 315 279.3333 6 20 315 279 +6 20 315 279.3333 6 20 315 279.3333 1 19 203 107 +6 20 315 279.3333 6 20 315 279.3333 3 12 231 190 +6 20 315 279.3333 6 20 315 279.3333 6 23 303 909 +8 33 404 213.6667 8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 8 33 404 213.6667 6 23 303 909 +explain select * from v1,v2,t2 where +((v1.a=v2.a) or (v1.a=t2.a)) and (t2.b<50) and (v1.b=v2.b); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +1 PRIMARY <derived3> ref key0 key0 5 v1.b 2 Using where +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,v2,t2 where +((v1.a=v2.a) or (v1.a=t2.a)) and (t2.b<50) and (v1.b=v2.b); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.b < 50)" + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(v1.b is not null)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + }, + "table": { + "table_name": "<derived3>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["b"], + "ref": ["v1.b"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v2.a = v1.a) or (v1.a = t2.a))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,v2,t2 where +((v1.a=v2.a) and (v1.a=t2.a)) or ((v2.b>13) and (t2.c<115)); +a b max_c avg_c a b max_c avg_c a b c d +6 20 315 279.3333 6 20 315 279.3333 6 20 315 279 +6 20 315 279.3333 6 20 315 279.3333 6 23 303 909 +8 33 404 213.6667 8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 8 33 404 213.6667 8 80 800 314 +select * from v1,v2,t2 where +((v1.a=v2.a) and (v1.a=t2.a)) or ((v2.b>13) and (t2.c<115)); +a b max_c avg_c a b max_c avg_c a b c d +6 20 315 279.3333 6 20 315 279.3333 6 20 315 279 +6 20 315 279.3333 6 20 315 279.3333 6 23 303 909 +8 33 404 213.6667 8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 8 33 404 213.6667 8 80 800 314 +explain select * from v1,v2,t2 where +((v1.a=v2.a) and (v1.a=t2.a)) or ((v2.b>13) and (t2.c<115)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (incremental, BNL join) +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,v2,t2 where +((v1.a=v2.a) and (v1.a=t2.a)) or ((v2.b>13) and (t2.c<115)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((v1.a = t2.a) or (t2.c < 115))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + }, + "buffer_type": "incremental", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.a = t2.a) and (v2.a = t2.a)) or ((v2.b > 13) and (t2.c < 115)))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + } + } +} +# using several derived tables : pushing in all tables +# conjunctive subformula : pushing into HAVING +# extracted or formula : pushing into WHERE +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,v2,t2 where ((v1.a=v2.a) or (v1.a=t2.a)) and +((v2.b<50) or (v2.b=19)) and (v1.max_c<300); +a b max_c avg_c a b max_c avg_c a b c d +1 19 107 107.0000 6 20 315 279.3333 1 21 909 12 +1 19 107 107.0000 6 20 315 279.3333 1 19 203 107 +1 19 107 107.0000 8 33 404 213.6667 1 21 909 12 +1 19 107 107.0000 8 33 404 213.6667 1 19 203 107 +select * from v1,v2,t2 where ((v1.a=v2.a) or (v1.a=t2.a)) and +((v2.b<50) or (v2.b=19)) and (v1.max_c<300); +a b max_c avg_c a b max_c avg_c a b c d +1 19 107 107.0000 6 20 315 279.3333 1 21 909 12 +1 19 107 107.0000 6 20 315 279.3333 1 19 203 107 +1 19 107 107.0000 8 33 404 213.6667 1 21 909 12 +1 19 107 107.0000 8 33 404 213.6667 1 19 203 107 +explain select * from v1,v2,t2 where ((v1.a=v2.a) or (v1.a=t2.a)) and +((v2.b<50) or (v2.b=19)) and (v1.max_c<300); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (incremental, BNL join) +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,v2,t2 where ((v1.a=v2.a) or (v1.a=t2.a)) and +((v2.b<50) or (v2.b=19)) and (v1.max_c<300); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(v1.max_c < 300)" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c < 300))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v2.b < 50) or (v2.b = 19))" + }, + "buffer_type": "incremental", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v2.a = v1.a) or (v1.a = t2.a)) and ((v2.b < 50) or (v2.b = 19)))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and ((t1.b < 50) or (t1.b = 19)))" + } + } + } + } + } + } + } +} +# using several derived tables : pushing only in one table +# conjunctive subformula : pushing into WHERE +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,v2,t2 where +(v1.a=t2.a) and (v1.a=v1.b) and (v1.a=v2.a) and (v2.max_c<300); +a b max_c avg_c a b max_c avg_c a b c d +select * from v1,v2,t2 where +(v1.a=t2.a) and (v1.a=v1.b) and (v1.a=v2.a) and (v2.max_c<300); +a b max_c avg_c a b max_c avg_c a b c d +explain select * from v1,v2,t2 where +(v1.a=t2.a) and (v1.a=v1.b) and (v1.a=v2.a) and (v2.max_c<300); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key1 key1 10 test.t2.a,test.t2.a 2 +1 PRIMARY <derived3> ref key0 key0 5 test.t2.a 2 Using where +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,v2,t2 where +(v1.a=t2.a) and (v1.a=v1.b) and (v1.a=v2.a) and (v2.max_c<300); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a is not null) and (t2.a is not null) and (t2.a is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key1"], + "key": "key1", + "key_length": "10", + "used_key_parts": ["a", "b"], + "ref": ["test.t2.a", "test.t2.a"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.b = t1.a)" + } + } + } + } + } + }, + "table": { + "table_name": "<derived3>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v2.max_c < 300)", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "((max_c < 707) and (max_c < 300))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + } + } +} +# using several derived tables : pushing only in one table +# extracted and formula : pushing into WHERE +# conjunctive subformula : pushing into WHERE using equalities +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,v2,t2 where (v1.a=1) and (v1.b>10) and (v1.b=v2.b); +a b max_c avg_c a b max_c avg_c a b c d +select * from v1,v2,t2 where (v1.a=1) and (v1.b>10) and (v1.b=v2.b); +a b max_c avg_c a b max_c avg_c a b c d +explain select * from v1,v2,t2 where (v1.a=1) and (v1.b>10) and (v1.b=v2.b); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +1 PRIMARY <derived3> ref key0 key0 5 v1.b 2 +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v1,v2,t2 where (v1.a=1) and (v1.b>10) and (v1.b=v2.b); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a = 1) and (v1.b > 10))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(v1.b is not null)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a = 1) and (t1.b > 10))" + } + } + } + } + } + }, + "table": { + "table_name": "<derived3>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["b"], + "ref": ["v1.b"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and (t1.b > 10))" + } + } + } + } + } + } + } +} +# extracted or formula : pushing into WHERE +# conjunctive subformula : pushing into WHERE using equalities +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_char as v,t2_char as t where +(v.a=t.a) and (t.a='b') and ((v.b='Vika') or (v.b='Ali')); +a b max_c a b c +b Vika 2 b Ivan 1 +b Vika 2 b Ali 6 +b Vika 2 b Hermes 3 +b Vika 2 b Ivan 11 +b Vika 2 b Harry 4 +select * from v_char as v,t2_char as t where +(v.a=t.a) and (t.a='b') and ((v.b='Vika') or (v.b='Ali')); +a b max_c a b c +b Vika 2 b Ivan 1 +b Vika 2 b Ali 6 +b Vika 2 b Hermes 3 +b Vika 2 b Ivan 11 +b Vika 2 b Harry 4 +explain select * from v_char as v,t2_char as t where +(v.a=t.a) and (t.a='b') and ((v.b='Vika') or (v.b='Ali')); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 12 Using where +1 PRIMARY t ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1_char ALL NULL NULL NULL NULL 12 Using where; Using temporary; Using filesort +explain format=json select * from v_char as v,t2_char as t where +(v.a=t.a) and (t.a='b') and ((v.b='Vika') or (v.b='Ali')); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 12, + "filtered": 100, + "attached_condition": "((v.a = 'b') and ((v.b = 'Vika') or (v.b = 'Ali')))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(max_c < 9)", + "filesort": { + "sort_key": "t1_char.b", + "temporary_table": { + "table": { + "table_name": "t1_char", + "access_type": "ALL", + "rows": 12, + "filtered": 100, + "attached_condition": "((t1_char.a = 'b') and ((t1_char.b = 'Vika') or (t1_char.b = 'Ali')))" + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 12, + "filtered": 100, + "attached_condition": "(t.a = 'b')" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL" + } + } +} +# using several derived tables : pushing in all tables +# extracted or formula : pushing into WHERE +# conjunctive subformulas : pushing into HAVING +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,v2,v3,t2 where +((v1.a=v2.a) or (v1.a=t2.a)) and ((v3.b<50) or (v3.b=33)) +and (v1.max_c<500) and (v3.a=t2.a) and (v2.max_c>300); +a b max_c avg_c a b max_c avg_c a b min_c a b c d +6 20 315 279.3333 6 20 315 279.3333 7 11 708 7 13 312 406 +6 20 315 279.3333 6 20 315 279.3333 8 33 114 8 64 248 107 +6 20 315 279.3333 6 20 315 279.3333 6 20 214 6 20 315 279 +6 20 315 279.3333 6 20 315 279.3333 8 33 114 8 80 800 314 +6 20 315 279.3333 6 20 315 279.3333 6 20 214 6 23 303 909 +6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 20 315 279 +6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 23 303 909 +8 33 404 213.6667 6 20 315 279.3333 8 33 114 8 64 248 107 +8 33 404 213.6667 6 20 315 279.3333 8 33 114 8 80 800 314 +8 33 404 213.6667 8 33 404 213.6667 7 11 708 7 13 312 406 +8 33 404 213.6667 8 33 404 213.6667 8 33 114 8 64 248 107 +8 33 404 213.6667 8 33 404 213.6667 6 20 214 6 20 315 279 +8 33 404 213.6667 8 33 404 213.6667 8 33 114 8 80 800 314 +8 33 404 213.6667 8 33 404 213.6667 6 20 214 6 23 303 909 +select * from v1,v2,v3,t2 where +((v1.a=v2.a) or (v1.a=t2.a)) and ((v3.b<50) or (v3.b=33)) +and (v1.max_c<500) and (v3.a=t2.a) and (v2.max_c>300); +a b max_c avg_c a b max_c avg_c a b min_c a b c d +6 20 315 279.3333 6 20 315 279.3333 7 11 708 7 13 312 406 +6 20 315 279.3333 6 20 315 279.3333 8 33 114 8 64 248 107 +6 20 315 279.3333 6 20 315 279.3333 6 20 214 6 20 315 279 +6 20 315 279.3333 6 20 315 279.3333 8 33 114 8 80 800 314 +6 20 315 279.3333 6 20 315 279.3333 6 20 214 6 23 303 909 +6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 20 315 279 +6 20 315 279.3333 8 33 404 213.6667 6 20 214 6 23 303 909 +8 33 404 213.6667 6 20 315 279.3333 8 33 114 8 64 248 107 +8 33 404 213.6667 6 20 315 279.3333 8 33 114 8 80 800 314 +8 33 404 213.6667 8 33 404 213.6667 7 11 708 7 13 312 406 +8 33 404 213.6667 8 33 404 213.6667 8 33 114 8 64 248 107 +8 33 404 213.6667 8 33 404 213.6667 6 20 214 6 20 315 279 +8 33 404 213.6667 8 33 404 213.6667 8 33 114 8 80 800 314 +8 33 404 213.6667 8 33 404 213.6667 6 20 214 6 23 303 909 +explain select * from v1,v2,v3,t2 where +((v1.a=v2.a) or (v1.a=t2.a)) and ((v3.b<50) or (v3.b=33)) +and (v1.max_c<500) and (v3.a=t2.a) and (v2.max_c>300); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived4> ref key0 key0 5 test.t2.a 2 Using where +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (incremental, BNL join) +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +explain format=json select * from v1,v2,v3,t2 where +((v1.a=v2.a) or (v1.a=t2.a)) and ((v3.b<50) or (v3.b=33)) +and (v1.max_c<500) and (v3.a=t2.a) and (v2.max_c>300); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.a is not null)" + }, + "table": { + "table_name": "<derived4>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v3.b < 50) or (v3.b = 33))", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "(min_c > 109)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 10) and ((t1.b < 50) or (t1.b = 33)))" + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(v2.max_c > 300)" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "((max_c < 707) and (max_c > 300))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(v1.max_c < 500)" + }, + "buffer_type": "incremental", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((v1.a = v2.a) or (v1.a = t2.a))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c < 500))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +# using several derived tables : pushing in all tables +# conjunctive subformulas : pushing into HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +(select a, b, min(c) as min_c from t1 +where t1.a>5 group by a,b having min_c < 707) v2, +t2 where (v1.a=v2.a) and (v1.b=t2.b) and (v1.max_c>130) and (v2.min_c<130); +a b max_c avg_c a b min_c a b c d +select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +(select a, b, min(c) as min_c from t1 +where t1.a>5 group by a,b having min_c < 707) v2, +t2 where (v1.a=v2.a) and (v1.b=t2.b) and (v1.max_c>130) and (v2.min_c<130); +a b max_c avg_c a b min_c a b c d +explain select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +(select a, b, min(c) as min_c from t1 +where t1.a>5 group by a,b having min_c < 707) v2, +t2 where (v1.a=v2.a) and (v1.b=t2.b) and (v1.max_c>130) and (v2.min_c<130); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key1 key1 5 test.t2.b 2 Using where +1 PRIMARY <derived3> ref key0 key0 5 v1.a 2 Using where +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +(select a, b, min(c) as min_c from t1 +where t1.a>5 group by a,b having min_c < 707) v2, +t2 where (v1.a=v2.a) and (v1.b=t2.b) and (v1.max_c>130) and (v2.min_c<130); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.b is not null)" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key1"], + "key": "key1", + "key_length": "5", + "used_key_parts": ["b"], + "ref": ["test.t2.b"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v1.max_c > 130) and (v1.a is not null))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c > 130))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + }, + "table": { + "table_name": "<derived3>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["v1.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v2.min_c < 130)", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "((min_c < 707) and (min_c < 130))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + } + } +} +# using several derived tables : pushing in all tables +# extracted or formulas : pushing into HAVING +# conjunctive subformula : pushing into HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +(select a, b, min(c) as min_c from t1 +where t1.a>5 group by a,b having min_c < 707) v2, +(select a, b, avg(c) as avg_c from t1 +where t1.a<8 group by a,b) v3, +t2 where (v1.a=v2.a) and (v1.b=v3.b) and ((v3.avg_c>170) or (v3.a<5)) +and ((v1.avg_c<400) or (v1.a>1)) and (v2.min_c<200); +a b max_c avg_c a b min_c a b avg_c a b c d +8 33 404 213.6667 8 33 114 1 33 497.5000 2 3 207 207 +8 33 404 213.6667 8 33 114 1 33 497.5000 1 21 909 12 +8 33 404 213.6667 8 33 114 1 33 497.5000 7 13 312 406 +8 33 404 213.6667 8 33 114 1 33 497.5000 8 64 248 107 +8 33 404 213.6667 8 33 114 1 33 497.5000 6 20 315 279 +8 33 404 213.6667 8 33 114 1 33 497.5000 1 19 203 107 +8 33 404 213.6667 8 33 114 1 33 497.5000 8 80 800 314 +8 33 404 213.6667 8 33 114 1 33 497.5000 3 12 231 190 +8 33 404 213.6667 8 33 114 1 33 497.5000 6 23 303 909 +select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +(select a, b, min(c) as min_c from t1 +where t1.a>5 group by a,b having min_c < 707) v2, +(select a, b, avg(c) as avg_c from t1 +where t1.a<8 group by a,b) v3, +t2 where (v1.a=v2.a) and (v1.b=v3.b) and ((v3.avg_c>170) or (v3.a<5)) +and ((v1.avg_c<400) or (v1.a>1)) and (v2.min_c<200); +a b max_c avg_c a b min_c a b avg_c a b c d +8 33 404 213.6667 8 33 114 1 33 497.5000 2 3 207 207 +8 33 404 213.6667 8 33 114 1 33 497.5000 1 21 909 12 +8 33 404 213.6667 8 33 114 1 33 497.5000 7 13 312 406 +8 33 404 213.6667 8 33 114 1 33 497.5000 8 64 248 107 +8 33 404 213.6667 8 33 114 1 33 497.5000 6 20 315 279 +8 33 404 213.6667 8 33 114 1 33 497.5000 1 19 203 107 +8 33 404 213.6667 8 33 114 1 33 497.5000 8 80 800 314 +8 33 404 213.6667 8 33 114 1 33 497.5000 3 12 231 190 +8 33 404 213.6667 8 33 114 1 33 497.5000 6 23 303 909 +explain select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +(select a, b, min(c) as min_c from t1 +where t1.a>5 group by a,b having min_c < 707) v2, +(select a, b, avg(c) as avg_c from t1 +where t1.a<8 group by a,b) v3, +t2 where (v1.a=v2.a) and (v1.b=v3.b) and ((v3.avg_c>170) or (v3.a<5)) +and ((v1.avg_c<400) or (v1.a>1)) and (v2.min_c<200); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +1 PRIMARY <derived3> ref key0 key0 5 v1.a 2 Using where +1 PRIMARY <derived4> ref key0 key0 5 v1.b 2 Using where +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +(select a, b, min(c) as min_c from t1 +where t1.a>5 group by a,b having min_c < 707) v2, +(select a, b, avg(c) as avg_c from t1 +where t1.a<8 group by a,b) v3, +t2 where (v1.a=v2.a) and (v1.b=v3.b) and ((v3.avg_c>170) or (v3.a<5)) +and ((v1.avg_c<400) or (v1.a>1)) and (v2.min_c<200); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.avg_c < 400) or (v1.a > 1))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.avg_c < 400) or (v1.a > 1)) and (v1.a is not null) and (v1.b is not null))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and ((avg_c < 400) or (t1.a > 1)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + }, + "table": { + "table_name": "<derived3>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["v1.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v2.min_c < 200)", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "((min_c < 707) and (min_c < 200))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + }, + "table": { + "table_name": "<derived4>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["b"], + "ref": ["v1.b"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v3.avg_c > 170) or (v3.a < 5))", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "((avg_c > 170) or (t1.a < 5))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a < 8)" + } + } + } + } + } + } + } +} +# extracted or formula : pushing into HAVING +# conjunctive subformula : pushing into WHERE +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where ((v1.a=1) or (v1.max_c<300)) and (v1.b>25); +a b max_c avg_c a b c d +5 27 132 132.0000 2 3 207 207 +5 27 132 132.0000 1 21 909 12 +5 27 132 132.0000 7 13 312 406 +5 27 132 132.0000 8 64 248 107 +5 27 132 132.0000 6 20 315 279 +5 27 132 132.0000 1 19 203 107 +5 27 132 132.0000 8 80 800 314 +5 27 132 132.0000 3 12 231 190 +5 27 132 132.0000 6 23 303 909 +select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where ((v1.a=1) or (v1.max_c<300)) and (v1.b>25); +a b max_c avg_c a b c d +5 27 132 132.0000 2 3 207 207 +5 27 132 132.0000 1 21 909 12 +5 27 132 132.0000 7 13 312 406 +5 27 132 132.0000 8 64 248 107 +5 27 132 132.0000 6 20 315 279 +5 27 132 132.0000 1 19 203 107 +5 27 132 132.0000 8 80 800 314 +5 27 132 132.0000 3 12 231 190 +5 27 132 132.0000 6 23 303 909 +explain select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where ((v1.a=1) or (v1.max_c<300)) and (v1.b>25); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +group by a,b having max_c < 707) v1, +t2 where ((v1.a=1) or (v1.max_c<300)) and (v1.b>25); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(((v1.a = 1) or (v1.max_c < 300)) and (v1.b > 25))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((v1.a = 1) or (v1.max_c < 300))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and ((t1.a = 1) or (max_c < 300)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.b > 25)" + } + } + } + } + } + } + } +} +# extracted and formula : pushing into WHERE +# conjunctive subformula : pushing into HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.b<30); +a b max_c avg_c a b c d +6 20 315 279.3333 6 20 315 279 +6 20 315 279.3333 6 23 303 909 +select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.b<30); +a b max_c avg_c a b c d +6 20 315 279.3333 6 20 315 279 +6 20 315 279.3333 6 23 303 909 +explain select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.b<30); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from +(select a, b, max(c) as max_c, avg(c) as avg_c from t1 +where t1.a>5 group by a,b having max_c < 707) v1, +t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.b<30); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.a is not null)" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v1.max_c > 300) and (v1.b < 30))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 707) and (max_c > 300))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and (t1.b < 30))" + } + } + } + } + } + } + } +} +# using query with union +# conjunctive subformula : pushing into WHERE +# conjunctive subformulas : pushing into HAVING and WHERE +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (t2.c>800) +union +select * from v1,t2 where (v1.max_c>100) and (v1.a>7) and (t2.d>800); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +8 33 404 213.6667 6 23 303 909 +select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (t2.c>800) +union +select * from v1,t2 where (v1.max_c>100) and (v1.a>7) and (t2.d>800); +a b max_c avg_c a b c d +1 21 500 234.6000 1 21 909 12 +8 33 404 213.6667 6 23 303 909 +explain select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (t2.c>800) +union +select * from v1,t2 where (v1.max_c>100) and (v1.a>7) and (t2.d>800); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived3> ref key0 key0 5 test.t2.b 2 Using where +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 UNION t2 ALL NULL NULL NULL NULL 9 Using where +2 UNION <derived4> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +explain format=json select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (t2.c>800) +union +select * from v1,t2 where (v1.max_c>100) and (v1.a>7) and (t2.d>800); +EXPLAIN +{ + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.c > 800) and (t2.b is not null))" + }, + "table": { + "table_name": "<derived3>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["b"], + "ref": ["test.t2.b"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v1.a < 5)", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a < 5)" + } + } + } + } + } + } + } + }, + { + "query_block": { + "select_id": 2, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.d > 800)" + }, + "block-nl-join": { + "table": { + "table_name": "<derived4>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.max_c > 100) and (v1.a > 7))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "((max_c < 707) and (max_c > 100))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 7)" + } + } + } + } + } + } + } + } + ] + } + } +} +# using query with union +# extracted and formula : pushing into WHERE +# extracted or formula : pushing into HAVING +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (v1.b=19) +union +select * from v1,t2 where ((v1.max_c>400) or (v1.avg_c>270)) and (v1.a<t2.a); +a b max_c avg_c a b c d +1 19 107 107.0000 1 19 203 107 +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +6 20 315 279.3333 7 13 312 406 +6 20 315 279.3333 8 64 248 107 +6 20 315 279.3333 8 80 800 314 +select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (v1.b=19) +union +select * from v1,t2 where ((v1.max_c>400) or (v1.avg_c>270)) and (v1.a<t2.a); +a b max_c avg_c a b c d +1 19 107 107.0000 1 19 203 107 +1 21 500 234.6000 2 3 207 207 +1 21 500 234.6000 7 13 312 406 +1 21 500 234.6000 8 64 248 107 +1 21 500 234.6000 6 20 315 279 +1 21 500 234.6000 8 80 800 314 +1 21 500 234.6000 3 12 231 190 +1 21 500 234.6000 6 23 303 909 +6 20 315 279.3333 7 13 312 406 +6 20 315 279.3333 8 64 248 107 +6 20 315 279.3333 8 80 800 314 +explain select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (v1.b=19) +union +select * from v1,t2 where ((v1.max_c>400) or (v1.avg_c>270)) and (v1.a<t2.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 UNION t2 ALL NULL NULL NULL NULL 9 +2 UNION <derived4> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +explain format=json select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (v1.b=19) +union +select * from v1,t2 where ((v1.max_c>400) or (v1.avg_c>270)) and (v1.a<t2.a); +EXPLAIN +{ + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.b = 19)" + }, + "block-nl-join": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.b = 19) and (v1.a < 5))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.b = 19) and (t1.a < 5))" + } + } + } + } + } + } + } + }, + { + "query_block": { + "select_id": 2, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived4>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.max_c > 400) or (v1.avg_c > 270))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.max_c > 400) or (v1.avg_c > 270)) and (v1.a < t2.a))", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "((max_c < 707) and ((max_c > 400) or (avg_c > 270)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } + } + ] + } + } +} +# using query with union +# extracted or formula : pushing into HAVING +# extracted or formula : pushing into WHERE +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +((t2.a=v1.a) or (v1.b=t2.b)) and ((v1.a=1) or (v1.a=6)) +union +select * from v1,t2 where ((v1.a>3) and (v1.b>27)) or (v1.max_c>550); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +1 21 500 234.6000 1 21 909 12 +1 21 500 234.6000 1 19 203 107 +6 20 315 279.3333 6 20 315 279 +6 20 315 279.3333 6 23 303 909 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 8 80 800 314 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +select * from v1,t2 where +((t2.a=v1.a) or (v1.b=t2.b)) and ((v1.a=1) or (v1.a=6)) +union +select * from v1,t2 where ((v1.a>3) and (v1.b>27)) or (v1.max_c>550); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +1 21 500 234.6000 1 21 909 12 +1 21 500 234.6000 1 19 203 107 +6 20 315 279.3333 6 20 315 279 +6 20 315 279.3333 6 23 303 909 +8 33 404 213.6667 2 3 207 207 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 7 13 312 406 +8 33 404 213.6667 8 64 248 107 +8 33 404 213.6667 6 20 315 279 +8 33 404 213.6667 1 19 203 107 +8 33 404 213.6667 8 80 800 314 +8 33 404 213.6667 3 12 231 190 +8 33 404 213.6667 6 23 303 909 +explain select * from v1,t2 where +((t2.a=v1.a) or (v1.b=t2.b)) and ((v1.a=1) or (v1.a=6)) +union +select * from v1,t2 where ((v1.a>3) and (v1.b>27)) or (v1.max_c>550); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 UNION t2 ALL NULL NULL NULL NULL 9 +2 UNION <derived4> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +explain format=json select * from v1,t2 where +((t2.a=v1.a) or (v1.b=t2.b)) and ((v1.a=1) or (v1.a=6)) +union +select * from v1,t2 where ((v1.a>3) and (v1.b>27)) or (v1.max_c>550); +EXPLAIN +{ + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a = 1) or (v1.a = 6))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.a = t2.a) or (v1.b = t2.b)) and ((v1.a = 1) or (v1.a = 6)))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a = 1) or (t1.a = 6))" + } + } + } + } + } + } + } + }, + { + "query_block": { + "select_id": 2, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived4>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(((v1.a > 3) and (v1.b > 27)) or (v1.max_c > 550))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "(((v1.a > 3) and (v1.b > 27)) or (v1.max_c > 550))", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "((max_c < 707) and (((t1.a > 3) and (t1.b > 27)) or (max_c > 550)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } + } + ] + } + } +} +# using query with union +# extracted or formula : pushing into HAVING +# conjunctive subformulas : pushing into WHERE +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v1,t2 where +((v1.a=1) and (v1.a=t2.a)) and ((v1.max_c<500) or (v1.avg_c>500)) +union +select * from v2,t2 where +((v2.a<t2.b) or (v2.max_c>200)) and (v2.b>10) and (t2.a<2) +union +select * from v2,t2 where +(v2.max_c=t2.c) and (v2.b<10); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +6 20 315 279.3333 1 21 909 12 +6 20 315 279.3333 1 19 203 107 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 1 19 203 107 +select * from v1,t2 where +((v1.a=1) and (v1.a=t2.a)) and ((v1.max_c<500) or (v1.avg_c>500)) +union +select * from v2,t2 where +((v2.a<t2.b) or (v2.max_c>200)) and (v2.b>10) and (t2.a<2) +union +select * from v2,t2 where +(v2.max_c=t2.c) and (v2.b<10); +a b max_c avg_c a b c d +1 19 107 107.0000 1 21 909 12 +1 19 107 107.0000 1 19 203 107 +6 20 315 279.3333 1 21 909 12 +6 20 315 279.3333 1 19 203 107 +8 33 404 213.6667 1 21 909 12 +8 33 404 213.6667 1 19 203 107 +explain select * from v1,t2 where +((v1.a=1) and (v1.a=t2.a)) and ((v1.max_c<500) or (v1.avg_c>500)) +union +select * from v2,t2 where +((v2.a<t2.b) or (v2.max_c>200)) and (v2.b>10) and (t2.a<2) +union +select * from v2,t2 where +(v2.max_c=t2.c) and (v2.b<10); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived4> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 UNION t2 ALL NULL NULL NULL NULL 9 Using where +2 UNION <derived5> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +5 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 UNION t2 ALL NULL NULL NULL NULL 9 Using where +3 UNION <derived6> ref key0 key0 5 test.t2.c 2 Using where +6 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +NULL UNION RESULT <union1,2,3> ALL NULL NULL NULL NULL NULL +explain format=json select * from v1,t2 where +((v1.a=1) and (v1.a=t2.a)) and ((v1.max_c<500) or (v1.avg_c>500)) +union +select * from v2,t2 where +((v2.a<t2.b) or (v2.max_c>200)) and (v2.b>10) and (t2.a<2) +union +select * from v2,t2 where +(v2.max_c=t2.c) and (v2.b<10); +EXPLAIN +{ + "query_block": { + "union_result": { + "table_name": "<union1,2,3>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.a = 1)" + }, + "block-nl-join": { + "table": { + "table_name": "<derived4>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a = 1) and ((v1.max_c < 500) or (v1.avg_c > 500)))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((v1.max_c < 500) or (v1.avg_c > 500))", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "((max_c < 707) and ((max_c < 500) or (avg_c > 500)))", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a = 1)" + } + } + } + } + } + } + } + }, + { + "query_block": { + "select_id": 2, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.a < 2)" + }, + "block-nl-join": { + "table": { + "table_name": "<derived5>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(v2.b > 10)" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((v2.a < t2.b) or (v2.max_c > 200))", + "materialized": { + "query_block": { + "select_id": 5, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and (t1.b > 10))" + } + } + } + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.c is not null)" + }, + "table": { + "table_name": "<derived6>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["max_c"], + "ref": ["test.t2.c"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v2.b < 10)", + "materialized": { + "query_block": { + "select_id": 6, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and (t1.b < 10))" + } + } + } + } + } + } + } + } + ] + } + } +} +# using derived table with union +# conjunctive subformulas : pushing into WHERE and HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_union,t2 where (v_union.a<3) and (v_union.c>100); +a b c a b c d +1 19 107 2 3 207 207 +1 19 107 1 21 909 12 +1 19 107 7 13 312 406 +1 19 107 8 64 248 107 +1 19 107 6 20 315 279 +1 19 107 1 19 203 107 +1 19 107 8 80 800 314 +1 19 107 3 12 231 190 +1 19 107 6 23 303 909 +select * from v_union,t2 where (v_union.a<3) and (v_union.c>100); +a b c a b c d +1 19 107 2 3 207 207 +1 19 107 1 21 909 12 +1 19 107 7 13 312 406 +1 19 107 8 64 248 107 +1 19 107 6 20 315 279 +1 19 107 1 19 203 107 +1 19 107 8 80 800 314 +1 19 107 3 12 231 190 +1 19 107 6 23 303 909 +explain select * from v_union,t2 where (v_union.a<3) and (v_union.c>100); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 40 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 UNION t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +explain format=json select * from v_union,t2 where (v_union.a<3) and (v_union.c>100); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 40, + "filtered": 100, + "attached_condition": "((v_union.a < 3) and (v_union.c > 100))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "union_result": { + "table_name": "<union2,3>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "having_condition": "((c > 109) and (c > 100))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 10) and (t1.a < 3))" + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "having_condition": "((c < 300) and (c > 100))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.b > 10) and (t1.a < 3))" + } + } + } + } + } + ] + } + } + } + } + } +} +# using derived table with union +# conjunctive subformula : pushing into WHERE +# extracted or formula : pushing into HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_union,t2 where +((v_union.a<2) or (v_union.c>800)) and (v_union.b>12); +a b c a b c d +1 19 107 2 3 207 207 +1 19 107 1 21 909 12 +1 19 107 7 13 312 406 +1 19 107 8 64 248 107 +1 19 107 6 20 315 279 +1 19 107 1 19 203 107 +1 19 107 8 80 800 314 +1 19 107 3 12 231 190 +1 19 107 6 23 303 909 +select * from v_union,t2 where +((v_union.a<2) or (v_union.c>800)) and (v_union.b>12); +a b c a b c d +1 19 107 2 3 207 207 +1 19 107 1 21 909 12 +1 19 107 7 13 312 406 +1 19 107 8 64 248 107 +1 19 107 6 20 315 279 +1 19 107 1 19 203 107 +1 19 107 8 80 800 314 +1 19 107 3 12 231 190 +1 19 107 6 23 303 909 +explain select * from v_union,t2 where +((v_union.a<2) or (v_union.c>800)) and (v_union.b>12); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 40 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 UNION t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +explain format=json select * from v_union,t2 where +((v_union.a<2) or (v_union.c>800)) and (v_union.b>12); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 40, + "filtered": 100, + "attached_condition": "(((v_union.a < 2) or (v_union.c > 800)) and (v_union.b > 12))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((v_union.a < 2) or (v_union.c > 800))", + "materialized": { + "query_block": { + "union_result": { + "table_name": "<union2,3>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "having_condition": "((c > 109) and ((t1.a < 2) or (c > 800)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 10) and (t1.b > 12))" + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "having_condition": "((c < 300) and ((t1.a < 2) or (c > 800)))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.b > 10) and (t1.b > 12))" + } + } + } + } + } + ] + } + } + } + } + } +} +# using derived table with union +# conjunctive subformula : pushing into HAVING +# conjunctive subformula : pushing into WHERE +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_union,t2 where +(v_union.a=1) and (v_union.a=t2.a) and (v_union.c<200); +a b c a b c d +1 19 107 1 21 909 12 +1 19 107 1 19 203 107 +select * from v_union,t2 where +(v_union.a=1) and (v_union.a=t2.a) and (v_union.c<200); +a b c a b c d +1 19 107 1 21 909 12 +1 19 107 1 19 203 107 +explain select * from v_union,t2 where +(v_union.a=1) and (v_union.a=t2.a) and (v_union.c<200); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 40 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 UNION t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +explain format=json select * from v_union,t2 where +(v_union.a=1) and (v_union.a=t2.a) and (v_union.c<200); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.a = 1)" + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 40, + "filtered": 100, + "attached_condition": "((v_union.a = 1) and (v_union.c < 200))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "union_result": { + "table_name": "<union2,3>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "having_condition": "((c > 109) and (c < 200))", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a = 1)" + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "having_condition": "((c < 300) and (c < 200))", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a = 1) and (t1.b > 10))" + } + } + } + } + } + ] + } + } + } + } + } +} +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_char as v,t2_char as t where +(v.a=t.a) and (v.b='Vika') and (v.max_c>2); +a b max_c a b c +c Vika 7 c Vinny 3 +c Vika 7 c Inga 9 +c Vika 7 c Ivan 2 +c Vika 7 c Inga 2 +select * from v_char as v,t2_char as t where +(v.a=t.a) and (v.b='Vika') and (v.max_c>2); +a b max_c a b c +c Vika 7 c Vinny 3 +c Vika 7 c Inga 9 +c Vika 7 c Ivan 2 +c Vika 7 c Inga 2 +explain select * from v_char as v,t2_char as t where +(v.a=t.a) and (v.b='Vika') and (v.max_c>2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t ALL NULL NULL NULL NULL 12 Using where +1 PRIMARY <derived2> ref key0 key0 2 test.t.a 2 Using where +2 DERIVED t1_char ALL NULL NULL NULL NULL 12 Using where; Using temporary; Using filesort +explain format=json select * from v_char as v,t2_char as t where +(v.a=t.a) and (v.b='Vika') and (v.max_c>2); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t", + "access_type": "ALL", + "rows": 12, + "filtered": 100, + "attached_condition": "(t.a is not null)" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "2", + "used_key_parts": ["a"], + "ref": ["test.t.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "((v.b = 'Vika') and (v.max_c > 2))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "((max_c < 9) and (max_c > 2))", + "filesort": { + "sort_key": "t1_char.a", + "temporary_table": { + "table": { + "table_name": "t1_char", + "access_type": "ALL", + "rows": 12, + "filtered": 100, + "attached_condition": "(t1_char.b = 'Vika')" + } + } + } + } + } + } + } +} +# using derived table with union +# using several derived tables : pushing in all tables +# conjunctive subformula : pushing into WHERE using equalities +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v_union,v1,t2 where +(v_union.a=v1.a) and (v1.a=t2.a) and (t2.a=1) +and ((v_union.c>800) or (v1.max_c>200)); +a b c a b max_c avg_c a b c d +1 19 107 1 21 500 234.6000 1 21 909 12 +1 19 107 1 21 500 234.6000 1 19 203 107 +select * from v_union,v1,t2 where +(v_union.a=v1.a) and (v1.a=t2.a) and (t2.a=1) +and ((v_union.c>800) or (v1.max_c>200)); +a b c a b max_c avg_c a b c d +1 19 107 1 21 500 234.6000 1 21 909 12 +1 19 107 1 21 500 234.6000 1 19 203 107 +explain select * from v_union,v1,t2 where +(v_union.a=v1.a) and (v1.a=t2.a) and (t2.a=1) +and ((v_union.c>800) or (v1.max_c>200)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived4> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 40 Using where; Using join buffer (incremental, BNL join) +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 UNION t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +explain format=json select * from v_union,v1,t2 where +(v_union.a=v1.a) and (v1.a=t2.a) and (t2.a=1) +and ((v_union.c>800) or (v1.max_c>200)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(t2.a = 1)" + }, + "block-nl-join": { + "table": { + "table_name": "<derived4>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(v1.a = 1)" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a = 1)" + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 40, + "filtered": 100, + "attached_condition": "(v_union.a = 1)" + }, + "buffer_type": "incremental", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((v_union.c > 800) or (v1.max_c > 200))", + "materialized": { + "query_block": { + "union_result": { + "table_name": "<union2,3>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "having_condition": "(c > 109)", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a = 1)" + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "having_condition": "(c < 300)", + "filesort": { + "sort_key": "t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a = 1) and (t1.b > 10))" + } + } + } + } + } + ] + } + } + } + } + } +} +# using derived table with union +# extracted or formula : pushing into WHERE +# conjunctive subformula : pushing into HAVING +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v2_union as v,t2 where +((v.a=6) or (v.a=8)) and (v.c>200) and (v.a=t2.a); +a b c a b c d +8 33 404.0000 8 64 248 107 +6 20 312.0000 6 20 315 279 +6 20 214.0000 6 20 315 279 +8 33 404.0000 8 80 800 314 +6 20 312.0000 6 23 303 909 +6 20 214.0000 6 23 303 909 +select * from v2_union as v,t2 where +((v.a=6) or (v.a=8)) and (v.c>200) and (v.a=t2.a); +a b c a b c d +8 33 404.0000 8 64 248 107 +6 20 312.0000 6 20 315 279 +6 20 214.0000 6 20 315 279 +8 33 404.0000 8 80 800 314 +6 20 312.0000 6 23 303 909 +6 20 214.0000 6 23 303 909 +explain select * from v2_union as v,t2 where +((v.a=6) or (v.a=8)) and (v.c>200) and (v.a=t2.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 6 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 UNION t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +4 UNION t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +NULL UNION RESULT <union2,3,4> ALL NULL NULL NULL NULL NULL +explain format=json select * from v2_union as v,t2 where +((v.a=6) or (v.a=8)) and (v.c>200) and (v.a=t2.a); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "(((t2.a = 6) or (t2.a = 8)) and (t2.a is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 6, + "filtered": 100, + "attached_condition": "(v.c > 200)", + "materialized": { + "query_block": { + "union_result": { + "table_name": "<union2,3,4>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "having_condition": "((c > 109) and (c > 200))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 10) and ((t1.a = 6) or (t1.a = 8)))" + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "having_condition": "((c < 300) and (c > 200))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.b > 10) and ((t1.a = 6) or (t1.a = 8)))" + } + } + } + } + }, + { + "query_block": { + "select_id": 4, + "having_condition": "((c < 707) and (c > 200))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.c > 300) and ((t1.a = 6) or (t1.a = 8)))" + } + } + } + } + } + ] + } + } + } + } + } +} +# using embedded derived table : pushing the same conditions +# using several derived tables : pushing in all tables +# conjunctive subformula : pushing into WHERE +# extracted and formula : pushing into WHERE +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v4,v1 where +(v4.a<13) and (v1.a>5) and (v1.b>12); +a b min_c a b max_c avg_c +1 19 107 6 20 315 279.3333 +1 21 500 6 20 315 279.3333 +5 16 207 6 20 315 279.3333 +5 27 132 6 20 315 279.3333 +6 20 315 6 20 315 279.3333 +8 33 404 6 20 315 279.3333 +1 19 107 8 33 404 213.6667 +1 21 500 8 33 404 213.6667 +5 16 207 8 33 404 213.6667 +5 27 132 8 33 404 213.6667 +6 20 315 8 33 404 213.6667 +8 33 404 8 33 404 213.6667 +select * from v4,v1 where +(v4.a<13) and (v1.a>5) and (v1.b>12); +a b min_c a b max_c avg_c +1 19 107 6 20 315 279.3333 +1 21 500 6 20 315 279.3333 +5 16 207 6 20 315 279.3333 +5 27 132 6 20 315 279.3333 +6 20 315 6 20 315 279.3333 +8 33 404 6 20 315 279.3333 +1 19 107 8 33 404 213.6667 +1 21 500 8 33 404 213.6667 +5 16 207 8 33 404 213.6667 +5 27 132 8 33 404 213.6667 +6 20 315 8 33 404 213.6667 +8 33 404 8 33 404 213.6667 +explain select * from v4,v1 where +(v4.a<13) and (v1.a>5) and (v1.b>12); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where +1 PRIMARY <derived4> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v4,v1 where +(v4.a<13) and (v1.a>5) and (v1.b>12); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(v4.a < 13)", + "materialized": { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "v1.a, v1.b", + "temporary_table": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a < 15) and (v1.a < 13))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 15) and (t1.a < 13))" + } + } + } + } + } + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "<derived4>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a > 5) and (v1.b > 12))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and (t1.b > 12))" + } + } + } + } + } + } + } +} +# using embedded view : nothing to push +# using several derived tables : pushing only in one table +# conjunctive subformula : pushing into WHERE +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v4,v1,t2 where +(v4.a=t2.a) and (v4.a=v1.a) and (v1.b>30); +a b min_c a b max_c avg_c a b c d +8 33 404 8 33 404 213.6667 8 64 248 107 +8 33 404 8 33 404 213.6667 8 80 800 314 +select * from v4,v1,t2 where +(v4.a=t2.a) and (v4.a=v1.a) and (v1.b>30); +a b min_c a b max_c avg_c a b c d +8 33 404 8 33 404 213.6667 8 64 248 107 +8 33 404 8 33 404 213.6667 8 80 800 314 +explain select * from v4,v1,t2 where +(v4.a=t2.a) and (v4.a=v1.a) and (v1.b>30); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key1 key1 5 test.t2.a 2 +1 PRIMARY <derived4> ref key0 key0 5 test.t2.a 2 Using where +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v4,v1,t2 where +(v4.a=t2.a) and (v4.a=v1.a) and (v1.b>30); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a is not null) and (t2.a is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key1"], + "key": "key1", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "v1.a, v1.b", + "temporary_table": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(v1.a < 15)", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a < 15)" + } + } + } + } + } + } + } + } + } + } + }, + "table": { + "table_name": "<derived4>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v1.b > 30)", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.b > 30)" + } + } + } + } + } + } + } +} +# using embedded view : pushing different conditions +# using several derived tables : pushing in all tables +# conjunctive subformula : pushing into WHERE using equalities +# extracted and formula : pushing into WHERE using equalities +# conjunctive subformula : pushing into HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v4,v1,t2 where +(v4.a=t2.a) and (v4.a>1) and (v4.a=v1.a) and (v4.min_c>100) and (v1.b<30); +a b min_c a b max_c avg_c a b c d +6 20 315 6 20 315 279.3333 6 20 315 279 +6 20 315 6 20 315 279.3333 6 23 303 909 +select * from v4,v1,t2 where +(v4.a=t2.a) and (v4.a>1) and (v4.a=v1.a) and (v4.min_c>100) and (v1.b<30); +a b min_c a b max_c avg_c a b c d +6 20 315 6 20 315 279.3333 6 20 315 279 +6 20 315 6 20 315 279.3333 6 23 303 909 +explain select * from v4,v1,t2 where +(v4.a=t2.a) and (v4.a>1) and (v4.a=v1.a) and (v4.min_c>100) and (v1.b<30); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key1 key1 5 test.t2.a 2 Using where +1 PRIMARY <derived4> ref key0 key0 5 test.t2.a 2 Using where +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v4,v1,t2 where +(v4.a=t2.a) and (v4.a>1) and (v4.a=v1.a) and (v4.min_c>100) and (v1.b<30); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.a > 1) and (t2.a is not null) and (t2.a is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key1"], + "key": "key1", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v4.min_c > 100)", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(min_c > 100)", + "filesort": { + "sort_key": "v1.a, v1.b", + "temporary_table": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a < 15) and (v1.a > 1))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 15) and (t1.a > 1))" + } + } + } + } + } + } + } + } + } + } + }, + "table": { + "table_name": "<derived4>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["test.t2.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v1.b < 30)", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 1) and (t1.b < 30))" + } + } + } + } + } + } + } +} +# using embedded view : pushing different conditions +# using several derived tables : pushing in all tables +# extracted or formula : pushing into WHERE +# conjunctive subformula : pushing into HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v4,v1,t2 where +(((v4.b>10) and (v4.a>1)) or (v4.b<20)) and (v1.max_c>200) and (v1.a=v4.a); +a b min_c a b max_c avg_c a b c d +1 19 107 1 21 500 234.6000 2 3 207 207 +1 19 107 1 21 500 234.6000 1 21 909 12 +1 19 107 1 21 500 234.6000 7 13 312 406 +1 19 107 1 21 500 234.6000 8 64 248 107 +1 19 107 1 21 500 234.6000 6 20 315 279 +1 19 107 1 21 500 234.6000 1 19 203 107 +1 19 107 1 21 500 234.6000 8 80 800 314 +1 19 107 1 21 500 234.6000 3 12 231 190 +1 19 107 1 21 500 234.6000 6 23 303 909 +5 16 207 5 16 207 207.0000 2 3 207 207 +5 16 207 5 16 207 207.0000 1 21 909 12 +5 16 207 5 16 207 207.0000 7 13 312 406 +5 16 207 5 16 207 207.0000 8 64 248 107 +5 16 207 5 16 207 207.0000 6 20 315 279 +5 16 207 5 16 207 207.0000 1 19 203 107 +5 16 207 5 16 207 207.0000 8 80 800 314 +5 16 207 5 16 207 207.0000 3 12 231 190 +5 16 207 5 16 207 207.0000 6 23 303 909 +5 27 132 5 16 207 207.0000 2 3 207 207 +5 27 132 5 16 207 207.0000 1 21 909 12 +5 27 132 5 16 207 207.0000 7 13 312 406 +5 27 132 5 16 207 207.0000 8 64 248 107 +5 27 132 5 16 207 207.0000 6 20 315 279 +5 27 132 5 16 207 207.0000 1 19 203 107 +5 27 132 5 16 207 207.0000 8 80 800 314 +5 27 132 5 16 207 207.0000 3 12 231 190 +5 27 132 5 16 207 207.0000 6 23 303 909 +6 20 315 6 20 315 279.3333 2 3 207 207 +6 20 315 6 20 315 279.3333 1 21 909 12 +6 20 315 6 20 315 279.3333 7 13 312 406 +6 20 315 6 20 315 279.3333 8 64 248 107 +6 20 315 6 20 315 279.3333 6 20 315 279 +6 20 315 6 20 315 279.3333 1 19 203 107 +6 20 315 6 20 315 279.3333 8 80 800 314 +6 20 315 6 20 315 279.3333 3 12 231 190 +6 20 315 6 20 315 279.3333 6 23 303 909 +8 33 404 8 33 404 213.6667 2 3 207 207 +8 33 404 8 33 404 213.6667 1 21 909 12 +8 33 404 8 33 404 213.6667 7 13 312 406 +8 33 404 8 33 404 213.6667 8 64 248 107 +8 33 404 8 33 404 213.6667 6 20 315 279 +8 33 404 8 33 404 213.6667 1 19 203 107 +8 33 404 8 33 404 213.6667 8 80 800 314 +8 33 404 8 33 404 213.6667 3 12 231 190 +8 33 404 8 33 404 213.6667 6 23 303 909 +select * from v4,v1,t2 where +(((v4.b>10) and (v4.a>1)) or (v4.b<20)) and (v1.max_c>200) and (v1.a=v4.a); +a b min_c a b max_c avg_c a b c d +1 19 107 1 21 500 234.6000 2 3 207 207 +1 19 107 1 21 500 234.6000 1 21 909 12 +1 19 107 1 21 500 234.6000 7 13 312 406 +1 19 107 1 21 500 234.6000 8 64 248 107 +1 19 107 1 21 500 234.6000 6 20 315 279 +1 19 107 1 21 500 234.6000 1 19 203 107 +1 19 107 1 21 500 234.6000 8 80 800 314 +1 19 107 1 21 500 234.6000 3 12 231 190 +1 19 107 1 21 500 234.6000 6 23 303 909 +5 16 207 5 16 207 207.0000 2 3 207 207 +5 16 207 5 16 207 207.0000 1 21 909 12 +5 16 207 5 16 207 207.0000 7 13 312 406 +5 16 207 5 16 207 207.0000 8 64 248 107 +5 16 207 5 16 207 207.0000 6 20 315 279 +5 16 207 5 16 207 207.0000 1 19 203 107 +5 16 207 5 16 207 207.0000 8 80 800 314 +5 16 207 5 16 207 207.0000 3 12 231 190 +5 16 207 5 16 207 207.0000 6 23 303 909 +5 27 132 5 16 207 207.0000 2 3 207 207 +5 27 132 5 16 207 207.0000 1 21 909 12 +5 27 132 5 16 207 207.0000 7 13 312 406 +5 27 132 5 16 207 207.0000 8 64 248 107 +5 27 132 5 16 207 207.0000 6 20 315 279 +5 27 132 5 16 207 207.0000 1 19 203 107 +5 27 132 5 16 207 207.0000 8 80 800 314 +5 27 132 5 16 207 207.0000 3 12 231 190 +5 27 132 5 16 207 207.0000 6 23 303 909 +6 20 315 6 20 315 279.3333 2 3 207 207 +6 20 315 6 20 315 279.3333 1 21 909 12 +6 20 315 6 20 315 279.3333 7 13 312 406 +6 20 315 6 20 315 279.3333 8 64 248 107 +6 20 315 6 20 315 279.3333 6 20 315 279 +6 20 315 6 20 315 279.3333 1 19 203 107 +6 20 315 6 20 315 279.3333 8 80 800 314 +6 20 315 6 20 315 279.3333 3 12 231 190 +6 20 315 6 20 315 279.3333 6 23 303 909 +8 33 404 8 33 404 213.6667 2 3 207 207 +8 33 404 8 33 404 213.6667 1 21 909 12 +8 33 404 8 33 404 213.6667 7 13 312 406 +8 33 404 8 33 404 213.6667 8 64 248 107 +8 33 404 8 33 404 213.6667 6 20 315 279 +8 33 404 8 33 404 213.6667 1 19 203 107 +8 33 404 8 33 404 213.6667 8 80 800 314 +8 33 404 8 33 404 213.6667 3 12 231 190 +8 33 404 8 33 404 213.6667 6 23 303 909 +explain select * from v4,v1,t2 where +(((v4.b>10) and (v4.a>1)) or (v4.b<20)) and (v1.max_c>200) and (v1.a=v4.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join) +1 PRIMARY <derived4> ref key0 key0 5 v4.a 2 Using where +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort +2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v4,v1,t2 where +(((v4.b>10) and (v4.a>1)) or (v4.b<20)) and (v1.max_c>200) and (v1.a=v4.a); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(((v4.b > 10) and (v4.a > 1)) or (v4.b < 20))" + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "attached_condition": "((((v4.b > 10) and (v4.a > 1)) or (v4.b < 20)) and (v4.a is not null))", + "materialized": { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "v1.a, v1.b", + "temporary_table": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a < 15) and (((v1.b > 10) and (v1.a > 1)) or (v1.b < 20)))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 15) and (((t1.b > 10) and (t1.a > 1)) or (t1.b < 20)))" + } + } + } + } + } + } + } + } + } + } + }, + "table": { + "table_name": "<derived4>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["v4.a"], + "rows": 2, + "filtered": 100, + "attached_condition": "(v1.max_c > 200)", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "((max_c < 707) and (max_c > 200))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + } + } + } + } + } + } + } +} +# using embedded view : pushing different conditions +# using several derived tables : pushing only in one table +# extracted or formula : pushing into WHERE +# extracted or formula : pushing into HAVING +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v4,v2 where +((v4.a>12) and (v4.min_c<300) and (v4.b>13)) or (v4.a<1); +a b min_c a b max_c avg_c +select * from v4,v2 where +((v4.a>12) and (v4.min_c<300) and (v4.b>13)) or (v4.a<1); +a b min_c a b max_c avg_c +explain select * from v4,v2 where +((v4.a>12) and (v4.min_c<300) and (v4.b>13)) or (v4.a<1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where +1 PRIMARY <derived4> ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join) +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v4,v2 where +((v4.a>12) and (v4.min_c<300) and (v4.b>13)) or (v4.a<1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(((v4.a > 12) and (v4.min_c < 300) and (v4.b > 13)) or (v4.a < 1))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(((v1.a > 12) and (min_c < 300) and (v1.b > 13)) or (v1.a < 1))", + "filesort": { + "sort_key": "v1.a, v1.b", + "temporary_table": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a < 15) and (((v1.a > 12) and (v1.b > 13)) or (v1.a < 1)))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 15) and (((t1.a > 12) and (t1.b > 13)) or (t1.a < 1)))" + } + } + } + } + } + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "<derived4>", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + } + } +} +# using embedded view : pushing different conditions +# using several derived tables : pushing only in one table +# conjunctive subformula : pushing into WHERE +# conjunctive subformula : pushing into HAVING +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and (v4.min_c<100); +a b min_c a b max_c avg_c +select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and (v4.min_c<100); +a b min_c a b max_c avg_c +explain select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and (v4.min_c<100); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where +1 PRIMARY <derived4> ref key0 key0 5 v4.a 2 +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and (v4.min_c<100); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v4.b = v4.a) and (v4.min_c < 100) and (v4.a is not null))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(min_c < 100)", + "filesort": { + "sort_key": "v1.a, v1.b", + "temporary_table": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.b = v1.a) and (v1.a < 15))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.b = t1.a) and (t1.a < 15))" + } + } + } + } + } + } + } + } + } + } + }, + "table": { + "table_name": "<derived4>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["b"], + "ref": ["v4.a"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + } + } +} +# using embedded view : pushing the same conditions +# using several derived tables : pushing in all tables +# extracted and formula : pushing into WHERE using equalities +# conjunctive subformula : pushing into WHERE +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and (v2.b<30); +a b min_c a b max_c avg_c +select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and (v2.b<30); +a b min_c a b max_c avg_c +explain select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and (v2.b<30); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where +1 PRIMARY <derived4> ref key0 key0 5 v4.a 2 +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and (v2.b<30); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v4.b = v4.a) and (v4.a < 30) and (v4.a is not null))", + "materialized": { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "v1.a, v1.b", + "temporary_table": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.b = v1.a) and (v1.a < 15) and (v1.a < 30))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.b = t1.a) and (t1.a < 15) and (t1.a < 30))" + } + } + } + } + } + } + } + } + } + } + }, + "table": { + "table_name": "<derived4>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["b"], + "ref": ["v4.a"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and (t1.b < 30))" + } + } + } + } + } + } + } +} +# using embedded view : pushing the same conditions +# using several derived tables : pushing in all tables +# extracted or formula : pushing into WHERE using equalities +# extracted and formula : pushing into WHERE using equalities +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and ((v2.b<30) or (v4.a>2)); +a b min_c a b max_c avg_c +select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and ((v2.b<30) or (v4.a>2)); +a b min_c a b max_c avg_c +explain select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and ((v2.b<30) or (v4.a>2)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where +1 PRIMARY <derived4> ref key0 key0 5 v4.a 2 +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v4,v2 where +(v4.a=v2.b) and (v4.a=v4.b) and ((v2.b<30) or (v4.a>2)); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v4.b = v4.a) and ((v4.a < 30) or (v4.a > 2)) and (v4.a is not null))", + "materialized": { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "v1.a, v1.b", + "temporary_table": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.b = v1.a) and (v1.a < 15) and ((v1.a < 30) or (v1.a > 2)))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.b = t1.a) and (t1.a < 15) and ((t1.a < 30) or (t1.a > 2)))" + } + } + } + } + } + } + } + } + } + } + }, + "table": { + "table_name": "<derived4>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["b"], + "ref": ["v4.a"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a > 5) and ((t1.b < 30) or (t1.b > 2)))" + } + } + } + } + } + } + } +} +# using embedded view : pushing the same conditions +# using several derived tables : pushing in all tables +# extracted or formula : pushing into WHERE +# conjunctive subformula : pushing into WHERE +# pushing equalities +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v4,v2 where +(((v4.a<12) and (v4.b>13)) or (v4.a>10)) and +(v4.min_c=v2.max_c) and (v4.min_c>100); +a b min_c a b max_c avg_c +6 20 315 6 20 315 279.3333 +8 33 404 8 33 404 213.6667 +select * from v4,v2 where +(((v4.a<12) and (v4.b>13)) or (v4.a>10)) and +(v4.min_c=v2.max_c) and (v4.min_c>100); +a b min_c a b max_c avg_c +6 20 315 6 20 315 279.3333 +8 33 404 8 33 404 213.6667 +explain select * from v4,v2 where +(((v4.a<12) and (v4.b>13)) or (v4.a>10)) and +(v4.min_c=v2.max_c) and (v4.min_c>100); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Using where +1 PRIMARY <derived4> ref key0 key0 5 v4.min_c 2 +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v4,v2 where +(((v4.a<12) and (v4.b>13)) or (v4.a>10)) and +(v4.min_c=v2.max_c) and (v4.min_c>100); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "<derived2>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((((v4.a < 12) and (v4.b > 13)) or (v4.a > 10)) and (v4.min_c > 100) and (v4.min_c is not null))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(min_c > 100)", + "filesort": { + "sort_key": "v1.a, v1.b", + "temporary_table": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a < 15) and (((v1.a < 12) and (v1.b > 13)) or (v1.a > 10)))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 15) and (((t1.a < 12) and (t1.b > 13)) or (t1.a > 10)))" + } + } + } + } + } + } + } + } + } + } + }, + "table": { + "table_name": "<derived4>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["max_c"], + "ref": ["v4.min_c"], + "rows": 2, + "filtered": 100, + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "((max_c < 707) and (max_c > 100))", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + } + } +} +# using embedded view : pushing the same conditions +# using several derived tables : pushing only in one table +# extracted or formula : pushing into WHERE +set statement optimizer_switch='condition_pushdown_for_derived=off' for select * from v4,v2,t2 where +(((v4.a<12) and (t2.b>13)) or (v4.a>10)) and +(v4.min_c=t2.c) and (t2.c>100); +a b min_c a b max_c avg_c a b c d +6 20 315 6 20 315 279.3333 6 20 315 279 +6 20 315 8 33 404 213.6667 6 20 315 279 +select * from v4,v2,t2 where +(((v4.a<12) and (t2.b>13)) or (v4.a>10)) and +(v4.min_c=t2.c) and (t2.c>100); +a b min_c a b max_c avg_c a b c d +6 20 315 6 20 315 279.3333 6 20 315 279 +6 20 315 8 33 404 213.6667 6 20 315 279 +explain select * from v4,v2,t2 where +(((v4.a<12) and (t2.b>13)) or (v4.a>10)) and +(v4.min_c=t2.c) and (t2.c>100); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2 Using where +1 PRIMARY <derived4> ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join) +4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +2 DERIVED <derived3> ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort +explain format=json select * from v4,v2,t2 where +(((v4.a<12) and (t2.b>13)) or (v4.a>10)) and +(v4.min_c=t2.c) and (t2.c>100); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 9, + "filtered": 100, + "attached_condition": "((t2.c > 100) and (t2.c is not null))" + }, + "table": { + "table_name": "<derived2>", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["min_c"], + "ref": ["test.t2.c"], + "rows": 2, + "filtered": 100, + "attached_condition": "(((v4.a < 12) and (t2.b > 13)) or (v4.a > 10))", + "materialized": { + "query_block": { + "select_id": 2, + "having_condition": "(min_c > 100)", + "filesort": { + "sort_key": "v1.a, v1.b", + "temporary_table": { + "table": { + "table_name": "<derived3>", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((v1.a < 15) and ((v1.a < 12) or (v1.a > 10)))", + "materialized": { + "query_block": { + "select_id": 3, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "((t1.a < 15) and ((t1.a < 12) or (t1.a > 10)))" + } + } + } + } + } + } + } + } + } + } + }, + "block-nl-join": { + "table": { + "table_name": "<derived4>", + "access_type": "ALL", + "rows": 20, + "filtered": 100 + }, + "buffer_type": "flat", + "buffer_size": "256Kb", + "join_type": "BNL", + "materialized": { + "query_block": { + "select_id": 4, + "having_condition": "(max_c < 707)", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 20, + "filtered": 100, + "attached_condition": "(t1.a > 5)" + } + } + } + } + } + } + } +} +drop view v1,v2,v3,v4,v_union,v2_union,v_double,v_char,v_decimal; +drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal; diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test new file mode 100644 index 00000000000..6bde221a55c --- /dev/null +++ b/mysql-test/t/derived_cond_pushdown.test @@ -0,0 +1,812 @@ +let $no_pushdown= set statement optimizer_switch='condition_pushdown_for_derived=off' for; + +create table t1 (a int, b int, c int); +create table t2 (a int, b int, c int, d decimal); +insert into t1 values + (1,21,345), (1,33,7), (8,33,114), (1,21,500), (1,19,107), (5,14,787), + (8,33,123), (9,10,211), (5,16,207), (1,33,988), (5,27,132), (1,21,104), + (6,20,309), (6,20,315), (1,21,101), (8,33,404), (9,10,800), (1,21,123), + (7,11,708), (6,20,214); +insert into t2 values + (2,3,207,207.0000), (1,21,909,12.0000), (7,13,312,406.0000), + (8,64,248,107.0000), (6,20,315,279.3333), (1,19,203,107.0000), + (8,80,800,314.0000), (3,12,231,190.0000), (6,23,303,909.0000); + +create table t1_double(a int, b double, c double); +insert into t1_double values + (1,23.4,14.3333), (1,12.5,18.9), (3,12.5,18.9), + (4,33.4,14.3333), (4,14.3333,13.65), (5,17.89,7.22), + (6,33.4,14.3), (10,33.4,13.65), (11,33.4,13.65); + +create table t2_double(a int, b double, c double); +insert into t2_double values + (1,22.4,14.3333), (1,12.5,18.9), (2,22.4,18.9), + (4,33.4,14.3333), (5,22.4,13.65), (7,17.89,18.9), + (6,33.4,14.3333), (10,31.4,13.65), (12,33.4,13.65); + +create table t1_char(a char, b char(8), c int); +insert into t1_char values + ('a','Ivan',1), ('b','Vika',2), ('b','Inga',6), ('c','Vika',7), + ('b','Ivan',7), ('a','Alex',6), ('b','Inga',5), ('d','Ron',9), + ('d','Harry',2), ('d','Hermione',3), ('c','Ivan',3), ('c','Harry',4); + +create table t2_char(a char, b char(8), c int); +insert into t2_char values + ('b','Ivan',1), ('c','Vinny',3), ('c','Inga',9), ('a','Vika',1), + ('c','Ivan',2), ('b','Ali',6), ('c','Inga',2), ('a','Ron',9), + ('d','Harry',1), ('b','Hermes',3), ('b','Ivan',11), ('b','Harry',4); + +create table t1_decimal (a decimal(3,1), b decimal(3,1), c int); +insert into t1_decimal values + (1,1,23),(2,2,11),(3,3,16), + (1,1,12),(1,1,14),(2,3,15), + (2,1,13),(2,3,11),(3,3,16); + +create table t2_decimal (a decimal(3,1), b decimal(3,1), c int); +insert into t2_decimal values + (2,1,13),(2,2,11),(3,3,16), + (1,3,22),(1,3,14),(2,2,15), + (2,1,43),(2,3,11),(2,3,16); + +create view v1 as select a, b, max(c) as max_c, avg(c) as avg_c from t1 + group by a,b having max_c < 707; + +create view v2 as select a, b, max(c) as max_c, avg(c) as avg_c from t1 + where t1.a>5 group by a,b having max_c < 707; + +create view v3 as select a, b, min(c) as min_c from t1 + where t1.a<10 group by a,b having min_c > 109; + +create view v4 as + select a, b, min(max_c) as min_c from v1 + where (v1.a<15) group by a,b; + +create view v_union as + select a, b, min(c) as c from t1 + where t1.a<10 group by a,b having c > 109 + union + select a, b, max(c) as c from t1 + where t1.b>10 group by a,b having c < 300; + +create view v2_union as + select a, b, min(c) as c from t1 + where t1.a<10 group by a,b having c > 109 + union + select a, b, max(c) as c from t1 + where t1.b>10 group by a,b having c < 300 + union + select a, b, avg(c) as c from t1 + where t1.c>300 group by a,b having c < 707; + +create view v_double as + select a, avg(a/4) as avg_a, b, c from t1_double + where (b>12.2) group by b,c having (avg_a<22.333); + +create view v_char as + select a, b, max(c) as max_c from t1_char + group by a,b having max_c < 9; + +create view v_decimal as + select a, b, avg(c) as avg_c from t1_decimal + group by a,b having (avg_c>12); + +--echo # conjunctive subformula : pushing into HAVING +let $query= select * from v1,t2 where (v1.max_c>214) and (t2.a>v1.a); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from + (select a, b, max(c) as max_c, avg(c) as avg_c from t1 + group by a,b having max_c < 707) v1, + t2 where (v1.a=t2.a) and (v1.max_c>300); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted or formula : pushing into HAVING +let $query= + select * from v1,t2 where + ((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,t2 where + ((v1.max_c>300) and (v1.avg_c>t2.d) and (v1.b=t2.b)) or + ((v1.max_c<135) and (v1.max_c<t2.c) and (v1.a=t2.a)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # conjunctive subformula : pushing into WHERE +let $query= select * from v1,t2 where (v1.a>6) and (t2.b>v1.b); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= select * from v2,t2 where (v2.b>25) and (t2.a<v2.a); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted or formula : pushing into WHERE +let $query= + select * from v1,t2 where + ((v1.a>7) and (t2.c<v1.max_c)) or ((v1.a<2) and (t2.b<v1.b)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v2,t2 where + ((v2.a>7) and (t2.c<v2.max_c)) or ((v2.a>5) and (t2.b<v2.b)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,t2 where + ((v1.a>4) and (v1.b>t2.b) and (v1.max_c=t2.d)) or + ((v1.a<2) and (v1.max_c<t2.c) and (v1.max_c=t2.d)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # conjunctive subformulas : pushing into HAVING and WHERE +let $query= + select * from v1,t2 where (v1.a<2) and (v1.max_c>400) and (t2.b>v1.b); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v_double as v,t2_double as t where + (v.a=t.a) and (v.avg_a>0.45) and (v.b>10); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v_decimal as v,t2_decimal as t where + (v.a=t.a) and (v.avg_c>15) and (v.b>1); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted or formula : pushing into HAVING and WHERE +let $query= + select * from v1,t2 where + ((v1.a>7) and (v1.max_c>300) and (t2.c<v1.max_c)) or + ((v1.a<4) and (v1.max_c<500) and (t2.b<v1.b)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,t2 where ((v1.a<2) and (v1.max_c>120)) or (v1.a>7); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted or formulas : pushing into WHERE and HAVING +let $query= + select * from v1,t2 where + ((v1.a<2) and (v1.max_c>120) and (v1.b=t2.b)) or (v1.a>7); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,t2 where + ((v1.a<2) and (v1.max_c<200) and (t2.c>v1.max_c) and (v1.max_c=t2.d)) or + ((v1.a>4) and (v1.max_c<500) and (t2.b<v1.b) and (v1.max_c=t2.c)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # prepare of a query containing extracted or formula +prepare stmt from "select * from v1,t2 where + ((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a));"; +execute stmt; +execute stmt; +deallocate prepare stmt; +prepare stmt from + "explain format=json select * from v1,t2 where + ((v1.max_c>400) and (t2.a>v1.a)) or ((v1.max_c<135) and (t2.a<v1.a));"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +--echo # conjunctive subformula : pushing into WHERE +--echo # pushing equalities +let $query= + select * from v1,t2 where (t2.a=v1.a) and (v1.b=t2.b) and (v1.a=1); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= select * from v1,t2 where (v1.a=5) and (v1.max_c=t2.d); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # conjunctive subformula : pushing into WHERE using equalities +let $query= select * from v1,t2 where (t2.a<5) and (v1.a=t2.a); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # conjunctive subformula : pushing into HAVING using equalities +let $query= select * from v1,t2 where (t2.c>150) and (v1.max_c=t2.c); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted and formula : pushing into WHERE +--echo # pushing equalities +let $query= + select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a) and (v1.a=3); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,t2 where (v1.a=1) and (v1.b=21) and (t2.a=2); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v_char as v,t2_char as t where + (v.a='c') and (v.b<'Hermes') and ((v.b=t.b) or (v.max_c>20)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted and formula : pushing into WHERE using equalities +--echo # pushing equalities +let $query= +select * from v_decimal as v,t2_decimal as t where + (v.a=v.b) and (v.b=t.b) and ((t.b>1) or (v.a=1)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted or formula : pushing into HAVING using equalities +let $query= + select * from v1,t2 + where ((t2.a<4) and (v1.a=t2.a)) or ((t2.c>150) and (v1.max_c=t2.c)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # conjunctive subformulas : pushing into WHERE and HAVING using equalities +let $query= + select * from v1,t2 + where ((t2.a>5) and (v1.a=t2.a)) and ((t2.c>250) and (v1.max_c=t2.c)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # conjunctive subformulas : pushing into WHERE and HAVING +--echo # pushing equalities +let $query= + select * from + (select a, b, max(c) as max_c, avg(c) as avg_c from t1 + group by a,b having max_c < 707) v1, + t2 where (v1.a=8) and (v1.a=t2.a) and (v1.max_c=404); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # conjunctive subformulas : pushing into WHERE and HAVING +let $query= + select * from v1,t2 where + (v1.a>3) and (v1.max_c>200) and (t2.b<v1.b) and (t2.d=v1.max_c); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # conjunctive subformula : pushing into WHERE +--echo # extracted or formula : pushing into HAVING using equalities +--echo # pushing equalities +let $query= + select * from v_double as v,t2_double as t where + (v.b=v.c) and (v.c=t.c) and ((t.c>10) or (v.a=1)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # conjunctive subformula : pushing into WHERE +--echo # extracted or formula : pushing into HAVING using equalities +let $query= + select * from v_double as v,t2_double as t where + (((v.a>0.2) or (v.b<17)) or (t.c>17)) and (t.c=v.c) and (v.c>18); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted or formula : pushing into WHERE +--echo # conjunctive subformula : pushing into HAVING +--echo # pushing equalities +let $query= + select * from v_decimal as v,t2_decimal as t where + (((v.a>4) or (v.a=2)) or (v.b>3)) and (v.avg_c=13); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from + (select a, b, max(c) as max_c, avg(c) as avg_c from t1 + where t1.a>5 group by a,b having max_c < 707) v1, + t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.a=v1.b); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # nothing to push +let $query= + select * from v1,t2 where (t2.a<2) and (t2.c>900); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= select * from v1,t2 where (v1.a=t2.a) and (v1.b=t2.b); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,t2 where + (t2.a=v1.a) or (v1.b=t2.b) and ((v1.a=1) or (v1.a=6)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,t2 where (v1.a=1) or (v1.b=21) or (t2.a=2); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,t2 where + (t2.a<2) and (t2.c>900) and ((v1.a<t2.a) or (t2.a<11)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using several derived tables : nothing to push +let $query= select * from v1,v2,t2 where + (v1.a=v2.a) and (v1.a=t2.a) and (v2.b<50); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,v2,t2 where + ((v1.a=v2.a) or (v1.a=t2.a)) and (t2.b<50) and (v1.b=v2.b); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v1,v2,t2 where + ((v1.a=v2.a) and (v1.a=t2.a)) or ((v2.b>13) and (t2.c<115)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using several derived tables : pushing in all tables +--echo # conjunctive subformula : pushing into HAVING +--echo # extracted or formula : pushing into WHERE +--echo # pushing equalities +let $query= + select * from v1,v2,t2 where ((v1.a=v2.a) or (v1.a=t2.a)) and + ((v2.b<50) or (v2.b=19)) and (v1.max_c<300); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using several derived tables : pushing only in one table +--echo # conjunctive subformula : pushing into WHERE +--echo # pushing equalities +let $query= + select * from v1,v2,t2 where + (v1.a=t2.a) and (v1.a=v1.b) and (v1.a=v2.a) and (v2.max_c<300); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using several derived tables : pushing only in one table +--echo # extracted and formula : pushing into WHERE +--echo # conjunctive subformula : pushing into WHERE using equalities +--echo # pushing equalities +let $query= + select * from v1,v2,t2 where (v1.a=1) and (v1.b>10) and (v1.b=v2.b); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted or formula : pushing into WHERE +--echo # conjunctive subformula : pushing into WHERE using equalities +--echo # pushing equalities +let $query= + select * from v_char as v,t2_char as t where + (v.a=t.a) and (t.a='b') and ((v.b='Vika') or (v.b='Ali')); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using several derived tables : pushing in all tables +--echo # extracted or formula : pushing into WHERE +--echo # conjunctive subformulas : pushing into HAVING +--echo # pushing equalities +let $query= + select * from v1,v2,v3,t2 where + ((v1.a=v2.a) or (v1.a=t2.a)) and ((v3.b<50) or (v3.b=33)) + and (v1.max_c<500) and (v3.a=t2.a) and (v2.max_c>300); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using several derived tables : pushing in all tables +--echo # conjunctive subformulas : pushing into HAVING +let $query= + select * from + (select a, b, max(c) as max_c, avg(c) as avg_c from t1 + where t1.a>5 group by a,b having max_c < 707) v1, + (select a, b, min(c) as min_c from t1 + where t1.a>5 group by a,b having min_c < 707) v2, + t2 where (v1.a=v2.a) and (v1.b=t2.b) and (v1.max_c>130) and (v2.min_c<130); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using several derived tables : pushing in all tables +--echo # extracted or formulas : pushing into HAVING +--echo # conjunctive subformula : pushing into HAVING +let $query= + select * from + (select a, b, max(c) as max_c, avg(c) as avg_c from t1 + where t1.a>5 group by a,b having max_c < 707) v1, + (select a, b, min(c) as min_c from t1 + where t1.a>5 group by a,b having min_c < 707) v2, + (select a, b, avg(c) as avg_c from t1 + where t1.a<8 group by a,b) v3, + t2 where (v1.a=v2.a) and (v1.b=v3.b) and ((v3.avg_c>170) or (v3.a<5)) + and ((v1.avg_c<400) or (v1.a>1)) and (v2.min_c<200); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted or formula : pushing into HAVING +--echo # conjunctive subformula : pushing into WHERE +let $query= + select * from + (select a, b, max(c) as max_c, avg(c) as avg_c from t1 + group by a,b having max_c < 707) v1, + t2 where ((v1.a=1) or (v1.max_c<300)) and (v1.b>25); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # extracted and formula : pushing into WHERE +--echo # conjunctive subformula : pushing into HAVING +let $query= + select * from + (select a, b, max(c) as max_c, avg(c) as avg_c from t1 + where t1.a>5 group by a,b having max_c < 707) v1, + t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.b<30); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using query with union +--echo # conjunctive subformula : pushing into WHERE +--echo # conjunctive subformulas : pushing into HAVING and WHERE +let $query= + select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (t2.c>800) + union + select * from v1,t2 where (v1.max_c>100) and (v1.a>7) and (t2.d>800); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using query with union +--echo # extracted and formula : pushing into WHERE +--echo # extracted or formula : pushing into HAVING +--echo # pushing equalities +let $query= + select * from v1,t2 where (v1.a<5) and (v1.b=t2.b) and (v1.b=19) + union + select * from v1,t2 where ((v1.max_c>400) or (v1.avg_c>270)) and (v1.a<t2.a); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using query with union +--echo # extracted or formula : pushing into HAVING +--echo # extracted or formula : pushing into WHERE +--echo # pushing equalities +let $query= + select * from v1,t2 where + ((t2.a=v1.a) or (v1.b=t2.b)) and ((v1.a=1) or (v1.a=6)) + union + select * from v1,t2 where ((v1.a>3) and (v1.b>27)) or (v1.max_c>550); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using query with union +--echo # extracted or formula : pushing into HAVING +--echo # conjunctive subformulas : pushing into WHERE +--echo # pushing equalities +let $query= + select * from v1,t2 where + ((v1.a=1) and (v1.a=t2.a)) and ((v1.max_c<500) or (v1.avg_c>500)) + union + select * from v2,t2 where + ((v2.a<t2.b) or (v2.max_c>200)) and (v2.b>10) and (t2.a<2) + union + select * from v2,t2 where + (v2.max_c=t2.c) and (v2.b<10); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using derived table with union +--echo # conjunctive subformulas : pushing into WHERE and HAVING +let $query= select * from v_union,t2 where (v_union.a<3) and (v_union.c>100); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using derived table with union +--echo # conjunctive subformula : pushing into WHERE +--echo # extracted or formula : pushing into HAVING +let $query= + select * from v_union,t2 where + ((v_union.a<2) or (v_union.c>800)) and (v_union.b>12); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using derived table with union +--echo # conjunctive subformula : pushing into HAVING +--echo # conjunctive subformula : pushing into WHERE +--echo # pushing equalities +let $query= + select * from v_union,t2 where + (v_union.a=1) and (v_union.a=t2.a) and (v_union.c<200); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +let $query= + select * from v_char as v,t2_char as t where + (v.a=t.a) and (v.b='Vika') and (v.max_c>2); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using derived table with union +--echo # using several derived tables : pushing in all tables +--echo # conjunctive subformula : pushing into WHERE using equalities +--echo # pushing equalities +let $query= + select * from v_union,v1,t2 where + (v_union.a=v1.a) and (v1.a=t2.a) and (t2.a=1) + and ((v_union.c>800) or (v1.max_c>200)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using derived table with union +--echo # extracted or formula : pushing into WHERE +--echo # conjunctive subformula : pushing into HAVING +--echo # pushing equalities +let $query= + select * from v2_union as v,t2 where + ((v.a=6) or (v.a=8)) and (v.c>200) and (v.a=t2.a); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using embedded derived table : pushing the same conditions +--echo # using several derived tables : pushing in all tables +--echo # conjunctive subformula : pushing into WHERE +--echo # extracted and formula : pushing into WHERE +let $query= +select * from v4,v1 where + (v4.a<13) and (v1.a>5) and (v1.b>12); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using embedded view : nothing to push +--echo # using several derived tables : pushing only in one table +--echo # conjunctive subformula : pushing into WHERE +let $query= + select * from v4,v1,t2 where + (v4.a=t2.a) and (v4.a=v1.a) and (v1.b>30); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using embedded view : pushing different conditions +--echo # using several derived tables : pushing in all tables +--echo # conjunctive subformula : pushing into WHERE using equalities +--echo # extracted and formula : pushing into WHERE using equalities +--echo # conjunctive subformula : pushing into HAVING +let $query= + select * from v4,v1,t2 where + (v4.a=t2.a) and (v4.a>1) and (v4.a=v1.a) and (v4.min_c>100) and (v1.b<30); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using embedded view : pushing different conditions +--echo # using several derived tables : pushing in all tables +--echo # extracted or formula : pushing into WHERE +--echo # conjunctive subformula : pushing into HAVING +let $query= + select * from v4,v1,t2 where + (((v4.b>10) and (v4.a>1)) or (v4.b<20)) and (v1.max_c>200) and (v1.a=v4.a); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using embedded view : pushing different conditions +--echo # using several derived tables : pushing only in one table +--echo # extracted or formula : pushing into WHERE +--echo # extracted or formula : pushing into HAVING +let $query= + select * from v4,v2 where + ((v4.a>12) and (v4.min_c<300) and (v4.b>13)) or (v4.a<1); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using embedded view : pushing different conditions +--echo # using several derived tables : pushing only in one table +--echo # conjunctive subformula : pushing into WHERE +--echo # conjunctive subformula : pushing into HAVING +--echo # pushing equalities +let $query= + select * from v4,v2 where + (v4.a=v2.b) and (v4.a=v4.b) and (v4.min_c<100); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using embedded view : pushing the same conditions +--echo # using several derived tables : pushing in all tables +--echo # extracted and formula : pushing into WHERE using equalities +--echo # conjunctive subformula : pushing into WHERE +--echo # pushing equalities +let $query= + select * from v4,v2 where + (v4.a=v2.b) and (v4.a=v4.b) and (v2.b<30); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using embedded view : pushing the same conditions +--echo # using several derived tables : pushing in all tables +--echo # extracted or formula : pushing into WHERE using equalities +--echo # extracted and formula : pushing into WHERE using equalities +--echo # pushing equalities +let $query= + select * from v4,v2 where + (v4.a=v2.b) and (v4.a=v4.b) and ((v2.b<30) or (v4.a>2)); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using embedded view : pushing the same conditions +--echo # using several derived tables : pushing in all tables +--echo # extracted or formula : pushing into WHERE +--echo # conjunctive subformula : pushing into WHERE +--echo # pushing equalities +let $query= + select * from v4,v2 where + (((v4.a<12) and (v4.b>13)) or (v4.a>10)) and + (v4.min_c=v2.max_c) and (v4.min_c>100); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +--echo # using embedded view : pushing the same conditions +--echo # using several derived tables : pushing only in one table +--echo # extracted or formula : pushing into WHERE +let $query= + select * from v4,v2,t2 where + (((v4.a<12) and (t2.b>13)) or (v4.a>10)) and + (v4.min_c=t2.c) and (t2.c>100); +eval $no_pushdown $query; +eval $query; +eval explain $query; +eval explain format=json $query; + +drop view v1,v2,v3,v4,v_union,v2_union,v_double,v_char,v_decimal; +drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;
\ No newline at end of file diff --git a/sql/item.cc b/sql/item.cc index 65fb00d4757..6c24cf2d073 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -479,6 +479,7 @@ Item::Item(THD *thd): } } + /** Constructor used by Item_field, Item_ref & aggregate (sum) functions. @@ -2161,6 +2162,73 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll, } +/** + @brief + Building clone for Item_func_or_sum + + @param thd thread handle + @param mem_root part of the memory for the clone + + @details + This method gets copy of the current item and also + build clones for its referencies. For the referencies + build_copy is called again. + + @retval + clone of the item + 0 if an error occured +*/ + +Item* Item_func_or_sum::build_clone(THD *thd, MEM_ROOT *mem_root) +{ + Item_func_or_sum *copy= (Item_func_or_sum *) get_copy(thd, mem_root); + if (!copy) + return 0; + if (arg_count > 2) + copy->args= + (Item**) alloc_root(mem_root, sizeof(Item*) * arg_count); + else if (arg_count > 0) + copy->args= copy->tmp_arg; + for (uint i= 0; i < arg_count; i++) + { + Item *arg_clone= args[i]->build_clone(thd, mem_root); + if (!arg_clone) + return 0; + copy->args[i]= arg_clone; + } + return copy; +} + + +/** + @brief + Building clone for Item_ref + + @param thd thread handle + @param mem_root part of the memory for the clone + + @details + This method gets copy of the current item and also + builds clone for its reference. + + @retval + clone of the item + 0 if an error occured +*/ + +Item* Item_ref::build_clone(THD *thd, MEM_ROOT *mem_root) +{ + Item_ref *copy= (Item_ref *) get_copy(thd, mem_root); + if (!copy) + return 0; + Item *item_clone= (* ref)->build_clone(thd, mem_root); + if (!item_clone) + return 0; + *copy->ref= item_clone; + return copy; +} + + void Item_ident_for_show::make_field(THD *thd, Send_field *tmp_field) { tmp_field->table_name= tmp_field->org_table_name= table_name; @@ -6554,6 +6622,85 @@ Item *Item_field::update_value_transformer(THD *thd, uchar *select_arg) } +Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg) +{ + st_select_lex *sl= (st_select_lex *)arg; + table_map map= sl->master_unit()->derived->table->map; + if (!((Item_field*)this)->item_equal) + { + if (used_tables() == map) + { + Item_ref *rf= + new (thd->mem_root) Item_ref(thd, &sl->context, + NullS, NullS, + ((Item_field*) this)->field_name); + if (!rf) + return 0; + return rf; + } + } + else + { + Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal; + Item_equal_fields_iterator li(*cond); + Item *item; + while ((item=li++)) + { + if (item->used_tables() == map && item->type() == FIELD_ITEM) + { + Item_ref *rf= + new (thd->mem_root) Item_ref(thd, &sl->context, + NullS, NullS, + ((Item_field*) item)->field_name); + if (!rf) + return 0; + return rf; + } + } + } + return this; +} + + +Item *Item_field::derived_field_transformer_for_where(THD *thd, uchar *arg) +{ + st_select_lex *sl= (st_select_lex *)arg; + List_iterator<Grouping_tmp_field> li(sl->grouping_tmp_fields); + Grouping_tmp_field *field; + table_map map= sl->master_unit()->derived->table->map; + if (used_tables() == map) + { + while ((field=li++)) + { + if (((Item_field*) this)->field == field->tmp_field) + return field->producing_item->build_clone(thd, thd->mem_root); + } + } + else if (((Item_field*)this)->item_equal) + { + Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal; + Item_equal_fields_iterator it(*cond); + Item *item; + while ((item=it++)) + { + if (item->used_tables() == map && item->type() == FIELD_ITEM) + { + Item_field *field_item= (Item_field *) item; + li.rewind(); + while ((field=li++)) + { + if (field_item->field == field->tmp_field) + { + return field->producing_item->build_clone(thd, thd->mem_root); + } + } + } + } + } + return this; +} + + void Item_field::print(String *str, enum_query_type query_type) { if (field && field->table->const_table) @@ -9722,5 +9869,62 @@ const char *dbug_print_item(Item *item) return "Couldn't fit into buffer"; } + #endif /*DBUG_OFF*/ +bool Item_field::exclusive_dependence_on_table_processor(uchar *map) +{ + table_map tab_map= *((table_map *) map); + return !((used_tables() == tab_map || + (item_equal && item_equal->used_tables() & tab_map))); +} + +bool Item_field::exclusive_dependence_on_grouping_fields_processor(uchar *arg) +{ + st_select_lex *sl= (st_select_lex *)arg; + List_iterator<Grouping_tmp_field> li(sl->grouping_tmp_fields); + Grouping_tmp_field *field; + table_map map= sl->master_unit()->derived->table->map; + if (used_tables() == map) + { + while ((field=li++)) + { + if (((Item_field*) this)->field == field->tmp_field) + return false; + } + } + else if (((Item_field*)this)->item_equal) + { + Item_equal *cond= (Item_equal *) ((Item_field*)this)->item_equal; + Item_equal_fields_iterator it(*cond); + Item *item; + while ((item=it++)) + { + if (item->used_tables() == map && item->type() == FIELD_ITEM) + { + li.rewind(); + while ((field=li++)) + { + if (((Item_field *)item)->field == field->tmp_field) + return false; + } + } + } + } + return true; +} + + +/*Item *Item::get_copy(THD *thd, MEM_ROOT *mem_root) +{ + dbug_print_item(this); + DBUG_ASSERT(0); + return 0; +}*/ + + +void Item::register_in(THD *thd) +{ + next= thd->free_list; + thd->free_list= this; +} diff --git a/sql/item.h b/sql/item.h index 674ff6e99dc..0cbe30ca9ef 100644 --- a/sql/item.h +++ b/sql/item.h @@ -33,6 +33,8 @@ C_MODE_START C_MODE_END #ifndef DBUG_OFF +const char *dbug_print_item(Item *item); + static inline bool trace_unsupported_func(const char *where, const char *processor_name) { @@ -105,6 +107,10 @@ char_to_byte_length_safe(uint32 char_length_arg, uint32 mbmaxlen_arg) #define MY_COLL_ALLOW_CONV (MY_COLL_ALLOW_SUPERSET_CONV | MY_COLL_ALLOW_COERCIBLE_CONV) #define MY_COLL_CMP_CONV (MY_COLL_ALLOW_CONV | MY_COLL_DISALLOW_NONE) +#define NO_EXTRACTION_FL (1 << 6) +#define FULL_EXTRACTION_FL (1 << 7) +#define EXTRACTION_MASK (NO_EXTRACTION_FL | FULL_EXTRACTION_FL) + class DTCollation { public: CHARSET_INFO *collation; @@ -607,7 +613,6 @@ class Item: public Value_source, public Type_std_attributes, public Type_handler { - Item(const Item &); /* Prevent use of these */ void operator=(Item &); /** The index in the JOIN::join_tab array of the JOIN_TAB this Item is attached @@ -1105,6 +1110,7 @@ public: virtual bool basic_const_item() const { return 0; } /* cloning of constant items (0 if it is not const) */ virtual Item *clone_item(THD *thd) { return 0; } + virtual Item* build_clone(THD *thd, MEM_ROOT *mem_root) { return get_copy(thd, mem_root); } virtual cond_result eq_cmp_result() const { return COND_OK; } inline uint float_length(uint decimals_par) const { return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;} @@ -1473,6 +1479,14 @@ public: virtual bool exists2in_processor(uchar *opt_arg) { return 0; } virtual bool find_selective_predicates_list_processor(uchar *opt_arg) { return 0; } + virtual bool exclusive_dependence_on_table_processor(uchar *map) + { return 0; } + virtual bool exclusive_dependence_on_grouping_fields_processor(uchar *arg) + { return 0; } + //virtual Item *get_copy(THD *thd, MEM_ROOT *mem_root); + + + virtual Item *get_copy(THD *thd, MEM_ROOT *mem_root)=0; /* To call bool function for all arguments */ struct bool_func_call_args @@ -1679,6 +1693,10 @@ public: { return this; } virtual Item *expr_cache_insert_transformer(THD *thd, uchar *unused) { return this; } + virtual Item *derived_field_transformer_for_having(THD *thd, uchar *arg) + { return this; } + virtual Item *derived_field_transformer_for_where(THD *thd, uchar *arg) + { return this; } virtual bool expr_cache_is_needed(THD *) { return FALSE; } virtual Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs); bool needs_charset_converter(uint32 length, CHARSET_INFO *tocs) @@ -1834,9 +1852,35 @@ public: */ virtual void under_not(Item_func_not * upper __attribute__((unused))) {}; + + + void register_in(THD *thd); + + bool depends_only_on(table_map view_map) + { return marker & FULL_EXTRACTION_FL; } + int get_extraction_flag() + { return marker & EXTRACTION_MASK; } + void set_extraction_flag(int flags) + { + marker &= ~EXTRACTION_MASK; + marker|= flags; + } + void clear_extraction_flag() + { + marker &= ~EXTRACTION_MASK; + } }; +template <class T> +inline Item* get_item_copy (THD *thd, MEM_ROOT *mem_root, T* item) +{ + Item *copy= new (mem_root) T(*item); + copy->register_in(thd); + return copy; +} + + /** Compare two Items for List<Item>::add_unique() */ @@ -2112,6 +2156,8 @@ public: { return this; } bool append_for_log(THD *thd, String *str); + + Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; } }; /***************************************************************************** @@ -2158,6 +2204,7 @@ public: purposes. */ virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; } private: uint m_case_expr_id; @@ -2238,6 +2285,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor("name_const"); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_name_const>(thd, mem_root, this); } }; class Item_num: public Item_basic_constant @@ -2372,6 +2421,8 @@ public: CHARSET_INFO *charset_for_protocol(void) const { return field->charset_for_protocol(); } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } + Item* get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_ident_for_show>(thd, mem_root, this); } }; @@ -2519,7 +2570,13 @@ public: Item_field *field_for_view_update() { return this; } int fix_outer_field(THD *thd, Field **field, Item **reference); virtual Item *update_value_transformer(THD *thd, uchar *select_arg); + virtual Item *derived_field_transformer_for_having(THD *thd, uchar *arg); + virtual Item *derived_field_transformer_for_where(THD *thd, uchar *arg); virtual void print(String *str, enum_query_type query_type); + bool exclusive_dependence_on_table_processor(uchar *map); + bool exclusive_dependence_on_grouping_fields_processor(uchar *arg); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_field>(thd, mem_root, this); } bool is_outer_field() const { DBUG_ASSERT(fixed); @@ -2613,6 +2670,8 @@ public: Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *arg) { return FALSE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_null>(thd, mem_root, this); } }; class Item_null_result :public Item_null @@ -2773,6 +2832,8 @@ public: { return this; } bool append_for_log(THD *thd, String *str); + + Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; } private: virtual bool set_value(THD *thd, sp_rcontext *ctx, Item **it); @@ -2824,6 +2885,8 @@ public: { return int_eq(value, item); } bool check_partition_func_processor(uchar *bool_arg) { return FALSE;} bool check_vcol_func_processor(uchar *arg) { return FALSE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_int>(thd, mem_root, this); } }; @@ -2840,6 +2903,8 @@ public: virtual void print(String *str, enum_query_type query_type); Item_num *neg(THD *thd); uint decimal_precision() const { return max_length; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_uint>(thd, mem_root, this); } }; @@ -2893,6 +2958,8 @@ public: void set_decimal_value(my_decimal *value_par); bool check_partition_func_processor(uchar *bool_arg) { return FALSE;} bool check_vcol_func_processor(uchar *arg) { return FALSE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_decimal>(thd, mem_root, this); } }; @@ -2941,6 +3008,8 @@ public: virtual void print(String *str, enum_query_type query_type); bool eq(const Item *item, bool binary_cmp) const { return real_eq(value, item); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_float>(thd, mem_root, this); } }; @@ -3131,6 +3200,9 @@ public: } return MYSQL_TYPE_STRING; // Not a temporal literal } + + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_string>(thd, mem_root, this); } }; @@ -3360,6 +3432,8 @@ public: } enum Item_result cast_to_int_type() const { return INT_RESULT; } void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_hex_hybrid>(thd, mem_root, this); } }; @@ -3400,6 +3474,8 @@ public: } enum Item_result cast_to_int_type() const { return STRING_RESULT; } void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_hex_string>(thd, mem_root, this); } }; @@ -3482,6 +3558,8 @@ public: void print(String *str, enum_query_type query_type); Item *clone_item(THD *thd); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_date_literal>(thd, mem_root, this); } }; @@ -3501,6 +3579,8 @@ public: void print(String *str, enum_query_type query_type); Item *clone_item(THD *thd); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_time_literal>(thd, mem_root, this); } }; @@ -3522,6 +3602,8 @@ public: void print(String *str, enum_query_type query_type); Item *clone_item(THD *thd); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_datetime_literal>(thd, mem_root, this); } }; @@ -3882,6 +3964,7 @@ public: virtual void fix_length_and_dec()= 0; bool const_item() const { return const_item_cache; } table_map used_tables() const { return used_tables_cache; } + Item* build_clone(THD *thd, MEM_ROOT *mem_root); }; @@ -4057,6 +4140,8 @@ public: DBUG_ASSERT(ref); return (*ref)->is_outer_field(); } + + Item* build_clone(THD *thd, MEM_ROOT *mem_root); /** Checks if the item tree that ref points to contains a subquery. @@ -4065,6 +4150,8 @@ public: { return (*ref)->has_subquery(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_ref>(thd, mem_root, this); } }; @@ -4107,6 +4194,8 @@ public: bool is_null(); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); virtual Ref_Type ref_type() { return DIRECT_REF; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_direct_ref>(thd, mem_root, this); } }; @@ -4268,6 +4357,9 @@ public: { return trace_unsupported_by_check_vcol_func_processor("cache"); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_cache_wrapper>(thd, mem_root, this); } + Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; } }; @@ -4519,6 +4611,8 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); virtual void print(String *str, enum_query_type query_type); table_map used_tables() const; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_ref_null_helper>(thd, mem_root, this); } }; /* @@ -4678,6 +4772,8 @@ public: longlong val_int(); void copy(); int save_in_field(Field *field, bool no_conversions); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_copy_string>(thd, mem_root, this); } }; @@ -4700,6 +4796,8 @@ public: return null_value ? 0 : cached_value; } virtual void copy(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_copy_int>(thd, mem_root, this); } }; @@ -4716,6 +4814,8 @@ public: { return null_value ? 0.0 : (double) (ulonglong) cached_value; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_copy_uint>(thd, mem_root, this); } }; @@ -4742,6 +4842,8 @@ public: cached_value= item->val_real(); null_value= item->null_value; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_copy_float>(thd, mem_root, this); } }; @@ -4761,6 +4863,8 @@ public: double val_real(); longlong val_int(); void copy(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_copy_decimal>(thd, mem_root, this); } }; @@ -5181,6 +5285,8 @@ public: enum Item_result result_type() const { return INT_RESULT; } bool cache_value(); int save_in_field(Field *field, bool no_conversions); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_cache_int>(thd, mem_root, this); } }; @@ -5205,6 +5311,8 @@ public: Important when storing packed datetime values. */ Item *clone_item(THD *thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_cache_temporal>(thd, mem_root, this); } }; @@ -5221,6 +5329,8 @@ public: my_decimal *val_decimal(my_decimal *); enum Item_result result_type() const { return REAL_RESULT; } bool cache_value(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_cache_real>(thd, mem_root, this); } }; @@ -5237,6 +5347,8 @@ public: my_decimal *val_decimal(my_decimal *); enum Item_result result_type() const { return DECIMAL_RESULT; } bool cache_value(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_cache_decimal>(thd, mem_root, this); } }; @@ -5263,6 +5375,8 @@ public: CHARSET_INFO *charset() const { return value->charset(); }; int save_in_field(Field *field, bool no_conversions); bool cache_value(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_cache_str>(thd, mem_root, this); } }; @@ -5286,6 +5400,8 @@ public: */ return Item::safe_charset_converter(thd, tocs); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_cache_str_for_nullif>(thd, mem_root, this); } }; @@ -5357,6 +5473,8 @@ public: } bool cache_value(); virtual void set_null(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_cache_row>(thd, mem_root, this); } }; @@ -5412,6 +5530,7 @@ public: static uint32 display_length(Item *item); static enum_field_types get_real_type(Item *); Field::geometry_type get_geometry_type() const { return geometry_type; }; + Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; } }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 335228c37fa..34416d6422c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -34,6 +34,9 @@ #include "sql_time.h" // make_truncated_value_warning #include "sql_base.h" // dynamic_column_error_message +#define FULL_EXTRACTION_FL (1 << 6) +#define NO_EXTRACTION_FL (1 << 7) + /** find an temporal type (item) that others will be converted to @@ -4844,6 +4847,43 @@ void Item_cond::neg_arguments(THD *thd) } +/** + @brief + Building clone for Item_cond + + @param thd thread handle + @param mem_root part of the memory for the clone + + @details + This method gets copy of the current item and also + build clones for its elements. For this elements + build_copy is called again. + + @retval + clone of the item + 0 if an error occured +*/ + +Item *Item_cond::build_clone(THD *thd, MEM_ROOT *mem_root) +{ + List_iterator_fast<Item> li(list); + Item *item; + Item_cond *copy= (Item_cond *) get_copy(thd, mem_root); + if (!copy) + return 0; + copy->list.empty(); + while ((item= li++)) + { + Item *arg_clone= item->build_clone(thd, mem_root); + if (!arg_clone) + return 0; + if (copy->list.push_back(arg_clone, mem_root)) + return 0; + } + return copy; +} + + void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding) { List_iterator<Item> li(list); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 5789186dbe8..3d688223bcf 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -26,6 +26,7 @@ #include "item_func.h" /* Item_int_func, Item_bool_func */ #define PCRE_STATIC 1 /* Important on Windows */ #include "pcre.h" /* pcre header file */ +#include "item.h" extern Item_result item_cmp_type(Item_result a,Item_result b); inline Item_result item_cmp_type(const Item *a, const Item *b) @@ -124,6 +125,7 @@ public: comparators= 0; } friend class Item_func; + friend class Item_bool_rowready_func2; }; @@ -243,6 +245,8 @@ public: Item_func_istrue(THD *thd, Item *a): Item_func_truth(thd, a, true, true) {} ~Item_func_istrue() {} virtual const char* func_name() const { return "istrue"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_istrue>(thd, mem_root, this); } }; @@ -257,6 +261,8 @@ public: Item_func_truth(thd, a, true, false) {} ~Item_func_isnottrue() {} virtual const char* func_name() const { return "isnottrue"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_isnottrue>(thd, mem_root, this); } }; @@ -270,6 +276,8 @@ public: Item_func_isfalse(THD *thd, Item *a): Item_func_truth(thd, a, false, true) {} ~Item_func_isfalse() {} virtual const char* func_name() const { return "isfalse"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_isfalse>(thd, mem_root, this); } }; @@ -284,6 +292,8 @@ public: Item_func_truth(thd, a, false, false) {} ~Item_func_isnotfalse() {} virtual const char* func_name() const { return "isnotfalse"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_isnotfalse>(thd, mem_root, this); } }; @@ -345,6 +355,8 @@ public: void fix_after_pullout(st_select_lex *new_parent, Item **ref); bool invisible_mode(); void reset_cache() { cache= NULL; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_in_optimizer>(thd, mem_root, this); } }; @@ -498,6 +510,17 @@ public: return add_key_fields_optimize_op(join, key_fields, and_level, usable_tables, sargables, false); } + Item *build_clone(THD *thd, MEM_ROOT *mem_root) + { + Item_bool_rowready_func2 *clone= + (Item_bool_rowready_func2 *) Item_func::build_clone(thd, mem_root); + if (clone) + { + clone->cmp.comparators= 0; + } + return clone; + } + }; /** @@ -520,6 +543,8 @@ public: Item_args::propagate_equal_fields(thd, Context_boolean(), cond); return this; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_xor>(thd, mem_root, this); } }; class Item_func_not :public Item_bool_func @@ -536,6 +561,8 @@ public: Item *neg_transformer(THD *thd); bool fix_fields(THD *, Item **); virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_not>(thd, mem_root, this); } }; class Item_maxmin_subselect; @@ -583,6 +610,8 @@ public: void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, table_map usable_tables, SARGABLE_PARAM **sargables); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_trig_cond>(thd, mem_root, this); } }; class Item_func_not_all :public Item_func_not @@ -658,6 +687,8 @@ public: uint in_equality_no; virtual uint exists2in_reserved_items() { return 1; }; friend class Arg_comparator; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_eq>(thd, mem_root, this); } }; class Item_func_equal :public Item_bool_rowready_func2 @@ -680,6 +711,8 @@ public: return add_key_fields_optimize_op(join, key_fields, and_level, usable_tables, sargables, true); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_equal>(thd, mem_root, this); } }; @@ -694,6 +727,8 @@ public: cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return ">="; } Item *negated_item(THD *thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_ge>(thd, mem_root, this); } }; @@ -708,6 +743,8 @@ public: cond_result eq_cmp_result() const { return COND_FALSE; } const char *func_name() const { return ">"; } Item *negated_item(THD *thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_gt>(thd, mem_root, this); } }; @@ -722,6 +759,8 @@ public: cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "<="; } Item *negated_item(THD *thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_le>(thd, mem_root, this); } }; @@ -736,6 +775,8 @@ public: cond_result eq_cmp_result() const { return COND_FALSE; } const char *func_name() const { return "<"; } Item *negated_item(THD *thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_lt>(thd, mem_root, this); } }; @@ -759,6 +800,8 @@ public: Item *negated_item(THD *thd); void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, table_map usable_tables, SARGABLE_PARAM **sargables); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_ne>(thd, mem_root, this); } }; @@ -839,6 +882,8 @@ public: cond); return this; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_between>(thd, mem_root, this); } }; @@ -857,6 +902,8 @@ public: agg_arg_charsets_for_comparison(cmp_collation, args, 2); fix_char_length(2); // returns "1" or "0" or "-1" } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_strcmp>(thd, mem_root, this); } }; @@ -887,6 +934,8 @@ public: str->append(func_name()); print_args(str, 0, query_type); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_interval>(thd, mem_root, this); } }; @@ -909,6 +958,8 @@ public: } const char *func_name() const { return "coalesce"; } table_map not_null_tables() const { return 0; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_coalesce>(thd, mem_root, this); } }; @@ -958,6 +1009,8 @@ public: { return Item_func_case_abbreviation2::decimal_precision2(args); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_ifnull>(thd, mem_root, this); } }; @@ -981,6 +1034,8 @@ public: const char *func_name() const { return "if"; } bool eval_not_null_tables(uchar *opt_arg); void fix_after_pullout(st_select_lex *new_parent, Item **ref); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_if>(thd, mem_root, this); } private: void cache_type_info(Item *source); }; @@ -1047,6 +1102,8 @@ public: cond, &args[2]); return this; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_nullif>(thd, mem_root, this); } }; @@ -1230,7 +1287,6 @@ public: item_dec->set_decimal_value(dec); } Item_result result_type() { return DECIMAL_RESULT; } - }; @@ -1488,6 +1544,19 @@ public: CHARSET_INFO *compare_collation() const { return cmp_collation.collation; } void cleanup(); Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_case>(thd, mem_root, this); } + Item *build_clone(THD *thd, MEM_ROOT *mem_root) + { + Item_func_case *clone= (Item_func_case *) Item_func::build_clone(thd, mem_root); + if (clone) + { + clone->case_item= 0; + clone->arg_buffer= 0; + bzero(&clone->cmp_items, sizeof(cmp_items)); + } + return clone; + } }; /* @@ -1584,6 +1653,18 @@ public: bool eval_not_null_tables(uchar *opt_arg); void fix_after_pullout(st_select_lex *new_parent, Item **ref); bool count_sargable_conds(uchar *arg); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_in>(thd, mem_root, this); } + Item *build_clone(THD *thd, MEM_ROOT *mem_root) + { + Item_func_in *clone= (Item_func_in *) Item_func::build_clone(thd, mem_root); + if (clone) + { + clone->array= 0; + bzero(&clone->cmp_items, sizeof(cmp_items)); + } + return clone; + } }; class cmp_item_row :public cmp_item @@ -1678,6 +1759,8 @@ public: bool top_level); table_map not_null_tables() const { return 0; } Item *neg_transformer(THD *thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_isnull>(thd, mem_root, this); } }; /* Functions used by HAVING for rewriting IN subquery */ @@ -1723,6 +1806,8 @@ public: Item *neg_transformer(THD *thd); virtual void print(String *str, enum_query_type query_type); void top_level_item() { abort_on_null=1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_isnotnull>(thd, mem_root, this); } }; @@ -1862,6 +1947,9 @@ public: void cleanup(); bool find_selective_predicates_list_processor(uchar *arg); + + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_like>(thd, mem_root, this); } }; @@ -1967,6 +2055,8 @@ public: longlong val_int(); void fix_length_and_dec(); const char *func_name() const { return "regexp"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_regex>(thd, mem_root, this); } virtual inline void print(String *str, enum_query_type query_type) { @@ -1994,6 +2084,8 @@ public: longlong val_int(); void fix_length_and_dec(); const char *func_name() const { return "regexp_instr"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_regexp_instr>(thd, mem_root, this); } }; @@ -2071,6 +2163,7 @@ public: Item *compile(THD *thd, Item_analyzer analyzer, uchar **arg_p, Item_transformer transformer, uchar *arg_t); bool eval_not_null_tables(uchar *opt_arg); + Item *build_clone(THD *thd, MEM_ROOT *mem_root); }; template <template<class> class LI, class T> class Item_equal_iterator; @@ -2243,6 +2336,7 @@ public: void set_context_field(Item_field *ctx_field) { context_field= ctx_field; } void set_link_equal_fields(bool flag) { link_equal_fields= flag; } + Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; } friend class Item_equal_fields_iterator; bool count_sargable_conds(uchar *arg); friend class Item_equal_iterator<List_iterator_fast,Item>; @@ -2388,6 +2482,8 @@ public: void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, table_map usable_tables, SARGABLE_PARAM **sargables); SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_cond_and>(thd, mem_root, this); } }; inline bool is_cond_and(Item *item) @@ -2412,6 +2508,8 @@ public: table_map not_null_tables() const { return and_tables_cache; } Item *copy_andor_structure(THD *thd); Item *neg_transformer(THD *thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_cond_or>(thd, mem_root, this); } }; class Item_func_dyncol_check :public Item_bool_func @@ -2420,6 +2518,8 @@ public: Item_func_dyncol_check(THD *thd, Item *str): Item_bool_func(thd, str) {} longlong val_int(); const char *func_name() const { return "column_check"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_dyncol_check>(thd, mem_root, this); } }; class Item_func_dyncol_exists :public Item_bool_func @@ -2429,6 +2529,8 @@ public: Item_bool_func(thd, str, num) {} longlong val_int(); const char *func_name() const { return "column_exists"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_dyncol_exists>(thd, mem_root, this); } }; inline bool is_cond_or(Item *item) diff --git a/sql/item_func.cc b/sql/item_func.cc index 57bd004cf88..193575f44f4 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6984,3 +6984,6 @@ void Item_func_last_value::fix_length_and_dec() Type_std_attributes::set(last_value); maybe_null= last_value->maybe_null; } + + + diff --git a/sql/item_func.h b/sql/item_func.h index 5c21535adbe..9cd5aea37fa 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -613,6 +613,8 @@ public: bool fix_fields(THD *thd, Item **ref); longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } bool check_vcol_func_processor(uchar *int_arg) { return TRUE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_connection_id>(thd, mem_root, this); } }; @@ -633,6 +635,8 @@ public: } virtual void print(String *str, enum_query_type query_type); uint decimal_precision() const { return args[0]->decimal_precision(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_signed>(thd, mem_root, this); } }; @@ -646,6 +650,8 @@ public: const char *func_name() const { return "cast_as_unsigned"; } longlong val_int(); virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_unsigned>(thd, mem_root, this); } }; @@ -669,6 +675,8 @@ public: void fix_length_and_dec() {} const char *func_name() const { return "decimal_typecast"; } virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_decimal_typecast>(thd, mem_root, this); } }; @@ -686,6 +694,8 @@ public: void fix_length_and_dec() { maybe_null= 1; } const char *func_name() const { return "double_typecast"; } virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_double_typecast>(thd, mem_root, this); } }; @@ -709,6 +719,8 @@ public: longlong int_op(); double real_op(); my_decimal *decimal_op(my_decimal *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_plus>(thd, mem_root, this); } }; class Item_func_minus :public Item_func_additive_op @@ -721,6 +733,8 @@ public: double real_op(); my_decimal *decimal_op(my_decimal *); void fix_length_and_dec(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_minus>(thd, mem_root, this); } }; @@ -736,6 +750,8 @@ public: void result_precision(); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_mul>(thd, mem_root, this); } }; @@ -750,6 +766,8 @@ public: const char *func_name() const { return "/"; } void fix_length_and_dec(); void result_precision(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_div>(thd, mem_root, this); } }; @@ -769,6 +787,8 @@ public: bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_int_div>(thd, mem_root, this); } }; @@ -784,6 +804,8 @@ public: void fix_length_and_dec(); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_mod>(thd, mem_root, this); } }; @@ -800,6 +822,8 @@ public: uint decimal_precision() const { return args[0]->decimal_precision(); } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_neg>(thd, mem_root, this); } }; @@ -814,6 +838,8 @@ public: void fix_length_and_dec(); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_abs>(thd, mem_root, this); } }; // A class to handle logarithmic and trigonometric functions @@ -836,6 +862,8 @@ public: Item_func_exp(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "exp"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_exp>(thd, mem_root, this); } }; @@ -845,6 +873,8 @@ public: Item_func_ln(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "ln"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_ln>(thd, mem_root, this); } }; @@ -855,6 +885,8 @@ public: Item_func_log(THD *thd, Item *a, Item *b): Item_dec_func(thd, a, b) {} double val_real(); const char *func_name() const { return "log"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_log>(thd, mem_root, this); } }; @@ -864,6 +896,8 @@ public: Item_func_log2(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "log2"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_log2>(thd, mem_root, this); } }; @@ -873,6 +907,8 @@ public: Item_func_log10(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "log10"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_log10>(thd, mem_root, this); } }; @@ -882,6 +918,8 @@ public: Item_func_sqrt(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "sqrt"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_sqrt>(thd, mem_root, this); } }; @@ -891,6 +929,8 @@ public: Item_func_pow(THD *thd, Item *a, Item *b): Item_dec_func(thd, a, b) {} double val_real(); const char *func_name() const { return "pow"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_pow>(thd, mem_root, this); } }; @@ -900,6 +940,8 @@ public: Item_func_acos(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "acos"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_acos>(thd, mem_root, this); } }; class Item_func_asin :public Item_dec_func @@ -908,6 +950,8 @@ public: Item_func_asin(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "asin"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_asin>(thd, mem_root, this); } }; class Item_func_atan :public Item_dec_func @@ -917,6 +961,8 @@ public: Item_func_atan(THD *thd, Item *a, Item *b): Item_dec_func(thd, a, b) {} double val_real(); const char *func_name() const { return "atan"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_atan>(thd, mem_root, this); } }; class Item_func_cos :public Item_dec_func @@ -925,6 +971,8 @@ public: Item_func_cos(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "cos"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_cos>(thd, mem_root, this); } }; class Item_func_sin :public Item_dec_func @@ -933,6 +981,8 @@ public: Item_func_sin(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "sin"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_sin>(thd, mem_root, this); } }; class Item_func_tan :public Item_dec_func @@ -941,6 +991,8 @@ public: Item_func_tan(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "tan"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_tan>(thd, mem_root, this); } }; class Item_func_cot :public Item_dec_func @@ -949,6 +1001,8 @@ public: Item_func_cot(THD *thd, Item *a): Item_dec_func(thd, a) {} double val_real(); const char *func_name() const { return "cot"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_cot>(thd, mem_root, this); } }; class Item_func_integer :public Item_int_func @@ -977,6 +1031,8 @@ public: my_decimal *decimal_op(my_decimal *); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_ceiling>(thd, mem_root, this); } }; @@ -990,6 +1046,8 @@ public: my_decimal *decimal_op(my_decimal *); bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_floor>(thd, mem_root, this); } }; /* This handles round and truncate */ @@ -1005,6 +1063,8 @@ public: longlong int_op(); my_decimal *decimal_op(my_decimal *); void fix_length_and_dec(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_round>(thd, mem_root, this); } }; @@ -1026,6 +1086,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_rand>(thd, mem_root, this); } private: void seed_random (Item * val); }; @@ -1037,6 +1099,8 @@ public: Item_func_sign(THD *thd, Item *a): Item_int_func(thd, a) {} const char *func_name() const { return "sign"; } longlong val_int(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_sign>(thd, mem_root, this); } }; @@ -1052,6 +1116,8 @@ public: const char *func_name() const { return name; } void fix_length_and_dec() { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_units>(thd, mem_root, this); } }; @@ -1088,6 +1154,8 @@ class Item_func_min :public Item_func_min_max public: Item_func_min(THD *thd, List<Item> &list): Item_func_min_max(thd, list, 1) {} const char *func_name() const { return "least"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_min>(thd, mem_root, this); } }; class Item_func_max :public Item_func_min_max @@ -1095,6 +1163,8 @@ class Item_func_max :public Item_func_min_max public: Item_func_max(THD *thd, List<Item> &list): Item_func_min_max(thd, list, -1) {} const char *func_name() const { return "greatest"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_max>(thd, mem_root, this); } }; @@ -1127,6 +1197,8 @@ public: /* The item could be a NULL constant. */ null_value= args[0]->is_null(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_rollup_const>(thd, mem_root, this); } }; @@ -1138,6 +1210,8 @@ public: longlong val_int(); const char *func_name() const { return "length"; } void fix_length_and_dec() { max_length=10; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_length>(thd, mem_root, this); } }; class Item_func_bit_length :public Item_func_length @@ -1147,6 +1221,8 @@ public: longlong val_int() { DBUG_ASSERT(fixed == 1); return Item_func_length::val_int()*8; } const char *func_name() const { return "bit_length"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_bit_length>(thd, mem_root, this); } }; class Item_func_char_length :public Item_int_func @@ -1157,6 +1233,8 @@ public: longlong val_int(); const char *func_name() const { return "char_length"; } void fix_length_and_dec() { max_length=10; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_char_length>(thd, mem_root, this); } }; class Item_func_coercibility :public Item_int_func @@ -1170,6 +1248,8 @@ public: Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) { return this; } bool const_item() const { return true; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_coercibility>(thd, mem_root, this); } }; class Item_func_locate :public Item_int_func @@ -1183,6 +1263,8 @@ public: longlong val_int(); void fix_length_and_dec(); virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_locate>(thd, mem_root, this); } }; @@ -1196,6 +1278,8 @@ public: longlong val_int(); const char *func_name() const { return "field"; } void fix_length_and_dec(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_field>(thd, mem_root, this); } }; @@ -1207,6 +1291,8 @@ public: longlong val_int(); const char *func_name() const { return "ascii"; } void fix_length_and_dec() { max_length=3; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_ascii>(thd, mem_root, this); } }; class Item_func_ord :public Item_int_func @@ -1216,6 +1302,8 @@ public: Item_func_ord(THD *thd, Item *a): Item_int_func(thd, a) {} longlong val_int(); const char *func_name() const { return "ord"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_ord>(thd, mem_root, this); } }; class Item_func_find_in_set :public Item_int_func @@ -1230,6 +1318,8 @@ public: longlong val_int(); const char *func_name() const { return "find_in_set"; } void fix_length_and_dec(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_find_in_set>(thd, mem_root, this); } }; /* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */ @@ -1253,6 +1343,8 @@ public: Item_func_bit_or(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {} longlong val_int(); const char *func_name() const { return "|"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_bit_or>(thd, mem_root, this); } }; class Item_func_bit_and :public Item_func_bit @@ -1261,6 +1353,8 @@ public: Item_func_bit_and(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {} longlong val_int(); const char *func_name() const { return "&"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_bit_and>(thd, mem_root, this); } }; class Item_func_bit_count :public Item_int_func @@ -1270,6 +1364,8 @@ public: longlong val_int(); const char *func_name() const { return "bit_count"; } void fix_length_and_dec() { max_length=2; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_bit_count>(thd, mem_root, this); } }; class Item_func_shift_left :public Item_func_bit @@ -1278,6 +1374,8 @@ public: Item_func_shift_left(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {} longlong val_int(); const char *func_name() const { return "<<"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_shift_left>(thd, mem_root, this); } }; class Item_func_shift_right :public Item_func_bit @@ -1286,6 +1384,8 @@ public: Item_func_shift_right(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {} longlong val_int(); const char *func_name() const { return ">>"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_shift_right>(thd, mem_root, this); } }; class Item_func_bit_neg :public Item_func_bit @@ -1299,6 +1399,8 @@ public: { Item_func::print(str, query_type); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_bit_neg>(thd, mem_root, this); } }; @@ -1321,6 +1423,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_last_insert_id>(thd, mem_root, this); } }; @@ -1338,6 +1442,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_benchmark>(thd, mem_root, this); } }; @@ -1360,6 +1466,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_sleep>(thd, mem_root, this); } }; @@ -1479,6 +1587,8 @@ class Item_func_udf_float :public Item_udf_func String *val_str(String *str); enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } void fix_length_and_dec() { fix_num_length_and_dec(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_udf_float>(thd, mem_root, this); } }; @@ -1496,6 +1606,8 @@ public: enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } void fix_length_and_dec() { decimals= 0; max_length= 21; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_udf_int>(thd, mem_root, this); } }; @@ -1513,6 +1625,8 @@ public: enum Item_result result_type () const { return DECIMAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; } void fix_length_and_dec() { fix_num_length_and_dec(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_udf_decimal>(thd, mem_root, this); } }; @@ -1551,6 +1665,8 @@ public: enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return string_field_type(); } void fix_length_and_dec(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_udf_str>(thd, mem_root, this); } }; #else /* Dummy functions to get sql_yacc.cc compiled */ @@ -1626,6 +1742,8 @@ class Item_func_get_lock :public Item_int_func { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_get_lock>(thd, mem_root, this); } }; class Item_func_release_lock :public Item_int_func @@ -1646,6 +1764,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_release_lock>(thd, mem_root, this); } }; /* replication functions */ @@ -1666,6 +1786,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_master_pos_wait>(thd, mem_root, this); } }; @@ -1682,6 +1804,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_master_gtid_wait>(thd, mem_root, this); } }; @@ -1795,6 +1919,8 @@ public: bool register_field_in_bitmap(uchar *arg); bool set_entry(THD *thd, bool create_if_not_exists); void cleanup(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_set_user_var>(thd, mem_root, this); } }; @@ -1821,6 +1947,8 @@ public: table_map used_tables() const { return const_item() ? 0 : RAND_TABLE_BIT; } bool eq(const Item *item, bool binary_cmp) const; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_get_user_var>(thd, mem_root, this); } private: bool set_value(THD *thd, sp_rcontext *ctx, Item **it); @@ -1860,6 +1988,8 @@ public: void set_null_value(CHARSET_INFO* cs); void set_value(const char *str, uint length, CHARSET_INFO* cs); enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_user_var_as_out_param>(thd, mem_root, this); } }; @@ -1914,6 +2044,8 @@ public: void cleanup(); bool check_vcol_func_processor(uchar *int_arg) { return TRUE;} + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_get_system_var>(thd, mem_root, this); } }; @@ -1964,6 +2096,9 @@ public: /* TODO: consider adding in support for the MATCH-based virtual columns */ return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_match>(thd, mem_root, this); } + Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; } private: /** Check whether storage engine for given table, @@ -2008,6 +2143,8 @@ public: Item_func_bit_xor(THD *thd, Item *a, Item *b): Item_func_bit(thd, a, b) {} longlong val_int(); const char *func_name() const { return "^"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_bit_xor>(thd, mem_root, this); } }; class Item_func_is_free_lock :public Item_int_func @@ -2022,6 +2159,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_is_free_lock>(thd, mem_root, this); } }; class Item_func_is_used_lock :public Item_int_func @@ -2036,6 +2175,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_is_used_lock>(thd, mem_root, this); } }; /* For type casts */ @@ -2087,6 +2228,8 @@ public: return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_row_count>(thd, mem_root, this); } }; @@ -2217,6 +2360,15 @@ public: { return TRUE; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_sp>(thd, mem_root, this); } + Item *build_clone(THD *thd, MEM_ROOT *mem_root) + { + Item_func_sp *clone= (Item_func_sp *) Item_func::build_clone(thd, mem_root); + if (clone) + clone->sp_result_field= NULL; + return clone; + } }; @@ -2231,6 +2383,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_found_rows>(thd, mem_root, this); } }; @@ -2248,6 +2402,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_uuid_short>(thd, mem_root, this); } }; @@ -2273,6 +2429,8 @@ public: Item_func::update_used_tables(); maybe_null= last_value->maybe_null; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_last_value>(thd, mem_root, this); } }; diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 56e2a729924..9a2a49f633b 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -51,6 +51,8 @@ public: Item_geometry_func(thd, a, srid) {} const char *func_name() const { return "st_geometryfromtext"; } String *val_str(String *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_geometry_from_text>(thd, mem_root, this); } }; class Item_func_geometry_from_wkb: public Item_geometry_func @@ -61,6 +63,8 @@ public: Item_geometry_func(thd, a, srid) {} const char *func_name() const { return "st_geometryfromwkb"; } String *val_str(String *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_geometry_from_wkb>(thd, mem_root, this); } }; class Item_func_as_wkt: public Item_str_ascii_func @@ -70,6 +74,8 @@ public: const char *func_name() const { return "st_astext"; } String *val_str_ascii(String *); void fix_length_and_dec(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_as_wkt>(thd, mem_root, this); } }; class Item_func_as_wkb: public Item_geometry_func @@ -79,6 +85,8 @@ public: const char *func_name() const { return "st_aswkb"; } String *val_str(String *); enum_field_types field_type() const { return MYSQL_TYPE_BLOB; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_as_wkb>(thd, mem_root, this); } }; class Item_func_geometry_type: public Item_str_ascii_func @@ -93,6 +101,8 @@ public: fix_length_and_charset(20, default_charset()); maybe_null= 1; }; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_geometry_type>(thd, mem_root, this); } }; @@ -125,6 +135,8 @@ public: {} const char *func_name() const { return "st_convexhull"; } String *val_str(String *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_convexhull>(thd, mem_root, this); } }; @@ -135,6 +147,8 @@ public: const char *func_name() const { return "st_centroid"; } String *val_str(String *); Field::geometry_type get_geometry_type() const; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_centroid>(thd, mem_root, this); } }; class Item_func_envelope: public Item_geometry_func @@ -144,6 +158,8 @@ public: const char *func_name() const { return "st_envelope"; } String *val_str(String *); Field::geometry_type get_geometry_type() const; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_envelope>(thd, mem_root, this); } }; @@ -175,6 +191,8 @@ public: Item_func_boundary(THD *thd, Item *a): Item_geometry_func(thd, a) {} const char *func_name() const { return "st_boundary"; } String *val_str(String *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_boundary>(thd, mem_root, this); } }; @@ -187,6 +205,8 @@ public: const char *func_name() const { return "point"; } String *val_str(String *); Field::geometry_type get_geometry_type() const; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_point>(thd, mem_root, this); } }; class Item_func_spatial_decomp: public Item_geometry_func @@ -211,6 +231,8 @@ public: } } String *val_str(String *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_spatial_decomp>(thd, mem_root, this); } }; class Item_func_spatial_decomp_n: public Item_geometry_func @@ -235,6 +257,8 @@ public: } } String *val_str(String *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_spatial_decomp_n>(thd, mem_root, this); } }; class Item_func_spatial_collection: public Item_geometry_func @@ -268,6 +292,8 @@ public: } const char *func_name() const { return "st_multipoint"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_spatial_collection>(thd, mem_root, this); } }; @@ -299,6 +325,7 @@ public: return add_key_fields_optimize_op(join, key_fields, and_level, usable_tables, sargables, false); } + Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; } }; @@ -310,6 +337,8 @@ public: { } longlong val_int(); const char *func_name() const; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_spatial_mbr_rel>(thd, mem_root, this); } }; @@ -324,6 +353,8 @@ public: { } longlong val_int(); const char *func_name() const; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_spatial_precise_rel>(thd, mem_root, this); } }; @@ -339,6 +370,8 @@ public: { } longlong val_int(); const char *func_name() const { return "st_relate"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_spatial_relate>(thd, mem_root, this); } }; @@ -368,6 +401,8 @@ public: { Item_func::print(str, query_type); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_spatial_operation>(thd, mem_root, this); } }; @@ -419,6 +454,8 @@ public: Item_geometry_func(thd, obj, distance) {} const char *func_name() const { return "st_buffer"; } String *val_str(String *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_buffer>(thd, mem_root, this); } }; @@ -429,6 +466,8 @@ public: longlong val_int(); const char *func_name() const { return "st_isempty"; } void fix_length_and_dec() { maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_isempty>(thd, mem_root, this); } }; class Item_func_issimple: public Item_int_func @@ -443,6 +482,8 @@ public: const char *func_name() const { return "st_issimple"; } void fix_length_and_dec() { decimals=0; max_length=2; } uint decimal_precision() const { return 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_issimple>(thd, mem_root, this); } }; class Item_func_isclosed: public Item_int_func @@ -453,6 +494,8 @@ public: const char *func_name() const { return "st_isclosed"; } void fix_length_and_dec() { decimals=0; max_length=2; } uint decimal_precision() const { return 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_isclosed>(thd, mem_root, this); } }; class Item_func_isring: public Item_func_issimple @@ -461,6 +504,8 @@ public: Item_func_isring(THD *thd, Item *a): Item_func_issimple(thd, a) {} longlong val_int(); const char *func_name() const { return "st_isring"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_isring>(thd, mem_root, this); } }; class Item_func_dimension: public Item_int_func @@ -471,6 +516,8 @@ public: longlong val_int(); const char *func_name() const { return "st_dimension"; } void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_dimension>(thd, mem_root, this); } }; class Item_func_x: public Item_real_func @@ -485,6 +532,8 @@ public: Item_real_func::fix_length_and_dec(); maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_x>(thd, mem_root, this); } }; @@ -500,6 +549,8 @@ public: Item_real_func::fix_length_and_dec(); maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_y>(thd, mem_root, this); } }; @@ -511,6 +562,8 @@ public: longlong val_int(); const char *func_name() const { return "st_numgeometries"; } void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_numgeometries>(thd, mem_root, this); } }; @@ -522,6 +575,8 @@ public: longlong val_int(); const char *func_name() const { return "st_numinteriorrings"; } void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_numinteriorring>(thd, mem_root, this); } }; @@ -533,6 +588,8 @@ public: longlong val_int(); const char *func_name() const { return "st_numpoints"; } void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_numpoints>(thd, mem_root, this); } }; @@ -548,6 +605,8 @@ public: Item_real_func::fix_length_and_dec(); maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_area>(thd, mem_root, this); } }; @@ -563,6 +622,8 @@ public: Item_real_func::fix_length_and_dec(); maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_glength>(thd, mem_root, this); } }; @@ -574,6 +635,8 @@ public: longlong val_int(); const char *func_name() const { return "srid"; } void fix_length_and_dec() { max_length= 10; maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_srid>(thd, mem_root, this); } }; @@ -588,6 +651,8 @@ public: Item_func_distance(THD *thd, Item *a, Item *b): Item_real_func(thd, a, b) {} double val_real(); const char *func_name() const { return "st_distance"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_distance>(thd, mem_root, this); } }; @@ -602,6 +667,8 @@ public: const char *func_name() const { return "st_pointonsurface"; } String *val_str(String *); Field::geometry_type get_geometry_type() const; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_pointonsurface>(thd, mem_root, this); } }; @@ -613,6 +680,8 @@ class Item_func_gis_debug: public Item_int_func { null_value= false; } const char *func_name() const { return "st_gis_debug"; } longlong val_int(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_gis_debug>(thd, mem_root, this); } }; #endif diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h index 82a4405df1e..9dcb3ab0db7 100644 --- a/sql/item_inetfunc.h +++ b/sql/item_inetfunc.h @@ -37,6 +37,8 @@ public: maybe_null= 1; unsigned_flag= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_inet_aton>(thd, mem_root, this); } }; @@ -57,6 +59,8 @@ public: fix_length_and_charset(3 * 8 + 7, default_charset()); maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_inet_ntoa>(thd, mem_root, this); } }; @@ -123,6 +127,8 @@ public: fix_length_and_charset(16, &my_charset_bin); maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_inet6_aton>(thd, mem_root, this); } protected: virtual bool calc_value(String *arg, String *buffer); @@ -155,6 +161,8 @@ public: maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_inet6_ntoa>(thd, mem_root, this); } protected: virtual bool calc_value(String *arg, String *buffer); @@ -175,6 +183,8 @@ public: public: virtual const char *func_name() const { return "is_ipv4"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_is_ipv4>(thd, mem_root, this); } protected: virtual bool calc_value(const String *arg); @@ -195,6 +205,8 @@ public: public: virtual const char *func_name() const { return "is_ipv6"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_is_ipv6>(thd, mem_root, this); } protected: virtual bool calc_value(const String *arg); @@ -215,6 +227,8 @@ public: public: virtual const char *func_name() const { return "is_ipv4_compat"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_is_ipv4_compat>(thd, mem_root, this); } protected: virtual bool calc_value(const String *arg); @@ -235,6 +249,8 @@ public: public: virtual const char *func_name() const { return "is_ipv4_mapped"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_is_ipv4_mapped>(thd, mem_root, this); } protected: virtual bool calc_value(const String *arg); diff --git a/sql/item_row.cc b/sql/item_row.cc index 56d73f7b759..24516a568c8 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -160,3 +160,21 @@ void Item_row::bring_value() for (uint i= 0; i < arg_count; i++) args[i]->bring_value(); } + + +Item* Item_row::build_clone(THD *thd, MEM_ROOT *mem_root) +{ + Item_row *copy= (Item_row *) get_copy(thd, mem_root); + if (!copy) + return 0; + copy->args= (Item**) alloc_root(mem_root, sizeof(Item*) * arg_count); + for (uint i= 0; i < arg_count; i++) + { + Item *arg_clone= args[i]->build_clone(thd, mem_root); + if (!arg_clone) + return 0; + copy->args[i]= arg_clone; + } + return copy; +} + diff --git a/sql/item_row.h b/sql/item_row.h index ddb6f0835f2..de8a4c991fc 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -120,6 +120,9 @@ public: bool null_inside() { return with_null; }; void bring_value(); bool check_vcol_func_processor(uchar *int_arg) {return FALSE; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_row>(thd, mem_root, this); } + Item *build_clone(THD *thd, MEM_ROOT *mem_root); }; #endif /* ITEM_ROW_INCLUDED */ diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 0ff38157c25..b20fb4e1fbc 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -105,6 +105,8 @@ public: String *val_str_ascii(String *); void fix_length_and_dec(); const char *func_name() const { return "md5"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_md5>(thd, mem_root, this); } }; @@ -114,7 +116,9 @@ public: Item_func_sha(THD *thd, Item *a): Item_str_ascii_func(thd, a) {} String *val_str_ascii(String *); void fix_length_and_dec(); - const char *func_name() const { return "sha"; } + const char *func_name() const { return "sha"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_sha>(thd, mem_root, this); } }; class Item_func_sha2 :public Item_str_ascii_func @@ -124,6 +128,8 @@ public: String *val_str_ascii(String *); void fix_length_and_dec(); const char *func_name() const { return "sha2"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_sha2>(thd, mem_root, this); } }; class Item_func_to_base64 :public Item_str_ascii_func @@ -134,6 +140,8 @@ public: String *val_str_ascii(String *); void fix_length_and_dec(); const char *func_name() const { return "to_base64"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_to_base64>(thd, mem_root, this); } }; class Item_func_from_base64 :public Item_str_func @@ -144,6 +152,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "from_base64"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_from_base64>(thd, mem_root, this); } }; #include <my_crypt.h> @@ -167,6 +177,8 @@ public: Item_aes_crypt(thd, a, b) {} void fix_length_and_dec(); const char *func_name() const { return "aes_encrypt"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_aes_encrypt>(thd, mem_root, this); } }; class Item_func_aes_decrypt :public Item_aes_crypt @@ -176,6 +188,8 @@ public: Item_aes_crypt(thd, a, b) {} void fix_length_and_dec(); const char *func_name() const { return "aes_decrypt"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_aes_decrypt>(thd, mem_root, this); } }; @@ -188,6 +202,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "concat"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_concat>(thd, mem_root, this); } }; class Item_func_decode_histogram :public Item_str_func @@ -204,6 +220,8 @@ public: maybe_null= 1; } const char *func_name() const { return "decode_histogram"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_decode_histogram>(thd, mem_root, this); } }; class Item_func_concat_ws :public Item_str_func @@ -215,6 +233,8 @@ public: void fix_length_and_dec(); const char *func_name() const { return "concat_ws"; } table_map not_null_tables() const { return 0; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_concat_ws>(thd, mem_root, this); } }; class Item_func_reverse :public Item_str_func @@ -225,6 +245,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "reverse"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_reverse>(thd, mem_root, this); } }; @@ -237,6 +259,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "replace"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_replace>(thd, mem_root, this); } }; @@ -260,6 +284,8 @@ public: String *val_str(String *str); void fix_length_and_dec(); const char *func_name() const { return "regexp_replace"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_regexp_replace>(thd, mem_root, this); } }; @@ -280,6 +306,8 @@ public: String *val_str(String *str); void fix_length_and_dec(); const char *func_name() const { return "regexp_substr"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_regexp_substr>(thd, mem_root, this); } }; @@ -293,6 +321,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "insert"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_insert>(thd, mem_root, this); } }; @@ -314,6 +344,8 @@ public: Item_func_lcase(THD *thd, Item *item): Item_str_conv(thd, item) {} const char *func_name() const { return "lcase"; } void fix_length_and_dec(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_lcase>(thd, mem_root, this); } }; class Item_func_ucase :public Item_str_conv @@ -322,6 +354,8 @@ public: Item_func_ucase(THD *thd, Item *item): Item_str_conv(thd, item) {} const char *func_name() const { return "ucase"; } void fix_length_and_dec(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_ucase>(thd, mem_root, this); } }; @@ -333,6 +367,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "left"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_left>(thd, mem_root, this); } }; @@ -344,6 +380,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "right"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_right>(thd, mem_root, this); } }; @@ -356,6 +394,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "substr"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_substr>(thd, mem_root, this); } }; @@ -368,6 +408,9 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "substring_index"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_substr_index>(thd, mem_root, this); } + }; @@ -399,6 +442,8 @@ public: const char *func_name() const { return "trim"; } virtual void print(String *str, enum_query_type query_type); virtual const char *mode_name() const { return "both"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_trim>(thd, mem_root, this); } }; @@ -410,6 +455,8 @@ public: String *val_str(String *); const char *func_name() const { return "ltrim"; } const char *mode_name() const { return "leading"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_ltrim>(thd, mem_root, this); } }; @@ -421,6 +468,8 @@ public: String *val_str(String *); const char *func_name() const { return "rtrim"; } const char *mode_name() const { return "trailing"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_rtrim>(thd, mem_root, this); } }; @@ -458,6 +507,8 @@ public: "password" : "old_password"); } static char *alloc(THD *thd, const char *password, size_t pass_len, enum PW_Alg al); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_password>(thd, mem_root, this); } }; @@ -476,6 +527,8 @@ public: max_length = args[0]->max_length + 9; } const char *func_name() const { return "des_encrypt"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_des_encrypt>(thd, mem_root, this); } }; class Item_func_des_decrypt :public Item_str_func @@ -494,6 +547,8 @@ public: max_length-= 9U; } const char *func_name() const { return "des_decrypt"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_des_decrypt>(thd, mem_root, this); } }; class Item_func_encrypt :public Item_str_func @@ -521,6 +576,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_encrypt>(thd, mem_root, this); } }; #include "sql_crypt.h" @@ -539,6 +596,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "encode"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_encode>(thd, mem_root, this); } protected: virtual void crypto_transform(String *); private: @@ -552,6 +611,8 @@ class Item_func_decode :public Item_func_encode public: Item_func_decode(THD *thd, Item *a, Item *seed_arg): Item_func_encode(thd, a, seed_arg) {} const char *func_name() const { return "decode"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_decode>(thd, mem_root, this); } protected: void crypto_transform(String *); }; @@ -592,6 +653,8 @@ public: } const char *func_name() const { return "database"; } const char *fully_qualified_func_name() const { return "database()"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_database>(thd, mem_root, this); } }; @@ -622,6 +685,8 @@ public: { return save_str_value_in_field(field, &str_value); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_user>(thd, mem_root, this); } }; @@ -657,6 +722,8 @@ public: DBUG_ASSERT(fixed == 1); return (null_value ? 0 : &str_value); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_current_role>(thd, mem_root, this); } }; @@ -668,6 +735,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "soundex"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_soundex>(thd, mem_root, this); } }; @@ -680,6 +749,8 @@ public: String *val_str(String *str); void fix_length_and_dec(); const char *func_name() const { return "elt"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_elt>(thd, mem_root, this); } }; @@ -692,6 +763,8 @@ public: String *val_str(String *str); void fix_length_and_dec(); const char *func_name() const { return "make_set"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_make_set>(thd, mem_root, this); } }; @@ -710,6 +783,8 @@ public: void fix_length_and_dec(); const char *func_name() const { return "format"; } virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_format>(thd, mem_root, this); } }; @@ -727,6 +802,8 @@ public: max_length= arg_count * 4; } const char *func_name() const { return "char"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_char>(thd, mem_root, this); } }; @@ -739,6 +816,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "repeat"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_repeat>(thd, mem_root, this); } }; @@ -749,6 +828,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "space"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_space>(thd, mem_root, this); } }; @@ -761,6 +842,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "binlog_gtid_pos"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_binlog_gtid_pos>(thd, mem_root, this); } }; @@ -773,6 +856,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "rpad"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_rpad>(thd, mem_root, this); } }; @@ -785,6 +870,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "lpad"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_lpad>(thd, mem_root, this); } }; @@ -801,6 +888,8 @@ public: max_length=64; maybe_null= 1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_conv>(thd, mem_root, this); } }; @@ -818,6 +907,8 @@ public: decimals=0; fix_char_length(args[0]->max_length * 2); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_hex>(thd, mem_root, this); } }; class Item_func_unhex :public Item_str_func @@ -837,6 +928,8 @@ public: decimals=0; max_length=(1+args[0]->max_length)/2; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_unhex>(thd, mem_root, this); } }; @@ -867,6 +960,8 @@ public: Item_func_like_range_min(THD *thd, Item *a, Item *b): Item_func_like_range(thd, a, b, true) { } const char *func_name() const { return "like_range_min"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_like_range_min>(thd, mem_root, this); } }; @@ -876,6 +971,8 @@ public: Item_func_like_range_max(THD *thd, Item *a, Item *b): Item_func_like_range(thd, a, b, false) { } const char *func_name() const { return "like_range_max"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_like_range_max>(thd, mem_root, this); } }; #endif @@ -900,6 +997,8 @@ public: } virtual void print(String *str, enum_query_type query_type); const char *func_name() const { return "cast_as_binary"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_binary>(thd, mem_root, this); } }; @@ -920,6 +1019,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_load_file>(thd, mem_root, this); } }; @@ -935,6 +1036,8 @@ class Item_func_export_set: public Item_str_func String *val_str(String *str); void fix_length_and_dec(); const char *func_name() const { return "export_set"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_export_set>(thd, mem_root, this); } }; @@ -952,6 +1055,8 @@ public: 2 * collation.collation->mbmaxlen; max_length= (uint32) MY_MIN(max_result_length, MAX_BLOB_WIDTH); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_quote>(thd, mem_root, this); } }; class Item_func_conv_charset :public Item_str_func @@ -1034,6 +1139,8 @@ public: void fix_length_and_dec(); const char *func_name() const { return "convert"; } virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_conv_charset>(thd, mem_root, this); } }; class Item_func_set_collation :public Item_str_func @@ -1052,6 +1159,8 @@ public: /* this function is transparent for view updating */ return args[0]->field_for_view_update(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_set_collation>(thd, mem_root, this); } }; @@ -1079,6 +1188,8 @@ public: :Item_func_expr_str_metadata(thd, a) { } String *val_str(String *); const char *func_name() const { return "charset"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_charset>(thd, mem_root, this); } }; @@ -1089,6 +1200,8 @@ public: :Item_func_expr_str_metadata(thd, a) {} String *val_str(String *); const char *func_name() const { return "collation"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_collation>(thd, mem_root, this); } }; @@ -1121,6 +1234,8 @@ public: } Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) { return this; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_weight_string>(thd, mem_root, this); } }; class Item_func_crc32 :public Item_int_func @@ -1132,6 +1247,8 @@ public: const char *func_name() const { return "crc32"; } void fix_length_and_dec() { max_length=10; } longlong val_int(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_crc32>(thd, mem_root, this); } }; class Item_func_uncompressed_length : public Item_int_func @@ -1142,6 +1259,8 @@ public: const char *func_name() const{return "uncompressed_length";} void fix_length_and_dec() { max_length=10; maybe_null= true; } longlong val_int(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_uncompressed_length>(thd, mem_root, this); } }; #ifdef HAVE_COMPRESS @@ -1158,6 +1277,8 @@ public: void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;} const char *func_name() const{return "compress";} String *val_str(String *) ZLIB_DEPENDED_FUNCTION + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_compress>(thd, mem_root, this); } }; class Item_func_uncompress: public Item_str_func @@ -1168,6 +1289,8 @@ public: void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; } const char *func_name() const{return "uncompress";} String *val_str(String *) ZLIB_DEPENDED_FUNCTION + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_uncompress>(thd, mem_root, this); } }; @@ -1187,6 +1310,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_uuid>(thd, mem_root, this); } }; @@ -1208,6 +1333,8 @@ public: String *val_str(String *); virtual void print(String *str, enum_query_type query_type); virtual enum Functype functype() const { return DYNCOL_FUNC; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_dyncol_create>(thd, mem_root, this); } }; @@ -1220,6 +1347,8 @@ public: const char *func_name() const{ return "column_add"; } String *val_str(String *); virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_dyncol_add>(thd, mem_root, this); } }; class Item_func_dyncol_json: public Item_str_func @@ -1235,6 +1364,8 @@ public: collation.set(&my_charset_bin); decimals= 0; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_dyncol_json>(thd, mem_root, this); } }; /* @@ -1259,6 +1390,8 @@ public: bool get_dyn_value(THD *thd, DYNAMIC_COLUMN_VALUE *val, String *tmp); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_dyncol_get>(thd, mem_root, this); } }; @@ -1269,6 +1402,8 @@ public: void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; }; const char *func_name() const{ return "column_list"; } String *val_str(String *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_dyncol_list>(thd, mem_root, this); } }; #endif /* ITEM_STRFUNC_INCLUDED */ diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 58b5a948048..ab7297f51b1 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -250,6 +250,9 @@ public: } void init_expr_cache_tracker(THD *thd); + + Item* build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; } + Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; } friend class select_result_interceptor; diff --git a/sql/item_sum.h b/sql/item_sum.h index e766e69a1c5..15cfd1f5b9c 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -772,6 +772,8 @@ public: } Item *copy_or_same(THD* thd); void remove(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_sum>(thd, mem_root, this); } private: void add_helper(bool perform_removal); @@ -829,6 +831,8 @@ class Item_sum_count :public Item_sum_int return has_with_distinct() ? "count(distinct " : "count("; } Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_count>(thd, mem_root, this); } }; @@ -876,6 +880,8 @@ public: count= 0; Item_sum_sum::cleanup(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_avg>(thd, mem_root, this); } }; @@ -934,6 +940,8 @@ public: count= 0; Item_sum_num::cleanup(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_variance>(thd, mem_root, this); } }; /* @@ -953,6 +961,8 @@ class Item_sum_std :public Item_sum_variance Item *result_item(THD *thd, Field *field); const char *func_name() const { return "std("; } Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_std>(thd, mem_root, this); } }; // This class is a string or number function depending on num_func @@ -1018,6 +1028,8 @@ public: bool add(); const char *func_name() const { return "min("; } Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_min>(thd, mem_root, this); } }; @@ -1031,6 +1043,8 @@ public: bool add(); const char *func_name() const { return "max("; } Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_max>(thd, mem_root, this); } }; @@ -1105,6 +1119,8 @@ public: bool add(); const char *func_name() const { return "bit_or("; } Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_or>(thd, mem_root, this); } private: void set_bits_from_counters(); @@ -1120,6 +1136,8 @@ public: bool add(); const char *func_name() const { return "bit_and("; } Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_and>(thd, mem_root, this); } private: void set_bits_from_counters(); @@ -1133,6 +1151,8 @@ public: bool add(); const char *func_name() const { return "bit_xor("; } Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_xor>(thd, mem_root, this); } private: void set_bits_from_counters(); @@ -1191,6 +1211,8 @@ public: my_decimal *val_decimal(my_decimal *dec) { return val_decimal_from_real(dec); } String *val_str(String *str) { return val_string_from_real(str); } double val_real(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_avg_field_double>(thd, mem_root, this); } }; @@ -1210,6 +1232,8 @@ public: longlong val_int() { return val_int_from_decimal(); } String *val_str(String *str) { return val_string_from_decimal(str); } my_decimal *val_decimal(my_decimal *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_avg_field_decimal>(thd, mem_root, this); } }; @@ -1234,6 +1258,8 @@ public: { return trace_unsupported_by_check_vcol_func_processor("var_field"); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_variance_field>(thd, mem_root, this); } }; @@ -1245,6 +1271,8 @@ public: { } enum Type type() const { return FIELD_STD_ITEM; } double val_real(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_std_field>(thd, mem_root, this); } }; @@ -1332,6 +1360,8 @@ class Item_sum_udf_float :public Item_udf_sum enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } void fix_length_and_dec() { fix_num_length_and_dec(); } Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_udf_float>(thd, mem_root, this); } }; @@ -1353,6 +1383,8 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } void fix_length_and_dec() { decimals=0; max_length=21; } Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_udf_int>(thd, mem_root, this); } }; @@ -1393,6 +1425,8 @@ public: enum_field_types field_type() const { return string_field_type(); } void fix_length_and_dec(); Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_udf_str>(thd, mem_root, this); } }; @@ -1413,6 +1447,8 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; } void fix_length_and_dec() { fix_num_length_and_dec(); } Item *copy_or_same(THD* thd); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_udf_decimal>(thd, mem_root, this); } }; #else /* Dummy functions to get sql_yacc.cc compiled */ @@ -1606,6 +1642,8 @@ public: virtual void print(String *str, enum_query_type query_type); virtual bool change_context_processor(uchar *cntx) { context= (Name_resolution_context *)cntx; return FALSE; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_group_concat>(thd, mem_root, this); } }; #endif /* ITEM_SUM_INCLUDED */ diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 175f3b06c1a..0edfc4f6a82 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -53,6 +53,8 @@ public: { max_length=6*MY_CHARSET_BIN_MB_MAXLEN; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_period_add>(thd, mem_root, this); } }; @@ -67,6 +69,8 @@ public: decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_period_diff>(thd, mem_root, this); } }; @@ -90,6 +94,8 @@ public: { return !has_date_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_to_days>(thd, mem_root, this); } }; @@ -123,6 +129,8 @@ public: { return !has_date_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_to_seconds>(thd, mem_root, this); } }; @@ -144,6 +152,8 @@ public: { return !has_date_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_dayofmonth>(thd, mem_root, this); } }; @@ -178,6 +188,8 @@ public: { return !has_date_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_month>(thd, mem_root, this); } }; @@ -195,6 +207,8 @@ public: { return !has_date_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_monthname>(thd, mem_root, this); } }; @@ -216,6 +230,8 @@ public: { return !has_date_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_dayofyear>(thd, mem_root, this); } }; @@ -237,6 +253,8 @@ public: { return !has_time_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_hour>(thd, mem_root, this); } }; @@ -258,6 +276,8 @@ public: { return !has_time_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_minute>(thd, mem_root, this); } }; @@ -279,6 +299,8 @@ public: { return !has_date_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_quarter>(thd, mem_root, this); } }; @@ -300,6 +322,8 @@ public: { return !has_time_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_second>(thd, mem_root, this); } }; @@ -315,6 +339,8 @@ public: max_length=2*MY_CHARSET_BIN_MB_MAXLEN; maybe_null=1; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_week>(thd, mem_root, this); } }; class Item_func_yearweek :public Item_int_func @@ -335,6 +361,8 @@ public: { return !has_date_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_yearweek>(thd, mem_root, this); } }; @@ -358,6 +386,8 @@ public: { return !has_date_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_year>(thd, mem_root, this); } }; @@ -393,6 +423,8 @@ public: { return !has_date_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_weekday>(thd, mem_root, this); } }; class Item_func_dayname :public Item_func_weekday @@ -464,6 +496,8 @@ public: } longlong int_op(); my_decimal *decimal_op(my_decimal* buf); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_unix_timestamp>(thd, mem_root, this); } }; @@ -483,6 +517,8 @@ public: } longlong int_op(); my_decimal *decimal_op(my_decimal* buf); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_time_to_sec>(thd, mem_root, this); } }; @@ -625,6 +661,8 @@ public: Item_func_curtime_local(THD *thd, uint dec): Item_func_curtime(thd, dec) {} const char *func_name() const { return "curtime"; } virtual void store_now_in_TIME(MYSQL_TIME *now_time); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_curtime_local>(thd, mem_root, this); } }; @@ -634,6 +672,8 @@ public: Item_func_curtime_utc(THD *thd, uint dec): Item_func_curtime(thd, dec) {} const char *func_name() const { return "utc_time"; } virtual void store_now_in_TIME(MYSQL_TIME *now_time); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_curtime_utc>(thd, mem_root, this); } }; @@ -660,6 +700,8 @@ public: Item_func_curdate_local(THD *thd): Item_func_curdate(thd) {} const char *func_name() const { return "curdate"; } void store_now_in_TIME(MYSQL_TIME *now_time); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_curdate_local>(thd, mem_root, this); } }; @@ -669,6 +711,8 @@ public: Item_func_curdate_utc(THD *thd): Item_func_curdate(thd) {} const char *func_name() const { return "utc_date"; } void store_now_in_TIME(MYSQL_TIME *now_time); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_curdate_utc>(thd, mem_root, this); } }; @@ -703,6 +747,8 @@ public: const char *func_name() const { return "now"; } virtual void store_now_in_TIME(MYSQL_TIME *now_time); virtual enum Functype functype() const { return NOW_FUNC; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_now_local>(thd, mem_root, this); } }; @@ -712,6 +758,8 @@ public: Item_func_now_utc(THD *thd, uint dec): Item_func_now(thd, dec) {} const char *func_name() const { return "utc_timestamp"; } virtual void store_now_in_TIME(MYSQL_TIME *now_time); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_now_utc>(thd, mem_root, this); } }; @@ -733,6 +781,8 @@ public: maybe_null= 0; used_tables_cache|= RAND_TABLE_BIT; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_sysdate_local>(thd, mem_root, this); } }; @@ -748,6 +798,8 @@ public: { return has_date_args() || has_time_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_from_days>(thd, mem_root, this); } }; @@ -766,6 +818,8 @@ public: void fix_length_and_dec(); uint format_length(const String *format); bool eq(const Item *item, bool binary_cmp) const; + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_date_format>(thd, mem_root, this); } }; @@ -777,6 +831,8 @@ class Item_func_from_unixtime :public Item_datetimefunc const char *func_name() const { return "from_unixtime"; } void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_from_unixtime>(thd, mem_root, this); } }; @@ -811,6 +867,8 @@ class Item_func_convert_tz :public Item_datetimefunc void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); void cleanup(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_convert_tz>(thd, mem_root, this); } }; @@ -825,6 +883,8 @@ public: Item_timefunc::fix_length_and_dec(); } const char *func_name() const { return "sec_to_time"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_sec_to_time>(thd, mem_root, this); } }; @@ -842,6 +902,8 @@ public: bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); bool eq(const Item *item, bool binary_cmp) const; void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_date_add_interval>(thd, mem_root, this); } }; @@ -896,6 +958,8 @@ class Item_extract :public Item_int_func } return true; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_extract>(thd, mem_root, this); } }; @@ -919,6 +983,8 @@ public: String *val_str(String *a); void fix_length_and_dec(); void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_char_typecast>(thd, mem_root, this); } }; @@ -944,6 +1010,8 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *cast_type() const { return "date"; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_date_typecast>(thd, mem_root, this); } }; @@ -956,6 +1024,8 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *cast_type() const { return "time"; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_time_typecast>(thd, mem_root, this); } }; @@ -968,6 +1038,8 @@ public: const char *cast_type() const { return "datetime"; } enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_datetime_typecast>(thd, mem_root, this); } }; @@ -979,6 +1051,8 @@ public: const char *func_name() const { return "makedate"; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_makedate>(thd, mem_root, this); } }; @@ -995,6 +1069,8 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); void print(String *str, enum_query_type query_type); const char *func_name() const { return "add_time"; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_add_time>(thd, mem_root, this); } }; class Item_func_timediff :public Item_timefunc @@ -1009,6 +1085,8 @@ public: Item_timefunc::fix_length_and_dec(); } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_timediff>(thd, mem_root, this); } }; class Item_func_maketime :public Item_timefunc @@ -1024,6 +1102,8 @@ public: } const char *func_name() const { return "maketime"; } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_maketime>(thd, mem_root, this); } }; @@ -1044,6 +1124,8 @@ public: { return !has_time_args(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_microsecond>(thd, mem_root, this); } }; @@ -1061,6 +1143,8 @@ public: maybe_null=1; } virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_timestamp_diff>(thd, mem_root, this); } }; @@ -1085,6 +1169,8 @@ public: fix_length_and_charset(17, default_charset()); } virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_get_format>(thd, mem_root, this); } }; @@ -1103,6 +1189,8 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date); const char *func_name() const { return "str_to_date"; } void fix_length_and_dec(); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_str_to_date>(thd, mem_root, this); } }; @@ -1112,6 +1200,8 @@ public: Item_func_last_day(THD *thd, Item *a): Item_datefunc(thd, a) {} const char *func_name() const { return "last_day"; } bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_last_day>(thd, mem_root, this); } }; #endif /* ITEM_TIMEFUNC_INCLUDED */ diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index 40f48cc7dc5..90ecd277d1f 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -119,7 +119,8 @@ public: { return "row_number"; } - + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_row_number>(thd, mem_root, this); } }; @@ -188,6 +189,8 @@ public: peer_tracker.cleanup(); Item_sum_int::cleanup(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_rank>(thd, mem_root, this); } }; @@ -251,6 +254,8 @@ class Item_sum_dense_rank: public Item_sum_int peer_tracker.cleanup(); Item_sum_int::cleanup(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_dense_rank>(thd, mem_root, this); } }; /* @@ -342,6 +347,8 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count } void setup_window_func(THD *thd, Window_spec *window_spec); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_percent_rank>(thd, mem_root, this); } private: longlong cur_rank; // Current rank of the current row. @@ -419,6 +426,9 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count decimals = 10; // TODO-cvicentiu find out how many decimals the standard // requires. } + + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_cume_dist>(thd, mem_root, this); } private: ulonglong current_row_count_; @@ -487,6 +497,9 @@ class Item_sum_ntile : public Item_sum_window_with_row_count enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } + + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_sum_ntile>(thd, mem_root, this); } private: longlong get_num_quantiles() { return args[0]->val_int(); } @@ -751,6 +764,8 @@ public: bool fix_fields(THD *thd, Item **ref); bool resolve_window_name(THD *thd); + + Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; } }; diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index ba17d2c48c3..1736f7d4990 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -250,6 +250,8 @@ public: Item_nodeset_func(thd, pxml) {} const char *func_name() const { return "xpath_rootelement"; } String *val_nodeset(String *nodeset); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_func_rootelement>(thd, mem_root, this); } }; @@ -261,6 +263,8 @@ public: Item_nodeset_func(thd, a, b, pxml) {} const char *func_name() const { return "xpath_union"; } String *val_nodeset(String *nodeset); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_func_union>(thd, mem_root, this); } }; @@ -293,6 +297,8 @@ public: Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} const char *func_name() const { return "xpath_selfbyname"; } String *val_nodeset(String *nodeset); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_func_selfbyname>(thd, mem_root, this); } }; @@ -305,6 +311,8 @@ public: Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} const char *func_name() const { return "xpath_childbyname"; } String *val_nodeset(String *nodeset); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_func_childbyname>(thd, mem_root, this); } }; @@ -319,6 +327,8 @@ public: need_self(need_self_arg) {} const char *func_name() const { return "xpath_descendantbyname"; } String *val_nodeset(String *nodeset); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_func_descendantbyname>(thd, mem_root, this); } }; @@ -333,6 +343,8 @@ public: need_self(need_self_arg) {} const char *func_name() const { return "xpath_ancestorbyname"; } String *val_nodeset(String *nodeset); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_func_ancestorbyname>(thd, mem_root, this); } }; @@ -345,6 +357,8 @@ public: Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} const char *func_name() const { return "xpath_parentbyname"; } String *val_nodeset(String *nodeset); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_func_parentbyname>(thd, mem_root, this); } }; @@ -357,6 +371,8 @@ public: Item_nodeset_func_axisbyname(thd, a, n_arg, l_arg, pxml) {} const char *func_name() const { return "xpath_attributebyname"; } String *val_nodeset(String *nodeset); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_func_attributebyname>(thd, mem_root, this); } }; @@ -372,6 +388,8 @@ public: Item_nodeset_func(thd, a, b, pxml) {} const char *func_name() const { return "xpath_predicate"; } String *val_nodeset(String *nodeset); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_func_predicate>(thd, mem_root, this); } }; @@ -383,6 +401,8 @@ public: Item_nodeset_func(thd, a, b, pxml) { } const char *func_name() const { return "xpath_elementbyindex"; } String *val_nodeset(String *nodeset); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_func_elementbyindex>(thd, mem_root, this); } }; @@ -422,6 +442,8 @@ public: } return args[0]->val_real() ? 1 : 0; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_xpath_cast_bool>(thd, mem_root, this); } }; @@ -434,6 +456,8 @@ public: Item_xpath_cast_number(THD *thd, Item *a): Item_real_func(thd, a) {} const char *func_name() const { return "xpath_cast_number"; } virtual double val_real() { return args[0]->val_real(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_xpath_cast_number>(thd, mem_root, this); } }; @@ -449,6 +473,8 @@ public: String *val_nodeset(String *res) { return string_cache; } void fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_context_cache>(thd, mem_root, this); } }; @@ -468,6 +494,8 @@ public: return ((MY_XPATH_FLT*)flt->ptr())->pos + 1; return 0; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_xpath_position>(thd, mem_root, this); } }; @@ -489,6 +517,8 @@ public: return predicate_supplied_context_size; return res->length() / sizeof(MY_XPATH_FLT); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_xpath_count>(thd, mem_root, this); } }; @@ -532,6 +562,8 @@ public: } return sum; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_xpath_sum>(thd, mem_root, this); } }; @@ -608,6 +640,8 @@ public: } return 0; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_nodeset_to_const_comparator>(thd, mem_root, this); } }; diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h index 3758025fc90..8daf8cbc281 100644 --- a/sql/item_xmlfunc.h +++ b/sql/item_xmlfunc.h @@ -105,6 +105,8 @@ public: Item_xml_str_func(thd, a, b) {} const char *func_name() const { return "extractvalue"; } String *val_str(String *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_xml_extractvalue>(thd, mem_root, this); } }; @@ -119,6 +121,8 @@ public: Item_xml_str_func(thd, a, b, c) {} const char *func_name() const { return "updatexml"; } String *val_str(String *); + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_xml_update>(thd, mem_root, this); } }; #endif /* ITEM_XMLFUNC_INCLUDED */ diff --git a/sql/procedure.h b/sql/procedure.h index 1452f33652a..adbff842f95 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -57,6 +57,7 @@ public: { return trace_unsupported_by_check_vcol_func_processor("proc"); } + Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; } }; class Item_proc_real :public Item_proc diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 79e57cded81..5a2b435c069 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -986,3 +986,137 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived) unit->set_thd(thd); DBUG_RETURN(FALSE); } + + +/** + @brief + Extract the condition depended on derived table/view and pushed it there + + @param thd The thread handle + @param cond The condition from which to extract the pushed condition + @param derived The reference to the derived table/view + + @details + This functiom builds the most restrictive condition depending only on + the derived table/view that can be extracted from the condition cond. + The built condition is pushed into the having clauses of the + selects contained in the query specifying the derived table/view. + The function also checks for each select whether any condition depending + only on grouping fields can be extracted from the pushed condition. + If so, it pushes the condition over grouping fields into the where + clause of the select. + + @retval + true if an error is reported + false otherwise +*/ + +bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived) +{ + if (!cond) + return false; + /* + Build the most restrictive condition extractable from 'cond' + that can be pushed into the derived table 'derived'. + All subexpressions of this condition are cloned from the + subexpressions of 'cond'. + This condition has to be fixed yet. + */ + Item *extracted_cond; + derived->check_pushable_cond_for_table(cond); + extracted_cond= derived->build_pushable_cond_for_table(thd, cond); + if (!extracted_cond) + { + /* Nothing can be pushed into the derived table */ + return false; + } + /* Push extracted_cond into every select of the unit specifying 'derived' */ + st_select_lex_unit *unit= derived->get_unit(); + st_select_lex *save_curr_select= thd->lex->current_select; + st_select_lex *sl= unit->first_select(); + for (; sl; sl= sl->next_select()) + { + thd->lex->current_select= sl; + /* + For each select of the unit except the last one + create a clone of extracted_cond + */ + Item *extracted_cond_copy= !sl->next_select() ? extracted_cond : + extracted_cond->build_clone(thd, thd->mem_root); + if (!extracted_cond_copy) + continue; + + /* + Figure out what can be extracted from the pushed condition + that could be pushed into the where clause of sl + */ + Item *cond_over_grouping_fields; + sl->collect_grouping_fields(thd); + sl->check_cond_extraction_for_grouping_fields(extracted_cond_copy, + &Item::exclusive_dependence_on_grouping_fields_processor); + cond_over_grouping_fields= + sl->build_cond_for_grouping_fields(thd, extracted_cond_copy, true); + + /* + Transform the references to the 'derived' columns from the condition + pushed into the where clause of sl to make them usable in the new context + */ + if (cond_over_grouping_fields) + cond_over_grouping_fields= cond_over_grouping_fields->transform(thd, + &Item::derived_field_transformer_for_where, + (uchar*) sl); + + if (cond_over_grouping_fields) + { + /* + In extracted_cond_copy remove top conjuncts that + has been pushed into the where clause of sl + */ + extracted_cond_copy= remove_pushed_top_conjuncts(thd, extracted_cond_copy); + + /* + Create the conjunction of the existing where condition of sl + and the pushed condition, take it as the new where condition of sl + and fix this new condition + */ + cond_over_grouping_fields->walk(&Item::cleanup_processor, 0, 0); + thd->change_item_tree(&sl->join->conds, + and_conds(thd, sl->join->conds, + cond_over_grouping_fields)); + + if (sl->join->conds->fix_fields(thd, &sl->join->conds)) + goto err; + + if (!extracted_cond_copy) + continue; + } + + /* + Transform the references to the 'derived' columns from the condition + pushed into the having clause of sl to make them usable in the new context + */ + extracted_cond_copy= extracted_cond_copy->transform(thd, + &Item::derived_field_transformer_for_having, + (uchar*) sl); + if (!extracted_cond_copy) + continue; + /* + Create the conjunction of the existing having condition of sl + and the pushed condition, take it as the new having condition of sl + and fix this new condition + */ + extracted_cond_copy->walk(&Item::cleanup_processor, 0, 0); + thd->change_item_tree(&sl->join->having, + and_conds(thd, sl->join->having, + extracted_cond_copy)); + sl->having_fix_field= 1; + if (sl->join->having->fix_fields(thd, &sl->join->having)) + return true; + sl->having_fix_field= 0; + } + thd->lex->current_select= save_curr_select; + return false; +err: + thd->lex->current_select= save_curr_select; + return true; +} diff --git a/sql/sql_derived.h b/sql/sql_derived.h index 1dffef7235b..c451e423032 100644 --- a/sql/sql_derived.h +++ b/sql/sql_derived.h @@ -37,4 +37,12 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived); */ bool mysql_derived_cleanup(THD *thd, LEX *lex, TABLE_LIST *derived); +Item *delete_not_needed_parts(THD *thd, Item *cond); + +#if 0 +bool pushdown_cond_for_derived(THD *thd, Item **cond, TABLE_LIST *derived); +#else +bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived); +#endif + #endif /* SQL_DERIVED_INCLUDED */ diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index de345b4dd1c..727fdd73265 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -4880,3 +4880,191 @@ void binlog_unsafe_map_init() } #endif + +/** + @brief + Finding fiels that are used in the GROUP BY of this st_select_lex + + @param thd The thread handle + + @details + This method looks through the fields which are used in the GROUP BY of this + st_select_lex and saves this fields. +*/ + +void st_select_lex::collect_grouping_fields(THD *thd) +{ + List_iterator<Item> li(join->fields_list); + Item *item= li++; + for (uint i= 0; i < master_unit()->derived->table->s->fields; i++, (item=li++)) + { + for (ORDER *ord= join->group_list; ord; ord= ord->next) + { + if ((*ord->item)->eq((Item*)item, 0)) + { + Grouping_tmp_field *grouping_tmp_field= + new Grouping_tmp_field(master_unit()->derived->table->field[i], item); + grouping_tmp_fields.push_back(grouping_tmp_field); + } + } + } +} + +/** + @brief + For a condition check possibility of exraction a formula over grouping fields + + @param cond The condition whose subformulas are to be analyzed + + @details + This method traverses the AND-OR condition cond and for each subformula of + the condition it checks whether it can be usable for the extraction of a + condition over the grouping fields of this select. The method uses + the call-back parameter check_processor to ckeck whether a primary formula + depends only on grouping fields. + The subformulas that are not usable are marked with the flag NO_EXTRACTION_FL. + The subformulas that can be entierly extracted are marked with the flag + FULL_EXTRACTION_FL. + @note + This method is called before any call of extract_cond_for_grouping_fields. + The flag NO_EXTRACTION_FL set in a subformula allows to avoid building clone + for the subformula when extracting the pushable condition. + The flag FULL_EXTRACTION_FL allows to delete later all top level conjuncts + from cond. +*/ + +void st_select_lex::check_cond_extraction_for_grouping_fields(Item *cond, + Item_processor check_processor) +{ + cond->clear_extraction_flag(); + if (cond->type() == Item::COND_ITEM) + { + bool and_cond= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC; + List<Item> *arg_list= ((Item_cond*) cond)->argument_list(); + List_iterator<Item> li(*arg_list); + uint count= 0; // to count items not containing NO_EXTRACTION_FL + uint count_full= 0; // to count items with FULL_EXTRACTION_FL + Item *item; + while ((item=li++)) + { + check_cond_extraction_for_grouping_fields(item, check_processor); + if (item->get_extraction_flag() != NO_EXTRACTION_FL) + { + count++; + if (item->get_extraction_flag() == FULL_EXTRACTION_FL) + count_full++; + } + else if (!and_cond) + break; + } + if ((and_cond && count == 0) || item) + cond->set_extraction_flag(NO_EXTRACTION_FL); + if (count_full == arg_list->elements) + cond->set_extraction_flag(FULL_EXTRACTION_FL); + if (cond->get_extraction_flag() != 0) + { + li.rewind(); + while ((item=li++)) + item->clear_extraction_flag(); + } + } + else + cond->set_extraction_flag(cond->walk(check_processor, + 0, (uchar *) this) ? + NO_EXTRACTION_FL : FULL_EXTRACTION_FL); +} + + +/** + @brief + Build condition extractable from the given one depended on grouping fields + + @param thd The thread handle + @param cond The condition from which the condition depended + on grouping fields is to be extracted + @param no_top_clones If it's true then no clones for the top fully + extractable conjuncts are built + + @details + For the given condition cond this method finds out what condition depended + only on the grouping fields can be extracted from cond. If such condition C + exists the method builds the item for it. + This method uses the flags NO_EXTRACTION_FL and FULL_EXTRACTION_FL set by the + preliminary call of st_select_lex::check_cond_extraction_for_grouping_fields + to figure out whether a subformula depends only on these fields or not. + @note + The built condition C is always implied by the condition cond + (cond => C). The method tries to build the most restictive such + condition (i.e. for any other condition C' such that cond => C' + we have C => C'). + @note + The build item is not ready for usage: substitution for the field items + has to be done and it has to be re-fixed. + + @retval + the built condition depended only on grouping fields if such a condition exists + NULL if there is no such a condition +*/ + +Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond, + bool no_top_clones) +{ + if (cond->get_extraction_flag() == FULL_EXTRACTION_FL) + { + if (no_top_clones) + return cond; + cond->clear_extraction_flag(); + return cond->build_clone(thd, thd->mem_root); + } + if (cond->type() == Item::COND_ITEM) + { + bool cond_and= false; + Item_cond *new_cond; + if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) + { + cond_and= true; + new_cond= new (thd->mem_root) Item_cond_and(thd); + } + else + new_cond= new (thd->mem_root) Item_cond_or(thd); + if (!new_cond) + return 0; + List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item=li++)) + { + if (item->get_extraction_flag() == NO_EXTRACTION_FL) + { + DBUG_ASSERT(cond_and); + item->clear_extraction_flag(); + continue; + } + Item *fix= build_cond_for_grouping_fields(thd, item, + no_top_clones & cond_and); + if (!fix) + { + if (cond_and) + continue; + break; + } + new_cond->argument_list()->push_back(fix, thd->mem_root); + } + + if (!cond_and && item) + { + while((item= li++)) + item->clear_extraction_flag(); + return 0; + } + switch (new_cond->argument_list()->elements) + { + case 0: + return 0; + case 1: + return new_cond->argument_list()->head(); + default: + return new_cond; + } + } + return 0; +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 10247bd33a2..77c9b9c7f37 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -726,6 +726,21 @@ public: typedef class st_select_lex_unit SELECT_LEX_UNIT; typedef Bounds_checked_array<Item*> Ref_ptr_array; + +/* + Structure which consists of the field and the item which + produces this field. +*/ + +class Grouping_tmp_field :public Sql_alloc +{ +public: + Field *tmp_field; + Item *producing_item; + Grouping_tmp_field(Field *fld, Item *item) + :tmp_field(fld), producing_item(item) {} +}; + /* SELECT_LEX - store information of parsed SELECT statment */ @@ -910,6 +925,8 @@ public: /* namp of nesting SELECT visibility (for aggregate functions check) */ nesting_map name_visibility_map; + + List<Grouping_tmp_field> grouping_tmp_fields; void init_query(); void init_select(); @@ -1097,6 +1114,11 @@ public: return master_unit()->with_element; } With_element *find_table_def_in_with_clauses(TABLE_LIST *table); + void collect_grouping_fields(THD *thd); + void check_cond_extraction_for_grouping_fields(Item *cond, + Item_processor processor); + Item *build_cond_for_grouping_fields(THD *thd, Item *cond, + bool no_to_clones); List<Window_spec> window_specs; void prepare_add_window_spec(THD *thd); @@ -3193,6 +3215,7 @@ public: } }; + extern sql_digest_state * digest_add_token(sql_digest_state *state, uint token, LEX_YYSTYPE yylval); diff --git a/sql/sql_priv.h b/sql/sql_priv.h index b15a80a889a..0d19ad1da17 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -224,7 +224,7 @@ #define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1ULL << 26) #define OPTIMIZER_SWITCH_EXTENDED_KEYS (1ULL << 27) #define OPTIMIZER_SWITCH_EXISTS_TO_IN (1ULL << 28) -#define OPTIMIZER_SWITCH_USE_CONDITION_SELECTIVITY (1ULL << 29) +#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED (1ULL << 29) #define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \ @@ -248,7 +248,8 @@ OPTIMIZER_SWITCH_SEMIJOIN | \ OPTIMIZER_SWITCH_FIRSTMATCH | \ OPTIMIZER_SWITCH_LOOSE_SCAN | \ - OPTIMIZER_SWITCH_EXISTS_TO_IN) + OPTIMIZER_SWITCH_EXISTS_TO_IN | \ + OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED) /* Replication uses 8 bytes to store SQL_MODE in the binary log. The day you use strictly more than 64 bits by adding one more define above, you should diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a6bbfc806e1..c09f2e601f1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1122,11 +1122,14 @@ int JOIN::optimize() int JOIN::optimize_inner() { +/* + if (conds) { Item *it_clone= conds->build_clone(thd,thd->mem_root); } +*/ ulonglong select_opts_for_readinfo; uint no_jbuf_after; JOIN_TAB *tab; DBUG_ENTER("JOIN::optimize"); - + dbug_print_item(conds); do_send_rows = (unit->select_limit_cnt) ? 1 : 0; // to prevent double initialization on EXPLAIN if (optimized) @@ -1139,10 +1142,6 @@ JOIN::optimize_inner() set_allowed_join_cache_types(); need_distinct= TRUE; - /* Run optimize phase for all derived tables/views used in this SELECT. */ - if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE)) - DBUG_RETURN(1); - if (select_lex->first_cond_optimization) { //Do it only for the first execution @@ -1254,9 +1253,32 @@ JOIN::optimize_inner() if (setup_jtbm_semi_joins(this, join_list, &conds)) DBUG_RETURN(1); - + conds= optimize_cond(this, conds, join_list, FALSE, &cond_value, &cond_equal, OPT_LINK_EQUAL_FIELDS); + + if (thd->lex->sql_command == SQLCOM_SELECT && + optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED)) + { + TABLE_LIST *tbl; + List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables); + while ((tbl= li++)) + { + if (tbl->is_materialized_derived()) + { + if (pushdown_cond_for_derived(thd, conds, tbl)) + DBUG_RETURN(1); + if (mysql_handle_single_derived(thd->lex, tbl, DT_OPTIMIZE)) + DBUG_RETURN(1); + } + } + } + else + { + /* Run optimize phase for all derived tables/views used in this SELECT. */ + if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE)) + DBUG_RETURN(1); + } if (thd->is_error()) { @@ -26022,5 +26044,60 @@ AGGR_OP::end_send() /** + @brief + Remove marked top conjuncts of a condition + + @param thd The thread handle + @param cond The condition which subformulas are to be removed + + @details + The function removes all top conjuncts marked with the flag + FULL_EXTRACTION_FL from the condition 'cond'. The resulting + formula is returned a the result of the function + If 'cond' s marked with such flag the function returns 0. + The function clear the extraction flags for the removed + formulas + + @retval + condition without removed subformulas + 0 if the whole 'cond' is removed +*/ + +Item *remove_pushed_top_conjuncts(THD *thd, Item *cond) +{ + if (cond->get_extraction_flag() == FULL_EXTRACTION_FL) + { + cond->clear_extraction_flag(); + return 0; + } + if (cond->type() == Item::COND_ITEM) + { + if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) + { + List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item= li++)) + { + if (item->get_extraction_flag() == FULL_EXTRACTION_FL) + { + item->clear_extraction_flag(); + li.remove(); + } + } + switch (((Item_cond*) cond)->argument_list()->elements) + { + case 0: + return 0; + case 1: + return ((Item_cond*) cond)->argument_list()->head(); + default: + return cond; + } + } + } + return cond; +} + +/** @} (end of group Query_Optimizer) */ diff --git a/sql/sql_select.h b/sql/sql_select.h index d4dc691c547..408dd6f9958 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -188,7 +188,7 @@ typedef enum_nested_loop_state Next_select_func setup_end_select_func(JOIN *join, JOIN_TAB *tab); int rr_sequential(READ_RECORD *info); int rr_sequential_and_unpack(READ_RECORD *info); - +Item *remove_pushed_top_conjuncts(THD *thd, Item *cond); #include "sql_explain.h" diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 4bf202813f3..881c6715ba2 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2382,6 +2382,7 @@ export const char *optimizer_switch_names[]= "table_elimination", "extended_keys", "exists_to_in", + "condition_pushdown_for_derived", "default", NullS }; static bool fix_optimizer_switch(sys_var *self, THD *thd, diff --git a/sql/table.cc b/sql/table.cc index dc1730b5b6f..63a54331083 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -7445,3 +7445,179 @@ double KEY::actual_rec_per_key(uint i) return (is_statistics_from_stat_tables ? read_stats->get_avg_frequency(i) : (double) rec_per_key[i]); } + + +/** + @brief + Mark subformulas of a condition unusable for the condition pushed into table + + @param cond The condition whose subformulas are to be marked + + @details + This method recursively traverses the AND-OR condition cond and for each subformula + of the codition it checks whether it can be usable for the extraction of a condition + that can be pushed into this table. The subformulas that are not usable are + marked with the flag NO_EXTRACTION_FL. + @note + This method is called before any call of TABLE_LIST::build_pushable_cond_for_table. + The flag NO_EXTRACTION_FL set in a subformula allows to avoid building clone + for the subformula when extracting the pushable condition. +*/ + +void TABLE_LIST::check_pushable_cond_for_table(Item *cond) +{ + table_map tab_map= table->map; + cond->clear_extraction_flag(); + if (cond->type() == Item::COND_ITEM) + { + bool and_cond= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC; + List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); + uint count= 0; + Item *item; + while ((item=li++)) + { + check_pushable_cond_for_table(item); + if (item->get_extraction_flag() != NO_EXTRACTION_FL) + count++; + else if (!and_cond) + break; + } + if ((and_cond && count == 0) || item) + { + cond->set_extraction_flag(NO_EXTRACTION_FL); + if (and_cond) + li.rewind(); + while ((item= li++)) + item->clear_extraction_flag(); + } + } + else if (cond->walk(&Item::exclusive_dependence_on_table_processor, + 0, (uchar *) &tab_map)) + cond->set_extraction_flag(NO_EXTRACTION_FL); +} + + +/** + @brief + Build condition extractable from the given one depended only on this table + + @param thd The thread handle + @param cond The condition from which the pushable one is to be extracted + + @details + For the given condition cond this method finds out what condition depended + only on this table can be extracted from cond. If such condition C exists + the method builds the item for it. + The method uses the flag NO_EXTRACTION_FL set by the preliminary call of + the method TABLE_LIST::check_pushable_cond_for_table to figure out whether + a subformula depends only on this table or not. + @note + The built condition C is always implied by the condition cond + (cond => C). The method tries to build the most restictive such + condition (i.e. for any other condition C' such that cond => C' + we have C => C'). + @note + The build item is not ready for usage: substitution for the field items + has to be done and it has to be re-fixed. + + @retval + the built condition pushable into this table if such a condition exists + NULL if there is no such a condition +*/ + +Item* TABLE_LIST::build_pushable_cond_for_table(THD *thd, Item *cond) +{ + table_map tab_map= table->map; + bool is_multiple_equality= cond->type() == Item::FUNC_ITEM && + ((Item_func*) cond)->functype() == Item_func::MULT_EQUAL_FUNC; + if (cond->get_extraction_flag() == NO_EXTRACTION_FL) + return 0; + if (cond->type() == Item::COND_ITEM) + { + bool cond_and= false; + Item_cond *new_cond; + if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) + { + cond_and= true; + new_cond=new (thd->mem_root) Item_cond_and(thd); + } + else + new_cond= new (thd->mem_root) Item_cond_or(thd); + if (!new_cond) + return 0; + List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item=li++)) + { + if (item->get_extraction_flag() == NO_EXTRACTION_FL) + { + if (!cond_and) + return 0; + continue; + } + Item *fix= build_pushable_cond_for_table(thd, item); + if (!fix && !cond_and) + return 0; + if (!fix) + continue; + new_cond->argument_list()->push_back(fix, thd->mem_root); + } + switch (new_cond->argument_list()->elements) + { + case 0: + return 0; + case 1: + return new_cond->argument_list()->head(); + default: + return new_cond; + } + } + else if (is_multiple_equality) + { + if (!(cond->used_tables() & tab_map)) + return 0; + Item *new_cond= NULL; + int i= 0; + Item_equal *item_equal= (Item_equal *) cond; + Item *left_item = item_equal->get_const(); + Item_equal_fields_iterator it(*item_equal); + Item *item; + if (!left_item) + { + while ((item=it++)) + if (item->used_tables() == tab_map) + { + left_item= item; + break; + } + } + if (!left_item) + return 0; + while ((item=it++)) + { + if (!(item->used_tables() == tab_map)) + continue; + Item_func_eq *eq= + new (thd->mem_root) Item_func_eq(thd, item, left_item); + if (eq) + { + i++; + switch (i) + { + case 1: + new_cond= eq; + break; + case 2: + new_cond= new (thd->mem_root) Item_cond_and(thd, new_cond, eq); + break; + default: + ((Item_cond_and*)new_cond)->argument_list()->push_back(eq, thd->mem_root); + } + } + } + return new_cond; + } + else if (cond->get_extraction_flag() != NO_EXTRACTION_FL) + return cond->build_clone(thd, thd->mem_root); + return 0; +} diff --git a/sql/table.h b/sql/table.h index a105df31e93..e0d98627d89 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2311,6 +2311,8 @@ struct TABLE_LIST return false; } void set_lock_type(THD* thd, enum thr_lock_type lock); + void check_pushable_cond_for_table(Item *cond); + Item *build_pushable_cond_for_table(THD *thd, Item *cond); private: bool prep_check_option(THD *thd, uint8 check_opt_type); |