summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/derived_cond_pushdown.result6436
-rw-r--r--mysql-test/t/derived_cond_pushdown.test812
-rw-r--r--sql/item.cc204
-rw-r--r--sql/item.h121
-rw-r--r--sql/item_cmpfunc.cc40
-rw-r--r--sql/item_cmpfunc.h104
-rw-r--r--sql/item_func.cc3
-rw-r--r--sql/item_func.h158
-rw-r--r--sql/item_geofunc.h69
-rw-r--r--sql/item_inetfunc.h16
-rw-r--r--sql/item_row.cc18
-rw-r--r--sql/item_row.h3
-rw-r--r--sql/item_strfunc.h139
-rw-r--r--sql/item_subselect.h3
-rw-r--r--sql/item_sum.h38
-rw-r--r--sql/item_timefunc.h92
-rw-r--r--sql/item_windowfunc.h17
-rw-r--r--sql/item_xmlfunc.cc34
-rw-r--r--sql/item_xmlfunc.h4
-rw-r--r--sql/procedure.h1
-rw-r--r--sql/sql_derived.cc134
-rw-r--r--sql/sql_derived.h8
-rw-r--r--sql/sql_lex.cc188
-rw-r--r--sql/sql_lex.h24
-rw-r--r--sql/sql_priv.h4
-rw-r--r--sql/sql_select.cc89
-rw-r--r--sql/sql_select.h2
-rw-r--r--sql/sys_vars.cc1
-rw-r--r--sql/table.cc176
-rw-r--r--sql/table.h2
30 files changed, 8926 insertions, 14 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 5da95b05b2f..6bce98b071c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -488,6 +488,7 @@ Item::Item(THD *thd):
}
}
+
/**
Constructor used by Item_field, Item_ref & aggregate (sum)
functions.
@@ -2258,6 +2259,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;
@@ -6708,6 +6776,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 &&
@@ -9933,5 +10080,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 8fcbf82853d..34fd66710c2 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -32,6 +32,8 @@ C_MODE_START
#include <ma_dyncol.h>
C_MODE_END
+const char *dbug_print_item(Item *item);
+
class Protocol;
struct TABLE_LIST;
void item_init(void); /* Init item functions */
@@ -89,6 +91,10 @@ bool mark_unsupported_function(const char *w1, const char *w2,
#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;
@@ -591,7 +597,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
@@ -1110,6 +1115,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 < FLOATING_POINT_DECIMALS ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
@@ -1475,6 +1481,14 @@ public:
virtual bool exists2in_processor(void *opt_arg) { return 0; }
virtual bool find_selective_predicates_list_processor(void *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)
@@ -1836,9 +1854,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()
*/
@@ -2119,6 +2163,8 @@ public:
{ return this; }
bool append_for_log(THD *thd, String *str);
+
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
};
/*****************************************************************************
@@ -2165,6 +2211,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;
@@ -2245,6 +2292,8 @@ public:
{
return mark_unsupported_function("name_const()", arg, VCOL_IMPOSSIBLE);
}
+ 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
@@ -2377,6 +2426,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); }
};
@@ -2529,7 +2580,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);
@@ -2622,6 +2679,8 @@ public:
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
bool check_partition_func_processor(void *int_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
@@ -2783,6 +2842,8 @@ public:
bool append_for_log(THD *thd, String *str);
bool check_vcol_func_processor(void *int_arg) {return FALSE;}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
+
private:
virtual bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
@@ -2831,6 +2892,8 @@ public:
{ return (uint) (max_length - MY_TEST(value < 0)); }
bool eq(const Item *item, bool binary_cmp) const
{ return int_eq(value, item); }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_int>(thd, mem_root, this); }
};
@@ -2847,6 +2910,8 @@ public:
virtual void print(String *str, enum_query_type query_type);
Item *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:
uint decimal_precision() const { return decimal_value.precision(); }
bool eq(const Item *, bool binary_cmp) const;
void set_decimal_value(my_decimal *value_par);
+ 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); }
};
@@ -3130,6 +3199,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); }
};
@@ -3358,6 +3430,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); }
};
@@ -3398,6 +3472,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); }
};
@@ -3479,6 +3555,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); }
};
@@ -3498,6 +3576,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); }
};
@@ -3519,6 +3599,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); }
};
@@ -3879,6 +3961,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);
};
@@ -4054,6 +4137,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.
@@ -4062,6 +4147,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); }
};
@@ -4104,6 +4191,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); }
};
@@ -4265,6 +4354,9 @@ public:
{
return mark_unsupported_function("cache", arg, VCOL_IMPOSSIBLE);
}
+ 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; }
};
@@ -4516,6 +4608,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); }
};
/*
@@ -4675,6 +4769,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); }
};
@@ -4697,6 +4793,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); }
};
@@ -4713,6 +4811,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); }
};
@@ -4739,6 +4839,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); }
};
@@ -4758,6 +4860,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); }
};
@@ -5183,6 +5287,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); }
};
@@ -5207,6 +5313,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); }
};
@@ -5223,6 +5331,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); }
};
@@ -5239,6 +5349,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); }
};
@@ -5265,6 +5377,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); }
};
@@ -5288,6 +5402,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); }
};
@@ -5359,6 +5475,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); }
};
@@ -5414,6 +5532,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 eafb6b1c91b..92fe5f2c474 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
@@ -4856,6 +4859,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 f899775ce88..6d432bd97f3 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;
};
@@ -244,6 +246,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); }
};
@@ -258,6 +262,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); }
};
@@ -271,6 +277,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); }
};
@@ -285,6 +293,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); }
};
@@ -346,6 +356,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); }
};
@@ -499,6 +511,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;
+ }
+
};
/**
@@ -521,6 +544,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
@@ -537,6 +562,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;
@@ -584,6 +611,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
@@ -659,6 +688,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
@@ -681,6 +712,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); }
};
@@ -695,6 +728,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); }
};
@@ -709,6 +744,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); }
};
@@ -723,6 +760,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); }
};
@@ -737,6 +776,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); }
};
@@ -760,6 +801,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); }
};
@@ -840,6 +883,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); }
};
@@ -858,6 +903,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); }
};
@@ -888,6 +935,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); }
};
@@ -910,6 +959,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); }
};
@@ -959,6 +1010,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); }
};
@@ -982,6 +1035,8 @@ public:
const char *func_name() const { return "if"; }
bool eval_not_null_tables(void *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);
};
@@ -1057,6 +1112,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); }
};
@@ -1240,7 +1297,6 @@ public:
item_dec->set_decimal_value(dec);
}
Item_result result_type() { return DECIMAL_RESULT; }
-
};
@@ -1499,6 +1555,19 @@ public:
void cleanup();
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond);
bool need_parentheses_in_default() { return true; }
+ 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;
+ }
};
/*
@@ -1595,6 +1664,18 @@ public:
bool eval_not_null_tables(void *opt_arg);
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
bool count_sargable_conds(void *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
@@ -1689,6 +1770,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 */
@@ -1734,6 +1817,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); }
};
@@ -1873,6 +1958,9 @@ public:
void cleanup();
bool find_selective_predicates_list_processor(void *arg);
+
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_like>(thd, mem_root, this); }
};
@@ -1978,6 +2066,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)
{
@@ -2005,6 +2095,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); }
};
@@ -2082,6 +2174,7 @@ public:
Item *compile(THD *thd, Item_analyzer analyzer, uchar **arg_p,
Item_transformer transformer, uchar *arg_t);
bool eval_not_null_tables(void *opt_arg);
+ Item *build_clone(THD *thd, MEM_ROOT *mem_root);
};
template <template<class> class LI, class T> class Item_equal_iterator;
@@ -2254,6 +2347,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(void *arg);
friend class Item_equal_iterator<List_iterator_fast,Item>;
@@ -2398,6 +2492,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)
@@ -2422,6 +2518,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
@@ -2431,6 +2529,8 @@ public:
longlong val_int();
const char *func_name() const { return "column_check"; }
bool need_parentheses_in_default() { return false; }
+ 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
@@ -2441,6 +2541,8 @@ public:
longlong val_int();
const char *func_name() const { return "column_exists"; }
bool need_parentheses_in_default() { return false; }
+ 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 cc1494cc034..f02c6ca3940 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -6957,3 +6957,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 92bc798e044..44ad4e8a543 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -615,6 +615,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_connection_id>(thd, mem_root, this); }
};
@@ -640,6 +642,8 @@ public:
virtual void print(String *str, enum_query_type query_type);
uint decimal_precision() const { return args[0]->decimal_precision(); }
bool need_parentheses_in_default() { return true; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_signed>(thd, mem_root, this); }
};
@@ -658,6 +662,8 @@ public:
return value;
}
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); }
};
@@ -682,6 +688,8 @@ public:
const char *func_name() const { return "decimal_typecast"; }
virtual void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_decimal_typecast>(thd, mem_root, this); }
};
@@ -700,6 +708,8 @@ public:
const char *func_name() const { return "double_typecast"; }
virtual void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_double_typecast>(thd, mem_root, this); }
};
@@ -723,6 +733,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
@@ -735,6 +747,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); }
};
@@ -750,6 +764,8 @@ public:
void result_precision();
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_mul>(thd, mem_root, this); }
};
@@ -764,6 +780,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); }
};
@@ -784,6 +802,8 @@ public:
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
bool need_parentheses_in_default() { return true; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_int_div>(thd, mem_root, this); }
};
@@ -799,6 +819,8 @@ public:
void fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_mod>(thd, mem_root, this); }
};
@@ -816,6 +838,8 @@ public:
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
bool need_parentheses_in_default() { return true; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_neg>(thd, mem_root, this); }
};
@@ -830,6 +854,8 @@ public:
void fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *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
@@ -852,6 +878,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); }
};
@@ -861,6 +889,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); }
};
@@ -871,6 +901,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); }
};
@@ -880,6 +912,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); }
};
@@ -889,6 +923,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); }
};
@@ -898,6 +934,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); }
};
@@ -907,6 +945,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); }
};
@@ -916,6 +956,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
@@ -924,6 +966,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
@@ -933,6 +977,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
@@ -941,6 +987,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
@@ -949,6 +997,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
@@ -957,6 +1007,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
@@ -965,6 +1017,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
@@ -993,6 +1047,8 @@ public:
my_decimal *decimal_op(my_decimal *);
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_ceiling>(thd, mem_root, this); }
};
@@ -1006,6 +1062,8 @@ public:
my_decimal *decimal_op(my_decimal *);
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *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 */
@@ -1021,6 +1079,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); }
};
@@ -1042,6 +1102,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
}
+ 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);
};
@@ -1053,6 +1115,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); }
};
@@ -1068,6 +1132,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); }
};
@@ -1104,6 +1170,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
@@ -1111,6 +1179,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); }
};
@@ -1143,6 +1213,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); }
};
@@ -1154,6 +1226,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
@@ -1163,6 +1237,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
@@ -1173,6 +1249,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
@@ -1186,6 +1264,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
@@ -1199,6 +1279,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); }
};
@@ -1212,6 +1294,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); }
};
@@ -1223,6 +1307,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
@@ -1232,6 +1318,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
@@ -1246,6 +1334,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: '~', '|', '^', '&', '>>', '<<' */
@@ -1270,6 +1360,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
@@ -1278,6 +1370,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
@@ -1287,6 +1381,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
@@ -1295,6 +1391,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
@@ -1303,6 +1401,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
@@ -1316,6 +1416,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); }
};
@@ -1338,6 +1440,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_last_insert_id>(thd, mem_root, this); }
};
@@ -1355,6 +1459,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_benchmark>(thd, mem_root, this); }
};
@@ -1377,6 +1483,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_sleep>(thd, mem_root, this); }
};
@@ -1500,6 +1608,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); }
};
@@ -1517,6 +1627,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); }
};
@@ -1534,6 +1646,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); }
};
@@ -1572,6 +1686,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 */
@@ -1647,6 +1763,8 @@ class Item_func_get_lock :public Item_int_func
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ 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
@@ -1667,6 +1785,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_release_lock>(thd, mem_root, this); }
};
/* replication functions */
@@ -1687,6 +1807,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_master_pos_wait>(thd, mem_root, this); }
};
@@ -1703,6 +1825,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_master_gtid_wait>(thd, mem_root, this); }
};
@@ -1816,6 +1940,8 @@ public:
bool register_field_in_bitmap(void *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); }
};
@@ -1842,6 +1968,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);
@@ -1881,6 +2009,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); }
};
@@ -1935,6 +2065,8 @@ public:
void cleanup();
bool check_vcol_func_processor(void *arg);
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_get_system_var>(thd, mem_root, this); }
};
@@ -1984,6 +2116,9 @@ public:
{
return mark_unsupported_function("match ... against()", arg, VCOL_IMPOSSIBLE);
}
+ 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,
@@ -2027,6 +2162,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
@@ -2041,6 +2178,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ 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
@@ -2055,6 +2194,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ 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 */
@@ -2105,6 +2246,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_row_count>(thd, mem_root, this); }
};
@@ -2232,6 +2375,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;
+ }
};
@@ -2246,6 +2398,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_found_rows>(thd, mem_root, this); }
};
@@ -2264,6 +2418,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_uuid_short>(thd, mem_root, this); }
};
@@ -2289,6 +2445,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 58e1d0a78fb..f96e570915e 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); }
};
@@ -300,6 +326,7 @@ public:
usable_tables, sargables, false);
}
bool need_parentheses_in_default() { return false; }
+ Item *build_clone(THD *thd, MEM_ROOT *mem_root) { return 0; }
};
@@ -311,6 +338,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); }
};
@@ -325,6 +354,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); }
};
@@ -341,6 +372,8 @@ public:
longlong val_int();
const char *func_name() const { return "st_relate"; }
bool need_parentheses_in_default() { return false; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_spatial_relate>(thd, mem_root, this); }
};
@@ -370,6 +403,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); }
};
@@ -421,6 +456,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); }
};
@@ -432,6 +469,8 @@ public:
const char *func_name() const { return "st_isempty"; }
void fix_length_and_dec() { maybe_null= 1; }
bool need_parentheses_in_default() { return false; }
+ 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
@@ -446,6 +485,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
@@ -456,6 +497,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
@@ -464,6 +507,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
@@ -474,6 +519,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
@@ -488,6 +535,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); }
};
@@ -503,6 +552,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); }
};
@@ -514,6 +565,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); }
};
@@ -525,6 +578,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); }
};
@@ -536,6 +591,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); }
};
@@ -551,6 +608,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); }
};
@@ -566,6 +625,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); }
};
@@ -577,6 +638,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); }
};
@@ -591,6 +654,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); }
};
@@ -605,6 +670,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); }
};
@@ -620,6 +687,8 @@ class Item_func_gis_debug: public Item_int_func
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ 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 f5a0596d860..741b9f7d997 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); }
};
@@ -124,6 +128,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);
@@ -156,6 +162,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);
@@ -176,6 +184,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);
@@ -196,6 +206,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);
@@ -216,6 +228,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);
@@ -236,6 +250,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 a17d2507547..ddbb0736d54 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 eb2686090e1..bbfebb56010 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(void *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 fd63c571359..25b63ebe73d 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 FALSE;
}
+ 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); }
};
@@ -665,10 +730,13 @@ public:
}
bool check_vcol_func_processor(void *arg)
{
+
context= 0;
return mark_unsupported_function(fully_qualified_func_name(), arg,
VCOL_SESSION_FUNC);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_current_role>(thd, mem_root, this); }
};
@@ -680,6 +748,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); }
};
@@ -692,6 +762,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); }
};
@@ -704,6 +776,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); }
};
@@ -722,6 +796,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); }
};
@@ -739,6 +815,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); }
};
@@ -751,6 +829,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); }
};
@@ -761,6 +841,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); }
};
@@ -775,8 +857,11 @@ public:
const char *func_name() const { return "binlog_gtid_pos"; }
bool check_vcol_func_processor(void *arg)
{
+
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_binlog_gtid_pos>(thd, mem_root, this); }
};
@@ -789,6 +874,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); }
};
@@ -801,6 +888,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); }
};
@@ -817,6 +906,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); }
};
@@ -834,6 +925,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
@@ -853,6 +946,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); }
};
@@ -883,6 +978,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); }
};
@@ -892,6 +989,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
@@ -917,6 +1016,8 @@ public:
virtual void print(String *str, enum_query_type query_type);
const char *func_name() const { return "cast_as_binary"; }
bool need_parentheses_in_default() { return true; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_binary>(thd, mem_root, this); }
};
@@ -937,6 +1038,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_load_file>(thd, mem_root, this); }
};
@@ -952,6 +1055,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); }
};
@@ -969,6 +1074,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
@@ -1051,6 +1158,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
@@ -1070,6 +1179,8 @@ public:
return args[0]->field_for_view_update();
}
bool need_parentheses_in_default() { return true; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_set_collation>(thd, mem_root, this); }
};
@@ -1097,6 +1208,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); }
};
@@ -1107,6 +1220,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); }
};
@@ -1139,6 +1254,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
@@ -1150,6 +1267,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
@@ -1160,6 +1279,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
@@ -1176,6 +1297,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
@@ -1186,6 +1309,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); }
};
@@ -1205,6 +1330,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_uuid>(thd, mem_root, this); }
};
@@ -1226,6 +1353,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); }
};
@@ -1238,6 +1367,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
@@ -1253,6 +1384,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); }
};
/*
@@ -1293,6 +1426,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); }
};
@@ -1303,6 +1438,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 178c875d5e5..492ad10c2b6 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -257,6 +257,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 4cb5529e1ce..9fd6f7867db 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -768,6 +768,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);
@@ -825,6 +827,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); }
};
@@ -872,6 +876,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); }
};
@@ -930,6 +936,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); }
};
/*
@@ -949,6 +957,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
@@ -1014,6 +1024,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); }
};
@@ -1027,6 +1039,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); }
};
@@ -1101,6 +1115,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();
@@ -1116,6 +1132,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();
@@ -1129,6 +1147,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();
@@ -1187,6 +1207,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); }
};
@@ -1206,6 +1228,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); }
};
@@ -1226,6 +1250,8 @@ public:
bool is_null() { update_null_value(); return null_value; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
enum Item_result result_type () const { return REAL_RESULT; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_variance_field>(thd, mem_root, this); }
};
@@ -1237,6 +1263,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); }
};
@@ -1324,6 +1352,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); }
};
@@ -1345,6 +1375,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); }
};
@@ -1385,6 +1417,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); }
};
@@ -1405,6 +1439,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 */
@@ -1598,6 +1634,8 @@ public:
virtual void print(String *str, enum_query_type query_type);
virtual bool change_context_processor(void *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 84f610b992d..d9de9b9311a 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); }
};
@@ -196,8 +208,11 @@ public:
}
bool check_vcol_func_processor(void *arg)
{
+
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_monthname>(thd, mem_root, this); }
};
@@ -219,6 +234,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); }
};
@@ -240,6 +257,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); }
};
@@ -261,6 +280,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); }
};
@@ -282,6 +303,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); }
};
@@ -303,6 +326,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); }
};
@@ -318,6 +343,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
@@ -338,6 +365,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); }
};
@@ -361,6 +390,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); }
};
@@ -396,6 +427,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
@@ -468,6 +501,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); }
};
@@ -487,6 +522,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 +662,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(THD *thd, 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 +673,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(THD *thd, 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); }
};
@@ -661,6 +702,8 @@ public:
Item_func_curdate_local(THD *thd): Item_func_curdate(thd) {}
const char *func_name() const { return "curdate"; }
void store_now_in_TIME(THD *thd, 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); }
};
@@ -670,6 +713,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(THD* thd, 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 +748,8 @@ public:
const char *func_name() const { return "now"; }
virtual void store_now_in_TIME(THD *thd, 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); }
};
@@ -718,7 +765,8 @@ public:
return mark_unsupported_function(func_name(), "()", arg,
VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC);
}
-
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_now_utc>(thd, mem_root, this); }
};
@@ -741,6 +789,8 @@ public:
VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC);
}
virtual enum Functype functype() const { return SYSDATE_FUNC; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_sysdate_local>(thd, mem_root, this); }
};
@@ -756,6 +806,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); }
};
@@ -778,6 +830,8 @@ public:
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
}
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_date_format>(thd, mem_root, this); }
};
@@ -789,6 +843,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); }
};
@@ -823,6 +879,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); }
};
@@ -837,6 +895,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); }
};
@@ -855,6 +915,8 @@ public:
bool eq(const Item *item, bool binary_cmp) const;
void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_date_add_interval>(thd, mem_root, this); }
};
@@ -909,6 +971,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); }
};
@@ -933,6 +997,8 @@ public:
void fix_length_and_dec();
void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_char_typecast>(thd, mem_root, this); }
};
@@ -958,6 +1024,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); }
};
@@ -970,6 +1038,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); }
};
@@ -982,6 +1052,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); }
};
@@ -993,6 +1065,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); }
};
@@ -1009,6 +1083,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
@@ -1023,6 +1099,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
@@ -1038,6 +1116,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); }
};
@@ -1058,6 +1138,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); }
};
@@ -1075,6 +1157,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); }
};
@@ -1099,6 +1183,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); }
};
@@ -1117,6 +1203,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); }
};
@@ -1126,6 +1214,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 9d2fa135e29..163cc855fe2 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 bf5abc882f2..cbbdeea0205 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 ed12793742e..3c58955c96a 100644
--- a/sql/item_xmlfunc.h
+++ b/sql/item_xmlfunc.h
@@ -101,6 +101,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); }
};
@@ -115,6 +117,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 be631675d5c..b9d5066bb3d 100644
--- a/sql/procedure.h
+++ b/sql/procedure.h
@@ -58,6 +58,7 @@ public:
DBUG_ASSERT(0); // impossible
return mark_unsupported_function("proc", arg, VCOL_IMPOSSIBLE);
}
+ 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 04a84accccf..314d5985a72 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1100,3 +1100,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 08b619668fb..df9ac92d690 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -4915,3 +4915,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 128b57438f0..97d1f001317 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -738,6 +738,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
*/
@@ -922,8 +937,9 @@ public:
/* namp of nesting SELECT visibility (for aggregate functions check) */
nesting_map name_visibility_map;
-
+
table_map with_dep;
+ List<Grouping_tmp_field> grouping_tmp_fields;
void init_query();
void init_select();
@@ -1110,6 +1126,11 @@ public:
With_element *find_table_def_in_with_clauses(TABLE_LIST *table);
bool check_unrestricted_recursive(bool only_standards_compliant);
bool check_subqueries_with_recursive_references();
+ 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);
@@ -3221,6 +3242,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 40349d3802a..4bf93040dc8 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -226,6 +226,7 @@
#define OPTIMIZER_SWITCH_EXTENDED_KEYS (1ULL << 27)
#define OPTIMIZER_SWITCH_EXISTS_TO_IN (1ULL << 28)
#define OPTIMIZER_SWITCH_ORDERBY_EQ_PROP (1ULL << 29)
+#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED (1ULL << 30)
#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
@@ -249,7 +250,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 e6bb6e03e43..f63011c367f 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1131,11 +1131,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)
@@ -1148,10 +1151,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
@@ -1263,9 +1262,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())
{
@@ -26208,5 +26230,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 24c7e0f9ff7..cde6209cb7e 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 ddceb67e1f4..b0a4b3f99d2 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -2390,6 +2390,7 @@ export const char *optimizer_switch_names[]=
"extended_keys",
"exists_to_in",
"orderby_uses_equalities",
+ "condition_pushdown_for_derived",
"default",
NullS
};
diff --git a/sql/table.cc b/sql/table.cc
index 6e5caf7f998..1b2b7352046 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -7903,3 +7903,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 6b2f20b3875..5ffce3e75a3 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -2344,6 +2344,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);