mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Fixes for condition pushdown to storage engine based on comments from code review
mysql-test/r/ndb_condition_pushdown.result: Added more tests for condition pushdown to storage engine based on comments from code review mysql-test/t/ndb_condition_pushdown.test: Added more tests for condition pushdown to storage engine based on comments from code review
This commit is contained in:
@ -1,10 +1,10 @@
|
|||||||
DROP TABLE IF EXISTS t1,t2;
|
DROP TABLE IF EXISTS t1,t2;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
auto int(5) unsigned NOT NULL auto_increment,
|
auto int(5) unsigned NOT NULL auto_increment,
|
||||||
string char(10) default "hello",
|
string char(10),
|
||||||
vstring varchar(10) default "hello",
|
vstring varchar(10),
|
||||||
bin binary(7) default "hello",
|
bin binary(7),
|
||||||
vbin varbinary(7) default "hello",
|
vbin varbinary(7),
|
||||||
tiny tinyint(4) DEFAULT '0' NOT NULL ,
|
tiny tinyint(4) DEFAULT '0' NOT NULL ,
|
||||||
short smallint(6) DEFAULT '1' NOT NULL ,
|
short smallint(6) DEFAULT '1' NOT NULL ,
|
||||||
medium mediumint(8) DEFAULT '0' NOT NULL,
|
medium mediumint(8) DEFAULT '0' NOT NULL,
|
||||||
@ -233,17 +233,41 @@ auto
|
|||||||
2
|
2
|
||||||
3
|
3
|
||||||
4
|
4
|
||||||
|
select auto from t1 where
|
||||||
|
string like "b%" and
|
||||||
|
vstring like "b%" and
|
||||||
|
bin like "b%" and
|
||||||
|
vbin like "b%"
|
||||||
|
order by auto;
|
||||||
|
auto
|
||||||
|
2
|
||||||
|
select auto from t1 where
|
||||||
|
string not like "b%" and
|
||||||
|
vstring not like "b%" and
|
||||||
|
bin not like "b%" and
|
||||||
|
vbin not like "b%"
|
||||||
|
order by auto;
|
||||||
|
auto
|
||||||
|
1
|
||||||
|
3
|
||||||
|
4
|
||||||
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
|
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
|
||||||
pk1 attr1 attr2 attr3
|
pk1 attr1 attr2 attr3
|
||||||
2 2 NULL NULL
|
2 2 NULL NULL
|
||||||
3 3 3 d
|
3 3 3 d
|
||||||
|
select * from t2 where attr3 is not null and attr1 > 2 order by pk1;
|
||||||
|
pk1 attr1 attr2 attr3
|
||||||
|
3 3 3 d
|
||||||
|
4 4 4 e
|
||||||
|
5 5 5 f
|
||||||
select * from t3 where attr2 > 9223372036854775803 and attr3 != 3 order by pk1;
|
select * from t3 where attr2 > 9223372036854775803 and attr3 != 3 order by pk1;
|
||||||
pk1 attr1 attr2 attr3 attr4
|
pk1 attr1 attr2 attr3 attr4
|
||||||
2 2 9223372036854775804 2 c
|
2 2 9223372036854775804 2 c
|
||||||
4 4 9223372036854775806 4 e
|
4 4 9223372036854775806 4 e
|
||||||
5 5 9223372036854775807 5 f
|
5 5 9223372036854775807 5 f
|
||||||
select * from t2,t3 where t2.attr1 > 1 and t2.attr2 = t3.attr2 and t3.attr1 < 5 order by t2.pk1;
|
select * from t2,t3 where t2.attr1 < 1 and t2.attr2 = t3.attr2 and t3.attr1 < 5 order by t2.pk1;
|
||||||
pk1 attr1 attr2 attr3 pk1 attr1 attr2 attr3 attr4
|
pk1 attr1 attr2 attr3 pk1 attr1 attr2 attr3 attr4
|
||||||
|
0 0 0 a 0 0 0 0 a
|
||||||
select * from t4 where attr1 < 5 and attr2 > 9223372036854775803 and attr3 != 3 order by t4.pk1;
|
select * from t4 where attr1 < 5 and attr2 > 9223372036854775803 and attr3 != 3 order by t4.pk1;
|
||||||
pk1 attr1 attr2 attr3 attr4
|
pk1 attr1 attr2 attr3 attr4
|
||||||
2 2 9223372036854775804 2 c
|
2 2 9223372036854775804 2 c
|
||||||
@ -257,8 +281,8 @@ set engine_condition_pushdown = on;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string = "aaaa" and
|
string = "aaaa" and
|
||||||
vstring = "aaaa" and
|
vstring = "aaaa" and
|
||||||
bin = "aaaa" and
|
/* bin = "aaaa" and
|
||||||
vbin = "aaaa" and
|
vbin = "aaaa" and */
|
||||||
tiny = -1 and
|
tiny = -1 and
|
||||||
short = -1 and
|
short = -1 and
|
||||||
medium = -1 and
|
medium = -1 and
|
||||||
@ -285,8 +309,8 @@ auto
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string != "aaaa" and
|
string != "aaaa" and
|
||||||
vstring != "aaaa" and
|
vstring != "aaaa" and
|
||||||
bin != "aaaa" and
|
/* bin != "aaaa" and
|
||||||
vbin != "aaaa" and
|
vbin != "aaaa" and */
|
||||||
tiny != -1 and
|
tiny != -1 and
|
||||||
short != -1 and
|
short != -1 and
|
||||||
medium != -1 and
|
medium != -1 and
|
||||||
@ -315,8 +339,8 @@ auto
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string > "aaaa" and
|
string > "aaaa" and
|
||||||
vstring > "aaaa" and
|
vstring > "aaaa" and
|
||||||
bin > "aaaa" and
|
/* bin > "aaaa" and
|
||||||
vbin > "aaaa" and
|
vbin > "aaaa" and */
|
||||||
tiny < -1 and
|
tiny < -1 and
|
||||||
short < -1 and
|
short < -1 and
|
||||||
medium < -1 and
|
medium < -1 and
|
||||||
@ -345,8 +369,8 @@ auto
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string >= "aaaa" and
|
string >= "aaaa" and
|
||||||
vstring >= "aaaa" and
|
vstring >= "aaaa" and
|
||||||
bin >= "aaaa" and
|
/* bin >= "aaaa" and
|
||||||
vbin >= "aaaa" and
|
vbin >= "aaaa" and */
|
||||||
tiny <= -1 and
|
tiny <= -1 and
|
||||||
short <= -1 and
|
short <= -1 and
|
||||||
medium <= -1 and
|
medium <= -1 and
|
||||||
@ -376,8 +400,8 @@ auto
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string < "dddd" and
|
string < "dddd" and
|
||||||
vstring < "dddd" and
|
vstring < "dddd" and
|
||||||
bin < "dddd" and
|
/* bin < "dddd" and
|
||||||
vbin < "dddd" and
|
vbin < "dddd" and */
|
||||||
tiny > -4 and
|
tiny > -4 and
|
||||||
short > -4 and
|
short > -4 and
|
||||||
medium > -4 and
|
medium > -4 and
|
||||||
@ -406,8 +430,8 @@ auto
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string <= "dddd" and
|
string <= "dddd" and
|
||||||
vstring <= "dddd" and
|
vstring <= "dddd" and
|
||||||
bin <= "dddd" and
|
/* bin <= "dddd" and
|
||||||
vbin <= "dddd" and
|
vbin <= "dddd" and */
|
||||||
tiny >= -4 and
|
tiny >= -4 and
|
||||||
short >= -4 and
|
short >= -4 and
|
||||||
medium >= -4 and
|
medium >= -4 and
|
||||||
@ -438,8 +462,8 @@ create index medium_index on t1(medium);
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string = "aaaa" and
|
string = "aaaa" and
|
||||||
vstring = "aaaa" and
|
vstring = "aaaa" and
|
||||||
bin = "aaaa" and
|
/* bin = "aaaa" and
|
||||||
vbin = "aaaa" and
|
vbin = "aaaa" and */
|
||||||
tiny = -1 and
|
tiny = -1 and
|
||||||
short = -1 and
|
short = -1 and
|
||||||
medium = -1 and
|
medium = -1 and
|
||||||
@ -466,8 +490,8 @@ auto
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string != "aaaa" and
|
string != "aaaa" and
|
||||||
vstring != "aaaa" and
|
vstring != "aaaa" and
|
||||||
bin != "aaaa" and
|
/* bin != "aaaa" and
|
||||||
vbin != "aaaa" and
|
vbin != "aaaa" and */
|
||||||
tiny != -1 and
|
tiny != -1 and
|
||||||
short != -1 and
|
short != -1 and
|
||||||
medium != -1 and
|
medium != -1 and
|
||||||
@ -496,8 +520,8 @@ auto
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string > "aaaa" and
|
string > "aaaa" and
|
||||||
vstring > "aaaa" and
|
vstring > "aaaa" and
|
||||||
bin > "aaaa" and
|
/* bin > "aaaa" and
|
||||||
vbin > "aaaa" and
|
vbin > "aaaa" and */
|
||||||
tiny < -1 and
|
tiny < -1 and
|
||||||
short < -1 and
|
short < -1 and
|
||||||
medium < -1 and
|
medium < -1 and
|
||||||
@ -526,8 +550,8 @@ auto
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string >= "aaaa" and
|
string >= "aaaa" and
|
||||||
vstring >= "aaaa" and
|
vstring >= "aaaa" and
|
||||||
bin >= "aaaa" and
|
/* bin >= "aaaa" and
|
||||||
vbin >= "aaaa" and
|
vbin >= "aaaa" and */
|
||||||
tiny <= -1 and
|
tiny <= -1 and
|
||||||
short <= -1 and
|
short <= -1 and
|
||||||
medium <= -1 and
|
medium <= -1 and
|
||||||
@ -557,8 +581,8 @@ auto
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string < "dddd" and
|
string < "dddd" and
|
||||||
vstring < "dddd" and
|
vstring < "dddd" and
|
||||||
bin < "dddd" and
|
/* bin < "dddd" and
|
||||||
vbin < "dddd" and
|
vbin < "dddd" and */
|
||||||
tiny > -4 and
|
tiny > -4 and
|
||||||
short > -4 and
|
short > -4 and
|
||||||
medium > -4 and
|
medium > -4 and
|
||||||
@ -587,8 +611,8 @@ auto
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string <= "dddd" and
|
string <= "dddd" and
|
||||||
vstring <= "dddd" and
|
vstring <= "dddd" and
|
||||||
bin <= "dddd" and
|
/* bin <= "dddd" and
|
||||||
vbin <= "dddd" and
|
vbin <= "dddd" and */
|
||||||
tiny >= -4 and
|
tiny >= -4 and
|
||||||
short >= -4 and
|
short >= -4 and
|
||||||
medium >= -4 and
|
medium >= -4 and
|
||||||
@ -615,17 +639,41 @@ auto
|
|||||||
2
|
2
|
||||||
3
|
3
|
||||||
4
|
4
|
||||||
|
select auto from t1 where
|
||||||
|
string like "b%" and
|
||||||
|
vstring like "b%" /* and
|
||||||
|
bin like "b%" and
|
||||||
|
vbin like "b%" */
|
||||||
|
order by auto;
|
||||||
|
auto
|
||||||
|
2
|
||||||
|
select auto from t1 where
|
||||||
|
string not like "b%" and
|
||||||
|
vstring not like "b%"/* and
|
||||||
|
bin not like "b%" and
|
||||||
|
vbin not like "b%" */
|
||||||
|
order by auto;
|
||||||
|
auto
|
||||||
|
1
|
||||||
|
3
|
||||||
|
4
|
||||||
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
|
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
|
||||||
pk1 attr1 attr2 attr3
|
pk1 attr1 attr2 attr3
|
||||||
2 2 NULL NULL
|
2 2 NULL NULL
|
||||||
3 3 3 d
|
3 3 3 d
|
||||||
|
select * from t2 where attr3 is not null and attr1 > 2 order by pk1;
|
||||||
|
pk1 attr1 attr2 attr3
|
||||||
|
3 3 3 d
|
||||||
|
4 4 4 e
|
||||||
|
5 5 5 f
|
||||||
select * from t3 where attr2 > 9223372036854775803 and attr3 != 3 order by pk1;
|
select * from t3 where attr2 > 9223372036854775803 and attr3 != 3 order by pk1;
|
||||||
pk1 attr1 attr2 attr3 attr4
|
pk1 attr1 attr2 attr3 attr4
|
||||||
2 2 9223372036854775804 2 c
|
2 2 9223372036854775804 2 c
|
||||||
4 4 9223372036854775806 4 e
|
4 4 9223372036854775806 4 e
|
||||||
5 5 9223372036854775807 5 f
|
5 5 9223372036854775807 5 f
|
||||||
select * from t2,t3 where t2.attr1 > 1 and t2.attr2 = t3.attr2 and t3.attr1 < 5 order by t2.pk1;
|
select * from t2,t3 where t2.attr1 < 1 and t2.attr2 = t3.attr2 and t3.attr1 < 5 order by t2.pk1;
|
||||||
pk1 attr1 attr2 attr3 pk1 attr1 attr2 attr3 attr4
|
pk1 attr1 attr2 attr3 pk1 attr1 attr2 attr3 attr4
|
||||||
|
0 0 0 a 0 0 0 0 a
|
||||||
select * from t4 where attr1 < 5 and attr2 > 9223372036854775803 and attr3 != 3 order by t4.pk1;
|
select * from t4 where attr1 < 5 and attr2 > 9223372036854775803 and attr3 != 3 order by t4.pk1;
|
||||||
pk1 attr1 attr2 attr3 attr4
|
pk1 attr1 attr2 attr3 attr4
|
||||||
2 2 9223372036854775804 2 c
|
2 2 9223372036854775804 2 c
|
||||||
@ -635,5 +683,15 @@ pk1 attr1 attr2 attr3 attr4 pk1 attr1 attr2 attr3 attr4
|
|||||||
2 2 9223372036854775804 2 c 2 2 9223372036854775804 2 c
|
2 2 9223372036854775804 2 c 2 2 9223372036854775804 2 c
|
||||||
3 3 9223372036854775805 3 d 3 3 9223372036854775805 3 d
|
3 3 9223372036854775805 3 d 3 3 9223372036854775805 3 d
|
||||||
4 4 9223372036854775806 4 e 4 4 9223372036854775806 4 e
|
4 4 9223372036854775806 4 e 4 4 9223372036854775806 4 e
|
||||||
|
select auto from t1 where string = "aaaa" collate latin1_general_ci order by auto;
|
||||||
|
auto
|
||||||
|
1
|
||||||
|
select * from t2 where (attr1 < 2) = (attr2 < 2) order by pk1;
|
||||||
|
pk1 attr1 attr2 attr3
|
||||||
|
0 0 0 a
|
||||||
|
1 1 1 b
|
||||||
|
3 3 3 d
|
||||||
|
4 4 4 e
|
||||||
|
5 5 5 f
|
||||||
set engine_condition_pushdown = @old_ecpd;
|
set engine_condition_pushdown = @old_ecpd;
|
||||||
DROP TABLE t1,t2,t3,t4;
|
DROP TABLE t1,t2,t3,t4;
|
||||||
|
@ -9,10 +9,10 @@ DROP TABLE IF EXISTS t1,t2;
|
|||||||
#
|
#
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
auto int(5) unsigned NOT NULL auto_increment,
|
auto int(5) unsigned NOT NULL auto_increment,
|
||||||
string char(10) default "hello",
|
string char(10),
|
||||||
vstring varchar(10) default "hello",
|
vstring varchar(10),
|
||||||
bin binary(7) default "hello",
|
bin binary(7),
|
||||||
vbin varbinary(7) default "hello",
|
vbin varbinary(7),
|
||||||
tiny tinyint(4) DEFAULT '0' NOT NULL ,
|
tiny tinyint(4) DEFAULT '0' NOT NULL ,
|
||||||
short smallint(6) DEFAULT '1' NOT NULL ,
|
short smallint(6) DEFAULT '1' NOT NULL ,
|
||||||
medium mediumint(8) DEFAULT '0' NOT NULL,
|
medium mediumint(8) DEFAULT '0' NOT NULL,
|
||||||
@ -233,10 +233,26 @@ time_field <= '04:04:04' and
|
|||||||
date_time <= '1904-04-04 04:04:04'
|
date_time <= '1904-04-04 04:04:04'
|
||||||
order by auto;
|
order by auto;
|
||||||
|
|
||||||
|
# Test LIKE/NOT LIKE
|
||||||
|
select auto from t1 where
|
||||||
|
string like "b%" and
|
||||||
|
vstring like "b%" and
|
||||||
|
bin like "b%" and
|
||||||
|
vbin like "b%"
|
||||||
|
order by auto;
|
||||||
|
|
||||||
|
select auto from t1 where
|
||||||
|
string not like "b%" and
|
||||||
|
vstring not like "b%" and
|
||||||
|
bin not like "b%" and
|
||||||
|
vbin not like "b%"
|
||||||
|
order by auto;
|
||||||
|
|
||||||
# Various tests
|
# Various tests
|
||||||
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
|
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
|
||||||
|
select * from t2 where attr3 is not null and attr1 > 2 order by pk1;
|
||||||
select * from t3 where attr2 > 9223372036854775803 and attr3 != 3 order by pk1;
|
select * from t3 where attr2 > 9223372036854775803 and attr3 != 3 order by pk1;
|
||||||
select * from t2,t3 where t2.attr1 > 1 and t2.attr2 = t3.attr2 and t3.attr1 < 5 order by t2.pk1;
|
select * from t2,t3 where t2.attr1 < 1 and t2.attr2 = t3.attr2 and t3.attr1 < 5 order by t2.pk1;
|
||||||
select * from t4 where attr1 < 5 and attr2 > 9223372036854775803 and attr3 != 3 order by t4.pk1;
|
select * from t4 where attr1 < 5 and attr2 > 9223372036854775803 and attr3 != 3 order by t4.pk1;
|
||||||
select * from t3,t4 where t4.attr1 > 1 and t4.attr2 = t3.attr2 and t4.attr3 < 5 order by t4.pk1;
|
select * from t3,t4 where t4.attr1 > 1 and t4.attr2 = t3.attr2 and t4.attr3 < 5 order by t4.pk1;
|
||||||
|
|
||||||
@ -246,8 +262,8 @@ set engine_condition_pushdown = on;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string = "aaaa" and
|
string = "aaaa" and
|
||||||
vstring = "aaaa" and
|
vstring = "aaaa" and
|
||||||
bin = "aaaa" and
|
/* bin = "aaaa" and
|
||||||
vbin = "aaaa" and
|
vbin = "aaaa" and */
|
||||||
tiny = -1 and
|
tiny = -1 and
|
||||||
short = -1 and
|
short = -1 and
|
||||||
medium = -1 and
|
medium = -1 and
|
||||||
@ -273,8 +289,8 @@ order by auto;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string != "aaaa" and
|
string != "aaaa" and
|
||||||
vstring != "aaaa" and
|
vstring != "aaaa" and
|
||||||
bin != "aaaa" and
|
/* bin != "aaaa" and
|
||||||
vbin != "aaaa" and
|
vbin != "aaaa" and */
|
||||||
tiny != -1 and
|
tiny != -1 and
|
||||||
short != -1 and
|
short != -1 and
|
||||||
medium != -1 and
|
medium != -1 and
|
||||||
@ -300,8 +316,8 @@ order by auto;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string > "aaaa" and
|
string > "aaaa" and
|
||||||
vstring > "aaaa" and
|
vstring > "aaaa" and
|
||||||
bin > "aaaa" and
|
/* bin > "aaaa" and
|
||||||
vbin > "aaaa" and
|
vbin > "aaaa" and */
|
||||||
tiny < -1 and
|
tiny < -1 and
|
||||||
short < -1 and
|
short < -1 and
|
||||||
medium < -1 and
|
medium < -1 and
|
||||||
@ -327,8 +343,8 @@ order by auto;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string >= "aaaa" and
|
string >= "aaaa" and
|
||||||
vstring >= "aaaa" and
|
vstring >= "aaaa" and
|
||||||
bin >= "aaaa" and
|
/* bin >= "aaaa" and
|
||||||
vbin >= "aaaa" and
|
vbin >= "aaaa" and */
|
||||||
tiny <= -1 and
|
tiny <= -1 and
|
||||||
short <= -1 and
|
short <= -1 and
|
||||||
medium <= -1 and
|
medium <= -1 and
|
||||||
@ -354,8 +370,8 @@ order by auto;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string < "dddd" and
|
string < "dddd" and
|
||||||
vstring < "dddd" and
|
vstring < "dddd" and
|
||||||
bin < "dddd" and
|
/* bin < "dddd" and
|
||||||
vbin < "dddd" and
|
vbin < "dddd" and */
|
||||||
tiny > -4 and
|
tiny > -4 and
|
||||||
short > -4 and
|
short > -4 and
|
||||||
medium > -4 and
|
medium > -4 and
|
||||||
@ -381,8 +397,8 @@ order by auto;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string <= "dddd" and
|
string <= "dddd" and
|
||||||
vstring <= "dddd" and
|
vstring <= "dddd" and
|
||||||
bin <= "dddd" and
|
/* bin <= "dddd" and
|
||||||
vbin <= "dddd" and
|
vbin <= "dddd" and */
|
||||||
tiny >= -4 and
|
tiny >= -4 and
|
||||||
short >= -4 and
|
short >= -4 and
|
||||||
medium >= -4 and
|
medium >= -4 and
|
||||||
@ -412,8 +428,8 @@ create index medium_index on t1(medium);
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string = "aaaa" and
|
string = "aaaa" and
|
||||||
vstring = "aaaa" and
|
vstring = "aaaa" and
|
||||||
bin = "aaaa" and
|
/* bin = "aaaa" and
|
||||||
vbin = "aaaa" and
|
vbin = "aaaa" and */
|
||||||
tiny = -1 and
|
tiny = -1 and
|
||||||
short = -1 and
|
short = -1 and
|
||||||
medium = -1 and
|
medium = -1 and
|
||||||
@ -439,8 +455,8 @@ order by auto;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string != "aaaa" and
|
string != "aaaa" and
|
||||||
vstring != "aaaa" and
|
vstring != "aaaa" and
|
||||||
bin != "aaaa" and
|
/* bin != "aaaa" and
|
||||||
vbin != "aaaa" and
|
vbin != "aaaa" and */
|
||||||
tiny != -1 and
|
tiny != -1 and
|
||||||
short != -1 and
|
short != -1 and
|
||||||
medium != -1 and
|
medium != -1 and
|
||||||
@ -466,8 +482,8 @@ order by auto;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string > "aaaa" and
|
string > "aaaa" and
|
||||||
vstring > "aaaa" and
|
vstring > "aaaa" and
|
||||||
bin > "aaaa" and
|
/* bin > "aaaa" and
|
||||||
vbin > "aaaa" and
|
vbin > "aaaa" and */
|
||||||
tiny < -1 and
|
tiny < -1 and
|
||||||
short < -1 and
|
short < -1 and
|
||||||
medium < -1 and
|
medium < -1 and
|
||||||
@ -493,8 +509,8 @@ order by auto;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string >= "aaaa" and
|
string >= "aaaa" and
|
||||||
vstring >= "aaaa" and
|
vstring >= "aaaa" and
|
||||||
bin >= "aaaa" and
|
/* bin >= "aaaa" and
|
||||||
vbin >= "aaaa" and
|
vbin >= "aaaa" and */
|
||||||
tiny <= -1 and
|
tiny <= -1 and
|
||||||
short <= -1 and
|
short <= -1 and
|
||||||
medium <= -1 and
|
medium <= -1 and
|
||||||
@ -520,8 +536,8 @@ order by auto;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string < "dddd" and
|
string < "dddd" and
|
||||||
vstring < "dddd" and
|
vstring < "dddd" and
|
||||||
bin < "dddd" and
|
/* bin < "dddd" and
|
||||||
vbin < "dddd" and
|
vbin < "dddd" and */
|
||||||
tiny > -4 and
|
tiny > -4 and
|
||||||
short > -4 and
|
short > -4 and
|
||||||
medium > -4 and
|
medium > -4 and
|
||||||
@ -547,8 +563,8 @@ order by auto;
|
|||||||
select auto from t1 where
|
select auto from t1 where
|
||||||
string <= "dddd" and
|
string <= "dddd" and
|
||||||
vstring <= "dddd" and
|
vstring <= "dddd" and
|
||||||
bin <= "dddd" and
|
/* bin <= "dddd" and
|
||||||
vbin <= "dddd" and
|
vbin <= "dddd" and */
|
||||||
tiny >= -4 and
|
tiny >= -4 and
|
||||||
short >= -4 and
|
short >= -4 and
|
||||||
medium >= -4 and
|
medium >= -4 and
|
||||||
@ -571,11 +587,32 @@ time_field <= '04:04:04' and
|
|||||||
date_time <= '1904-04-04 04:04:04'
|
date_time <= '1904-04-04 04:04:04'
|
||||||
order by auto;
|
order by auto;
|
||||||
|
|
||||||
|
# Test LIKE/NOT LIKE
|
||||||
|
select auto from t1 where
|
||||||
|
string like "b%" and
|
||||||
|
vstring like "b%" /* and
|
||||||
|
bin like "b%" and
|
||||||
|
vbin like "b%" */
|
||||||
|
order by auto;
|
||||||
|
|
||||||
|
select auto from t1 where
|
||||||
|
string not like "b%" and
|
||||||
|
vstring not like "b%"/* and
|
||||||
|
bin not like "b%" and
|
||||||
|
vbin not like "b%" */
|
||||||
|
order by auto;
|
||||||
|
|
||||||
# Various tests
|
# Various tests
|
||||||
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
|
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
|
||||||
|
select * from t2 where attr3 is not null and attr1 > 2 order by pk1;
|
||||||
select * from t3 where attr2 > 9223372036854775803 and attr3 != 3 order by pk1;
|
select * from t3 where attr2 > 9223372036854775803 and attr3 != 3 order by pk1;
|
||||||
select * from t2,t3 where t2.attr1 > 1 and t2.attr2 = t3.attr2 and t3.attr1 < 5 order by t2.pk1;
|
select * from t2,t3 where t2.attr1 < 1 and t2.attr2 = t3.attr2 and t3.attr1 < 5 order by t2.pk1;
|
||||||
select * from t4 where attr1 < 5 and attr2 > 9223372036854775803 and attr3 != 3 order by t4.pk1;
|
select * from t4 where attr1 < 5 and attr2 > 9223372036854775803 and attr3 != 3 order by t4.pk1;
|
||||||
select * from t3,t4 where t4.attr1 > 1 and t4.attr2 = t3.attr2 and t4.attr3 < 5 order by t4.pk1;
|
select * from t3,t4 where t4.attr1 > 1 and t4.attr2 = t3.attr2 and t4.attr3 < 5 order by t4.pk1;
|
||||||
|
|
||||||
|
# Some tests that are currently not supported and should not push condition
|
||||||
|
select auto from t1 where string = "aaaa" collate latin1_general_ci order by auto;
|
||||||
|
select * from t2 where (attr1 < 2) = (attr2 < 2) order by pk1;
|
||||||
|
|
||||||
set engine_condition_pushdown = @old_ecpd;
|
set engine_condition_pushdown = @old_ecpd;
|
||||||
DROP TABLE t1,t2,t3,t4;
|
DROP TABLE t1,t2,t3,t4;
|
||||||
|
@ -5930,6 +5930,7 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
// Expect char string or binary string
|
// Expect char string or binary string
|
||||||
context->expect_only(Item::STRING_ITEM);
|
context->expect_only(Item::STRING_ITEM);
|
||||||
context->expect(Item::VARBIN_ITEM);
|
context->expect(Item::VARBIN_ITEM);
|
||||||
|
context->expect_collation(field_item->collation.collation);
|
||||||
break;
|
break;
|
||||||
case(REAL_RESULT):
|
case(REAL_RESULT):
|
||||||
context->expect_only(Item::REAL_ITEM);
|
context->expect_only(Item::REAL_ITEM);
|
||||||
@ -5945,7 +5946,22 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Expect another logical expression
|
||||||
|
context->expect_only(Item::FUNC_ITEM);
|
||||||
|
context->expect(Item::COND_ITEM);
|
||||||
|
// Check that field and string constant collations are the same
|
||||||
|
if ((field->result_type() == STRING_RESULT) &&
|
||||||
|
!context->expecting_collation(item->collation.collation))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info", ("Found non-matching collations %s and %s",
|
||||||
|
item->collation.collation->name,
|
||||||
|
context->collation->name));
|
||||||
|
context->supported= FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -5957,12 +5973,22 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item::FUNC_ITEM): {
|
case(Item::FUNC_ITEM): {
|
||||||
Item_func *func_item= (Item_func *) item;
|
Item_func *func_item= (Item_func *) item;
|
||||||
|
// Check that we expect a function or functional expression here
|
||||||
|
if (context->expecting(Item::FUNC_ITEM) ||
|
||||||
|
func_item->functype() == Item_func::UNKNOWN_FUNC)
|
||||||
|
context->expect_nothing();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Did not expect function here
|
||||||
|
context->supported= FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
context->expect_nothing();
|
|
||||||
switch(func_item->functype()) {
|
switch(func_item->functype()) {
|
||||||
case(Item_func::EQ_FUNC): {
|
case(Item_func::EQ_FUNC): {
|
||||||
DBUG_PRINT("info", ("EQ_FUNC"));
|
DBUG_PRINT("info", ("EQ_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::STRING_ITEM);
|
context->expect(Item::STRING_ITEM);
|
||||||
context->expect(Item::INT_ITEM);
|
context->expect(Item::INT_ITEM);
|
||||||
context->expect(Item::REAL_ITEM);
|
context->expect(Item::REAL_ITEM);
|
||||||
@ -5977,7 +6003,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item_func::NE_FUNC): {
|
case(Item_func::NE_FUNC): {
|
||||||
DBUG_PRINT("info", ("NE_FUNC"));
|
DBUG_PRINT("info", ("NE_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::STRING_ITEM);
|
context->expect(Item::STRING_ITEM);
|
||||||
context->expect(Item::INT_ITEM);
|
context->expect(Item::INT_ITEM);
|
||||||
context->expect(Item::REAL_ITEM);
|
context->expect(Item::REAL_ITEM);
|
||||||
@ -5992,7 +6019,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item_func::LT_FUNC): {
|
case(Item_func::LT_FUNC): {
|
||||||
DBUG_PRINT("info", ("LT_FUNC"));
|
DBUG_PRINT("info", ("LT_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::STRING_ITEM);
|
context->expect(Item::STRING_ITEM);
|
||||||
context->expect(Item::INT_ITEM);
|
context->expect(Item::INT_ITEM);
|
||||||
context->expect(Item::REAL_ITEM);
|
context->expect(Item::REAL_ITEM);
|
||||||
@ -6007,7 +6035,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item_func::LE_FUNC): {
|
case(Item_func::LE_FUNC): {
|
||||||
DBUG_PRINT("info", ("LE_FUNC"));
|
DBUG_PRINT("info", ("LE_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::STRING_ITEM);
|
context->expect(Item::STRING_ITEM);
|
||||||
context->expect(Item::INT_ITEM);
|
context->expect(Item::INT_ITEM);
|
||||||
context->expect(Item::REAL_ITEM);
|
context->expect(Item::REAL_ITEM);
|
||||||
@ -6022,7 +6051,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item_func::GE_FUNC): {
|
case(Item_func::GE_FUNC): {
|
||||||
DBUG_PRINT("info", ("GE_FUNC"));
|
DBUG_PRINT("info", ("GE_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::STRING_ITEM);
|
context->expect(Item::STRING_ITEM);
|
||||||
context->expect(Item::INT_ITEM);
|
context->expect(Item::INT_ITEM);
|
||||||
context->expect(Item::REAL_ITEM);
|
context->expect(Item::REAL_ITEM);
|
||||||
@ -6037,7 +6067,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item_func::GT_FUNC): {
|
case(Item_func::GT_FUNC): {
|
||||||
DBUG_PRINT("info", ("GT_FUNC"));
|
DBUG_PRINT("info", ("GT_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::STRING_ITEM);
|
context->expect(Item::STRING_ITEM);
|
||||||
context->expect(Item::REAL_ITEM);
|
context->expect(Item::REAL_ITEM);
|
||||||
context->expect(Item::DECIMAL_ITEM);
|
context->expect(Item::DECIMAL_ITEM);
|
||||||
@ -6052,7 +6083,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item_func::LIKE_FUNC): {
|
case(Item_func::LIKE_FUNC): {
|
||||||
DBUG_PRINT("info", ("LIKE_FUNC"));
|
DBUG_PRINT("info", ("LIKE_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::STRING_ITEM);
|
context->expect(Item::STRING_ITEM);
|
||||||
context->expect(Item::FIELD_ITEM);
|
context->expect(Item::FIELD_ITEM);
|
||||||
context->expect_field_result(STRING_RESULT);
|
context->expect_field_result(STRING_RESULT);
|
||||||
@ -6060,7 +6092,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item_func::NOTLIKE_FUNC): {
|
case(Item_func::NOTLIKE_FUNC): {
|
||||||
DBUG_PRINT("info", ("NOTLIKE_FUNC"));
|
DBUG_PRINT("info", ("NOTLIKE_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::STRING_ITEM);
|
context->expect(Item::STRING_ITEM);
|
||||||
context->expect(Item::FIELD_ITEM);
|
context->expect(Item::FIELD_ITEM);
|
||||||
context->expect_field_result(STRING_RESULT);
|
context->expect_field_result(STRING_RESULT);
|
||||||
@ -6068,7 +6101,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item_func::ISNULL_FUNC): {
|
case(Item_func::ISNULL_FUNC): {
|
||||||
DBUG_PRINT("info", ("ISNULL_FUNC"));
|
DBUG_PRINT("info", ("ISNULL_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::FIELD_ITEM);
|
context->expect(Item::FIELD_ITEM);
|
||||||
context->expect_field_result(STRING_RESULT);
|
context->expect_field_result(STRING_RESULT);
|
||||||
context->expect_field_result(REAL_RESULT);
|
context->expect_field_result(REAL_RESULT);
|
||||||
@ -6078,7 +6112,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item_func::ISNOTNULL_FUNC): {
|
case(Item_func::ISNOTNULL_FUNC): {
|
||||||
DBUG_PRINT("info", ("ISNOTNULL_FUNC"));
|
DBUG_PRINT("info", ("ISNOTNULL_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::FIELD_ITEM);
|
context->expect(Item::FIELD_ITEM);
|
||||||
context->expect_field_result(STRING_RESULT);
|
context->expect_field_result(STRING_RESULT);
|
||||||
context->expect_field_result(REAL_RESULT);
|
context->expect_field_result(REAL_RESULT);
|
||||||
@ -6088,7 +6123,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
}
|
}
|
||||||
case(Item_func::NOT_FUNC): {
|
case(Item_func::NOT_FUNC): {
|
||||||
DBUG_PRINT("info", ("NOT_FUNC"));
|
DBUG_PRINT("info", ("NOT_FUNC"));
|
||||||
curr_cond->ndb_item= new Ndb_item(func_item->functype());
|
curr_cond->ndb_item= new Ndb_item(func_item->functype(),
|
||||||
|
func_item);
|
||||||
context->expect(Item::FUNC_ITEM);
|
context->expect(Item::FUNC_ITEM);
|
||||||
context->expect(Item::COND_ITEM);
|
context->expect(Item::COND_ITEM);
|
||||||
break;
|
break;
|
||||||
@ -6102,16 +6138,28 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
case(STRING_RESULT): {
|
case(STRING_RESULT): {
|
||||||
NDB_ITEM_QUALIFICATION q;
|
NDB_ITEM_QUALIFICATION q;
|
||||||
q.value_type= Item::STRING_ITEM;
|
q.value_type= Item::STRING_ITEM;
|
||||||
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
|
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
|
||||||
if (context->expect_field_result_mask)
|
if (context->expect_field_result_mask)
|
||||||
{
|
{
|
||||||
// We have not seen the field argument yet
|
// We have not seen the field argument yet
|
||||||
context->expect_only(Item::FIELD_ITEM);
|
context->expect_only(Item::FIELD_ITEM);
|
||||||
context->expect_only_field_result(STRING_RESULT);
|
context->expect_only_field_result(STRING_RESULT);
|
||||||
|
context->expect_collation(func_item->collation.collation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->expect_nothing();
|
{
|
||||||
|
// Expect another logical expression
|
||||||
|
context->expect_only(Item::FUNC_ITEM);
|
||||||
|
context->expect(Item::COND_ITEM);
|
||||||
|
// Check that string result have correct collation
|
||||||
|
if (!context->expecting_collation(item->collation.collation))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info", ("Found non-matching collations %s and %s",
|
||||||
|
item->collation.collation->name,
|
||||||
|
context->collation->name));
|
||||||
|
context->supported= FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Skip any arguments since we will evaluate function instead
|
// Skip any arguments since we will evaluate function instead
|
||||||
DBUG_PRINT("info", ("Skip until end of arguments marker"));
|
DBUG_PRINT("info", ("Skip until end of arguments marker"));
|
||||||
context->skip= func_item->argument_count();
|
context->skip= func_item->argument_count();
|
||||||
@ -6128,7 +6176,11 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_only_field_result(REAL_RESULT);
|
context->expect_only_field_result(REAL_RESULT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->expect_nothing();
|
{
|
||||||
|
// Expect another logical expression
|
||||||
|
context->expect_only(Item::FUNC_ITEM);
|
||||||
|
context->expect(Item::COND_ITEM);
|
||||||
|
}
|
||||||
|
|
||||||
// Skip any arguments since we will evaluate function instead
|
// Skip any arguments since we will evaluate function instead
|
||||||
DBUG_PRINT("info", ("Skip until end of arguments marker"));
|
DBUG_PRINT("info", ("Skip until end of arguments marker"));
|
||||||
@ -6146,7 +6198,11 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_only_field_result(INT_RESULT);
|
context->expect_only_field_result(INT_RESULT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->expect_nothing();
|
{
|
||||||
|
// Expect another logical expression
|
||||||
|
context->expect_only(Item::FUNC_ITEM);
|
||||||
|
context->expect(Item::COND_ITEM);
|
||||||
|
}
|
||||||
|
|
||||||
// Skip any arguments since we will evaluate function instead
|
// Skip any arguments since we will evaluate function instead
|
||||||
DBUG_PRINT("info", ("Skip until end of arguments marker"));
|
DBUG_PRINT("info", ("Skip until end of arguments marker"));
|
||||||
@ -6164,8 +6220,11 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_only_field_result(DECIMAL_RESULT);
|
context->expect_only_field_result(DECIMAL_RESULT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->expect_nothing();
|
{
|
||||||
|
// Expect another logical expression
|
||||||
|
context->expect_only(Item::FUNC_ITEM);
|
||||||
|
context->expect(Item::COND_ITEM);
|
||||||
|
}
|
||||||
// Skip any arguments since we will evaluate function instead
|
// Skip any arguments since we will evaluate function instead
|
||||||
DBUG_PRINT("info", ("Skip until end of arguments marker"));
|
DBUG_PRINT("info", ("Skip until end of arguments marker"));
|
||||||
context->skip= func_item->argument_count();
|
context->skip= func_item->argument_count();
|
||||||
@ -6207,9 +6266,22 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
// We have not seen the field argument yet
|
// We have not seen the field argument yet
|
||||||
context->expect_only(Item::FIELD_ITEM);
|
context->expect_only(Item::FIELD_ITEM);
|
||||||
context->expect_only_field_result(STRING_RESULT);
|
context->expect_only_field_result(STRING_RESULT);
|
||||||
|
context->expect_collation(item->collation.collation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->expect_nothing();
|
{
|
||||||
|
// Expect another logical expression
|
||||||
|
context->expect_only(Item::FUNC_ITEM);
|
||||||
|
context->expect(Item::COND_ITEM);
|
||||||
|
// Check that we are comparing with a field with same collation
|
||||||
|
if (!context->expecting_collation(item->collation.collation))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info", ("Found non-matching collations %s and %s",
|
||||||
|
item->collation.collation->name,
|
||||||
|
context->collation->name));
|
||||||
|
context->supported= FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
@ -6230,7 +6302,11 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_only_field_result(INT_RESULT);
|
context->expect_only_field_result(INT_RESULT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->expect_nothing();
|
{
|
||||||
|
// Expect another logical expression
|
||||||
|
context->expect_only(Item::FUNC_ITEM);
|
||||||
|
context->expect(Item::COND_ITEM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
@ -6251,7 +6327,11 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_only_field_result(REAL_RESULT);
|
context->expect_only_field_result(REAL_RESULT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->expect_nothing();
|
{
|
||||||
|
// Expect another logical expression
|
||||||
|
context->expect_only(Item::FUNC_ITEM);
|
||||||
|
context->expect(Item::COND_ITEM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
@ -6278,7 +6358,11 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_only_field_result(STRING_RESULT);
|
context->expect_only_field_result(STRING_RESULT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->expect_nothing();
|
{
|
||||||
|
// Expect another logical expression
|
||||||
|
context->expect_only(Item::FUNC_ITEM);
|
||||||
|
context->expect(Item::COND_ITEM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
@ -6300,27 +6384,38 @@ void ndb_serialize_cond(const Item *item, void *arg)
|
|||||||
context->expect_field_result(DECIMAL_RESULT);
|
context->expect_field_result(DECIMAL_RESULT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->expect_nothing();
|
{
|
||||||
|
// Expect another logical expression
|
||||||
|
context->expect_only(Item::FUNC_ITEM);
|
||||||
|
context->expect(Item::COND_ITEM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->supported= FALSE;
|
context->supported= FALSE;
|
||||||
break;
|
break;
|
||||||
case(Item::COND_ITEM): {
|
case(Item::COND_ITEM): {
|
||||||
Item_cond *cond_item= (Item_cond *) item;
|
Item_cond *cond_item= (Item_cond *) item;
|
||||||
switch(cond_item->functype()) {
|
|
||||||
case(Item_func::COND_AND_FUNC):
|
if (context->expecting(Item::COND_ITEM))
|
||||||
DBUG_PRINT("info", ("COND_AND_FUNC"));
|
switch(cond_item->functype()) {
|
||||||
curr_cond->ndb_item= new Ndb_item(cond_item->functype());
|
case(Item_func::COND_AND_FUNC):
|
||||||
break;
|
DBUG_PRINT("info", ("COND_AND_FUNC"));
|
||||||
case(Item_func::COND_OR_FUNC):
|
curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
|
||||||
DBUG_PRINT("info", ("COND_OR_FUNC"));
|
cond_item);
|
||||||
curr_cond->ndb_item= new Ndb_item(cond_item->functype());
|
break;
|
||||||
break;
|
case(Item_func::COND_OR_FUNC):
|
||||||
default:
|
DBUG_PRINT("info", ("COND_OR_FUNC"));
|
||||||
DBUG_PRINT("info", ("COND_ITEM %d", cond_item->functype()));
|
curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
|
||||||
context->supported= FALSE;
|
cond_item);
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
|
DBUG_PRINT("info", ("COND_ITEM %d", cond_item->functype()));
|
||||||
|
context->supported= FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Did not expect condition
|
||||||
|
context->supported= FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -6339,6 +6434,9 @@ ha_ndbcluster::serialize_cond(const COND *cond, Ndb_cond_stack *ndb_cond)
|
|||||||
DBUG_ENTER("serialize_cond");
|
DBUG_ENTER("serialize_cond");
|
||||||
Item *item= (Item *) cond;
|
Item *item= (Item *) cond;
|
||||||
Ndb_cond_traverse_context context(table, (void *)m_table, ndb_cond);
|
Ndb_cond_traverse_context context(table, (void *)m_table, ndb_cond);
|
||||||
|
// Expect a logical expression
|
||||||
|
context.expect(Item::FUNC_ITEM);
|
||||||
|
context.expect(Item::COND_ITEM);
|
||||||
item->traverse_cond(&ndb_serialize_cond, (void *) &context, Item::PREFIX);
|
item->traverse_cond(&ndb_serialize_cond, (void *) &context, Item::PREFIX);
|
||||||
DBUG_PRINT("info", ("The pushed condition is %ssupported", (context.supported)?"":"not "));
|
DBUG_PRINT("info", ("The pushed condition is %ssupported", (context.supported)?"":"not "));
|
||||||
|
|
||||||
@ -6356,22 +6454,33 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
if (!cond->next)
|
if (!cond->next)
|
||||||
break;
|
break;
|
||||||
Ndb_item *a= cond->next->ndb_item;
|
Ndb_item *a= cond->next->ndb_item;
|
||||||
|
Ndb_item *b, *field, *value= NULL;
|
||||||
|
switch(cond->ndb_item->argument_count()) {
|
||||||
|
case(1):
|
||||||
|
field=
|
||||||
|
(a->type == NDB_FIELD)? a : NULL;
|
||||||
|
break;
|
||||||
|
case(2):
|
||||||
|
if (!cond->next->next)
|
||||||
|
break;
|
||||||
|
b= cond->next->next->ndb_item;
|
||||||
|
value=
|
||||||
|
(a->type == NDB_VALUE)? a
|
||||||
|
: (b->type == NDB_VALUE)? b
|
||||||
|
: NULL;
|
||||||
|
field=
|
||||||
|
(a->type == NDB_FIELD)? a
|
||||||
|
: (b->type == NDB_FIELD)? b
|
||||||
|
: NULL;
|
||||||
|
break;
|
||||||
|
deafult:
|
||||||
|
break;
|
||||||
|
}
|
||||||
switch((negated) ?
|
switch((negated) ?
|
||||||
Ndb_item::negate(cond->ndb_item->qualification.function_type)
|
Ndb_item::negate(cond->ndb_item->qualification.function_type)
|
||||||
: cond->ndb_item->qualification.function_type)
|
: cond->ndb_item->qualification.function_type)
|
||||||
{
|
{
|
||||||
case(Item_func::EQ_FUNC): {
|
case(Item_func::EQ_FUNC): {
|
||||||
if (!cond->next->next)
|
|
||||||
break;
|
|
||||||
Ndb_item *b= cond->next->next->ndb_item;
|
|
||||||
Ndb_item *value=
|
|
||||||
(a->type == NDB_VALUE)? a
|
|
||||||
: (b->type == NDB_VALUE)? b
|
|
||||||
: NULL;
|
|
||||||
Ndb_item *field=
|
|
||||||
(a->type == NDB_FIELD)? a
|
|
||||||
: (b->type == NDB_FIELD)? b
|
|
||||||
: NULL;
|
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -6385,17 +6494,6 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::NE_FUNC): {
|
case(Item_func::NE_FUNC): {
|
||||||
if (!cond->next->next)
|
|
||||||
break;
|
|
||||||
Ndb_item *b= cond->next->next->ndb_item;
|
|
||||||
Ndb_item *value=
|
|
||||||
(a->type == NDB_VALUE)? a
|
|
||||||
: (b->type == NDB_VALUE)? b
|
|
||||||
: NULL;
|
|
||||||
Ndb_item *field=
|
|
||||||
(a->type == NDB_FIELD)? a
|
|
||||||
: (b->type == NDB_FIELD)? b
|
|
||||||
: NULL;
|
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -6409,17 +6507,6 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::LT_FUNC): {
|
case(Item_func::LT_FUNC): {
|
||||||
if (!cond->next->next)
|
|
||||||
break;
|
|
||||||
Ndb_item *b= cond->next->next->ndb_item;
|
|
||||||
Ndb_item *value=
|
|
||||||
(a->type == NDB_VALUE)? a
|
|
||||||
: (b->type == NDB_VALUE)? b
|
|
||||||
: NULL;
|
|
||||||
Ndb_item *field=
|
|
||||||
(a->type == NDB_FIELD)? a
|
|
||||||
: (b->type == NDB_FIELD)? b
|
|
||||||
: NULL;
|
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -6445,17 +6532,6 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::LE_FUNC): {
|
case(Item_func::LE_FUNC): {
|
||||||
if (!cond->next->next)
|
|
||||||
break;
|
|
||||||
Ndb_item *b= cond->next->next->ndb_item;
|
|
||||||
Ndb_item *value=
|
|
||||||
(a->type == NDB_VALUE)? a
|
|
||||||
: (b->type == NDB_VALUE)? b
|
|
||||||
: NULL;
|
|
||||||
Ndb_item *field=
|
|
||||||
(a->type == NDB_FIELD)? a
|
|
||||||
: (b->type == NDB_FIELD)? b
|
|
||||||
: NULL;
|
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -6481,17 +6557,6 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::GE_FUNC): {
|
case(Item_func::GE_FUNC): {
|
||||||
if (!cond->next->next)
|
|
||||||
break;
|
|
||||||
Ndb_item *b= cond->next->next->ndb_item;
|
|
||||||
Ndb_item *value=
|
|
||||||
(a->type == NDB_VALUE)? a
|
|
||||||
: (b->type == NDB_VALUE)? b
|
|
||||||
: NULL;
|
|
||||||
Ndb_item *field=
|
|
||||||
(a->type == NDB_FIELD)? a
|
|
||||||
: (b->type == NDB_FIELD)? b
|
|
||||||
: NULL;
|
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -6517,17 +6582,6 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::GT_FUNC): {
|
case(Item_func::GT_FUNC): {
|
||||||
if (!cond->next->next)
|
|
||||||
break;
|
|
||||||
Ndb_item *b= cond->next->next->ndb_item;
|
|
||||||
Ndb_item *value=
|
|
||||||
(a->type == NDB_VALUE)? a
|
|
||||||
: (b->type == NDB_VALUE)? b
|
|
||||||
: NULL;
|
|
||||||
Ndb_item *field=
|
|
||||||
(a->type == NDB_FIELD)? a
|
|
||||||
: (b->type == NDB_FIELD)? b
|
|
||||||
: NULL;
|
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
value->save_in_field(field);
|
value->save_in_field(field);
|
||||||
@ -6553,17 +6607,6 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::LIKE_FUNC): {
|
case(Item_func::LIKE_FUNC): {
|
||||||
if (!cond->next->next)
|
|
||||||
break;
|
|
||||||
Ndb_item *b= cond->next->next->ndb_item;
|
|
||||||
Ndb_item *value=
|
|
||||||
(a->type == NDB_VALUE)? a
|
|
||||||
: (b->type == NDB_VALUE)? b
|
|
||||||
: NULL;
|
|
||||||
Ndb_item *field=
|
|
||||||
(a->type == NDB_FIELD)? a
|
|
||||||
: (b->type == NDB_FIELD)? b
|
|
||||||
: NULL;
|
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
if (value->qualification.value_type != Item::STRING_ITEM) break;
|
if (value->qualification.value_type != Item::STRING_ITEM) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
@ -6573,24 +6616,13 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
value->pack_length()));
|
value->pack_length()));
|
||||||
if (filter->cmp(NdbScanFilter::COND_LIKE,
|
if (filter->cmp(NdbScanFilter::COND_LIKE,
|
||||||
field->get_field_no(),
|
field->get_field_no(),
|
||||||
field->get_val(),
|
value->get_val(),
|
||||||
field->pack_length()) == -1)
|
value->pack_length()) == -1)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
cond= cond->next->next->next;
|
cond= cond->next->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::NOTLIKE_FUNC): {
|
case(Item_func::NOTLIKE_FUNC): {
|
||||||
if (!cond->next->next)
|
|
||||||
break;
|
|
||||||
Ndb_item *b= cond->next->next->ndb_item;
|
|
||||||
Ndb_item *value=
|
|
||||||
(a->type == NDB_VALUE)? a
|
|
||||||
: (b->type == NDB_VALUE)? b
|
|
||||||
: NULL;
|
|
||||||
Ndb_item *field=
|
|
||||||
(a->type == NDB_FIELD)? a
|
|
||||||
: (b->type == NDB_FIELD)? b
|
|
||||||
: NULL;
|
|
||||||
if (!value || !field) break;
|
if (!value || !field) break;
|
||||||
if (value->qualification.value_type != Item::STRING_ITEM) break;
|
if (value->qualification.value_type != Item::STRING_ITEM) break;
|
||||||
// Save value in right format for the field type
|
// Save value in right format for the field type
|
||||||
@ -6600,28 +6632,26 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
value->pack_length()));
|
value->pack_length()));
|
||||||
if (filter->cmp(NdbScanFilter::COND_NOT_LIKE,
|
if (filter->cmp(NdbScanFilter::COND_NOT_LIKE,
|
||||||
field->get_field_no(),
|
field->get_field_no(),
|
||||||
field->get_val(),
|
value->get_val(),
|
||||||
field->pack_length()) == -1)
|
value->pack_length()) == -1)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
cond= cond->next->next->next;
|
cond= cond->next->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case(Item_func::ISNULL_FUNC):
|
case(Item_func::ISNULL_FUNC):
|
||||||
if (a->type == NDB_FIELD)
|
if (!field)
|
||||||
{
|
break;
|
||||||
DBUG_PRINT("info", ("Generating ISNULL filter"));
|
DBUG_PRINT("info", ("Generating ISNULL filter"));
|
||||||
if (filter->isnull(a->get_field_no()) == -1)
|
if (filter->isnull(field->get_field_no()) == -1)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
|
||||||
cond= cond->next->next;
|
cond= cond->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
case(Item_func::ISNOTNULL_FUNC): {
|
case(Item_func::ISNOTNULL_FUNC): {
|
||||||
if (a->type == NDB_FIELD)
|
if (!field)
|
||||||
{
|
break;
|
||||||
DBUG_PRINT("info", ("Generating ISNOTNULL filter"));
|
DBUG_PRINT("info", ("Generating ISNOTNULL filter"));
|
||||||
if (filter->isnotnull(a->get_field_no()) == -1)
|
if (filter->isnotnull(field->get_field_no()) == -1)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
|
||||||
cond= cond->next->next;
|
cond= cond->next->next;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@ -6638,62 +6668,64 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ha_ndbcluster::build_scan_filter_group(Ndb_cond* &cond, NdbScanFilter *filter,
|
ha_ndbcluster::build_scan_filter_group(Ndb_cond* &cond, NdbScanFilter *filter)
|
||||||
bool negated)
|
|
||||||
{
|
{
|
||||||
|
uint level=0;
|
||||||
|
bool negated= false;
|
||||||
|
|
||||||
DBUG_ENTER("build_scan_filter_group");
|
DBUG_ENTER("build_scan_filter_group");
|
||||||
if (!cond) DBUG_RETURN(1);
|
do
|
||||||
switch(cond->ndb_item->type) {
|
{
|
||||||
case(NDB_FUNCTION):
|
if (!cond) DBUG_RETURN(1);
|
||||||
switch(cond->ndb_item->qualification.function_type) {
|
switch(cond->ndb_item->type) {
|
||||||
case(Item_func::COND_AND_FUNC): {
|
case(NDB_FUNCTION):
|
||||||
DBUG_PRINT("info", ("Generating %s group", (negated)?"NAND":"AND"));
|
switch(cond->ndb_item->qualification.function_type) {
|
||||||
if ((negated) ? filter->begin(NdbScanFilter::NAND)
|
case(Item_func::COND_AND_FUNC): {
|
||||||
: filter->begin(NdbScanFilter::AND) == -1)
|
level++;
|
||||||
DBUG_RETURN(1);
|
DBUG_PRINT("info", ("Generating %s group %u", (negated)?"NAND":"AND",
|
||||||
cond= cond->next;
|
level));
|
||||||
do
|
if ((negated) ? filter->begin(NdbScanFilter::NAND)
|
||||||
{
|
: filter->begin(NdbScanFilter::AND) == -1)
|
||||||
if (build_scan_filter_group(cond, filter))
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
} while (cond && cond->ndb_item->type != NDB_END_COND);
|
negated= false;
|
||||||
|
cond= cond->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(Item_func::COND_OR_FUNC): {
|
||||||
|
level++;
|
||||||
|
DBUG_PRINT("info", ("Generating %s group %u", (negated)?"NOR":"OR",
|
||||||
|
level));
|
||||||
|
if ((negated) ? filter->begin(NdbScanFilter::NOR)
|
||||||
|
: filter->begin(NdbScanFilter::OR) == -1)
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
negated= false;
|
||||||
|
cond= cond->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(Item_func::NOT_FUNC): {
|
||||||
|
cond= cond->next;
|
||||||
|
negated= true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if (build_scan_filter_predicate(cond, filter, negated))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
negated= false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case(NDB_END_COND):
|
||||||
|
DBUG_PRINT("info", ("End of group %u", level));
|
||||||
|
level--;
|
||||||
if (cond) cond= cond->next;
|
if (cond) cond= cond->next;
|
||||||
if (filter->end() == -1)
|
if (filter->end() == -1)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
DBUG_PRINT("info", ("End of %s group", (negated)?"NAND":"AND"));
|
|
||||||
break;
|
break;
|
||||||
|
default: {
|
||||||
|
DBUG_PRINT("info", ("Illegal scan filter"));
|
||||||
}
|
}
|
||||||
case(Item_func::COND_OR_FUNC): {
|
|
||||||
DBUG_PRINT("info", ("Generating % group", (negated)?"NOR":"OR"));
|
|
||||||
if ((negated) ? filter->begin(NdbScanFilter::NOR)
|
|
||||||
: filter->begin(NdbScanFilter::OR) == -1)
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
cond= cond->next;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (build_scan_filter_group(cond, filter))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
} while (cond && cond->ndb_item->type != NDB_END_COND);
|
|
||||||
if (cond) cond= cond->next;
|
|
||||||
if (filter->end() == -1)
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
DBUG_PRINT("info", ("End of %s group", (negated)?"NOR":"OR"));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case(Item_func::NOT_FUNC): {
|
} while (level > 0);
|
||||||
cond= cond->next;
|
|
||||||
build_scan_filter_group(cond, filter, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if (build_scan_filter_predicate(cond, filter, negated))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default: {
|
|
||||||
DBUG_PRINT("info", ("Illegal scan filter"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@ -6706,8 +6738,6 @@ ha_ndbcluster::build_scan_filter(Ndb_cond * &cond, NdbScanFilter *filter)
|
|||||||
|
|
||||||
switch(cond->ndb_item->type) {
|
switch(cond->ndb_item->type) {
|
||||||
case(Item_func::COND_AND_FUNC):
|
case(Item_func::COND_AND_FUNC):
|
||||||
simple_cond= FALSE;
|
|
||||||
break;
|
|
||||||
case(Item_func::COND_OR_FUNC):
|
case(Item_func::COND_OR_FUNC):
|
||||||
simple_cond= FALSE;
|
simple_cond= FALSE;
|
||||||
break;
|
break;
|
||||||
|
@ -109,10 +109,18 @@ static const negated_function_mapping neg_map[]=
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This class is used for serialization of the Item tree for
|
This class is the construction element for serialization of Item tree
|
||||||
condition pushdown. It is stored in a linked list implemented
|
in condition pushdown.
|
||||||
by Ndb_cond class.
|
An instance of Ndb_Item represents a constant, table field reference,
|
||||||
*/
|
unary or binary comparison predicate, and start/end of AND/OR.
|
||||||
|
Instances of Ndb_Item are stored in a linked list implemented by Ndb_cond
|
||||||
|
class.
|
||||||
|
The order of elements produced by Ndb_cond::next corresponds to
|
||||||
|
depth-first traversal of the Item (i.e. expression) tree in prefix order.
|
||||||
|
AND and OR have arbitrary arity, so the end of AND/OR group is marked with
|
||||||
|
Ndb_item with type == NDB_END_COND.
|
||||||
|
NOT items represent negated conditions and generate NAND/NOR groups.
|
||||||
|
*/
|
||||||
class Ndb_item {
|
class Ndb_item {
|
||||||
public:
|
public:
|
||||||
Ndb_item(NDB_ITEM_TYPE item_type) : type(item_type) {};
|
Ndb_item(NDB_ITEM_TYPE item_type) : type(item_type) {};
|
||||||
@ -134,6 +142,8 @@ class Ndb_item {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(NDB_FUNCTION):
|
case(NDB_FUNCTION):
|
||||||
|
value.item= item_value;
|
||||||
|
break;
|
||||||
case(NDB_END_COND):
|
case(NDB_END_COND):
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -146,9 +156,11 @@ class Ndb_item {
|
|||||||
field_value->column_no= column_no;
|
field_value->column_no= column_no;
|
||||||
value.field_value= field_value;
|
value.field_value= field_value;
|
||||||
};
|
};
|
||||||
Ndb_item(Item_func::Functype func_type) : type(NDB_FUNCTION)
|
Ndb_item(Item_func::Functype func_type, const Item *item_value)
|
||||||
|
: type(NDB_FUNCTION)
|
||||||
{
|
{
|
||||||
qualification.function_type= func_type;
|
qualification.function_type= func_type;
|
||||||
|
value.item= item_value;
|
||||||
};
|
};
|
||||||
~Ndb_item()
|
~Ndb_item()
|
||||||
{
|
{
|
||||||
@ -179,6 +191,11 @@ class Ndb_item {
|
|||||||
|
|
||||||
int get_field_no() { return value.field_value->column_no; };
|
int get_field_no() { return value.field_value->column_no; };
|
||||||
|
|
||||||
|
int argument_count()
|
||||||
|
{
|
||||||
|
return ((Item_func *) value.item)->argument_count();
|
||||||
|
};
|
||||||
|
|
||||||
const char* get_val()
|
const char* get_val()
|
||||||
{
|
{
|
||||||
switch(type) {
|
switch(type) {
|
||||||
@ -274,7 +291,7 @@ class Ndb_cond_traverse_context
|
|||||||
Ndb_cond_traverse_context(TABLE *tab, void* ndb_tab, Ndb_cond_stack* stack)
|
Ndb_cond_traverse_context(TABLE *tab, void* ndb_tab, Ndb_cond_stack* stack)
|
||||||
: table(tab), ndb_table(ndb_tab),
|
: table(tab), ndb_table(ndb_tab),
|
||||||
supported(TRUE), stack_ptr(stack), cond_ptr(NULL),
|
supported(TRUE), stack_ptr(stack), cond_ptr(NULL),
|
||||||
expect_mask(0), expect_field_result_mask(0), skip(0)
|
expect_mask(0), expect_field_result_mask(0), skip(0), collation(NULL)
|
||||||
{
|
{
|
||||||
if (stack)
|
if (stack)
|
||||||
cond_ptr= stack->ndb_cond;
|
cond_ptr= stack->ndb_cond;
|
||||||
@ -318,6 +335,17 @@ class Ndb_cond_traverse_context
|
|||||||
expect_field_result_mask= 0;
|
expect_field_result_mask= 0;
|
||||||
expect_field_result(result);
|
expect_field_result(result);
|
||||||
};
|
};
|
||||||
|
void expect_collation(CHARSET_INFO* col)
|
||||||
|
{
|
||||||
|
collation= col;
|
||||||
|
};
|
||||||
|
bool expecting_collation(CHARSET_INFO* col)
|
||||||
|
{
|
||||||
|
bool matching= (!collation) ? true : (collation == col);
|
||||||
|
collation= NULL;
|
||||||
|
|
||||||
|
return matching;
|
||||||
|
};
|
||||||
|
|
||||||
TABLE* table;
|
TABLE* table;
|
||||||
void* ndb_table;
|
void* ndb_table;
|
||||||
@ -327,6 +355,8 @@ class Ndb_cond_traverse_context
|
|||||||
uint expect_mask;
|
uint expect_mask;
|
||||||
uint expect_field_result_mask;
|
uint expect_field_result_mask;
|
||||||
uint skip;
|
uint skip;
|
||||||
|
CHARSET_INFO* collation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -428,27 +458,40 @@ class ha_ndbcluster: public handler
|
|||||||
/*
|
/*
|
||||||
Condition pushdown
|
Condition pushdown
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
Push a condition to ndbcluster storage engine for evaluation
|
/*
|
||||||
during table and index scans. The conditions will be stored on a stack
|
Push condition down to the table handler.
|
||||||
for possibly storing several conditions. The stack can be popped
|
SYNOPSIS
|
||||||
by calling cond_pop, handler::extra(HA_EXTRA_RESET) (handler::reset())
|
cond_push()
|
||||||
will clear the stack.
|
cond Condition to be pushed. The condition tree must not be
|
||||||
The current implementation supports arbitrary AND/OR nested conditions
|
modified by the by the caller.
|
||||||
with comparisons between columns and constants (including constant
|
RETURN
|
||||||
expressions and function calls) and the following comparison operators:
|
The 'remainder' condition that caller must use to filter out records.
|
||||||
=, !=, >, >=, <, <=, "is null", and "is not null".
|
NULL means the handler will not return rows that do not match the
|
||||||
|
passed condition.
|
||||||
RETURN
|
NOTES
|
||||||
NULL The condition was supported and will be evaluated for each
|
The pushed conditions form a stack (from which one can remove the
|
||||||
row found during the scan
|
last pushed condition using cond_pop).
|
||||||
cond The condition was not supported and all rows will be returned from
|
The table handler filters out rows using (pushed_cond1 AND pushed_cond2
|
||||||
the scan for evaluation (and thus not saved on stack)
|
AND ... AND pushed_condN)
|
||||||
*/
|
or less restrictive condition, depending on handler's capabilities.
|
||||||
|
|
||||||
|
handler->extra(HA_EXTRA_RESET) call empties the condition stack.
|
||||||
|
Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
|
||||||
|
condition stack.
|
||||||
|
The current implementation supports arbitrary AND/OR nested conditions
|
||||||
|
with comparisons between columns and constants (including constant
|
||||||
|
expressions and function calls) and the following comparison operators:
|
||||||
|
=, !=, >, >=, <, <=, like, "not like", "is null", and "is not null".
|
||||||
|
Negated conditions are supported by NOT which generate NAND/NOR groups.
|
||||||
|
*/
|
||||||
const COND *cond_push(const COND *cond);
|
const COND *cond_push(const COND *cond);
|
||||||
/*
|
/*
|
||||||
Pop the top condition from the condition stack of the handler instance.
|
Pop the top condition from the condition stack of the handler instance.
|
||||||
*/
|
SYNOPSIS
|
||||||
|
cond_pop()
|
||||||
|
Pops the top if condition stack, if stack is not empty
|
||||||
|
*/
|
||||||
void cond_pop();
|
void cond_pop();
|
||||||
|
|
||||||
uint8 table_cache_type();
|
uint8 table_cache_type();
|
||||||
@ -536,8 +579,7 @@ private:
|
|||||||
NdbScanFilter* filter,
|
NdbScanFilter* filter,
|
||||||
bool negated= false);
|
bool negated= false);
|
||||||
int build_scan_filter_group(Ndb_cond* &cond,
|
int build_scan_filter_group(Ndb_cond* &cond,
|
||||||
NdbScanFilter* filter,
|
NdbScanFilter* filter);
|
||||||
bool negated= false);
|
|
||||||
int build_scan_filter(Ndb_cond* &cond, NdbScanFilter* filter);
|
int build_scan_filter(Ndb_cond* &cond, NdbScanFilter* filter);
|
||||||
int generate_scan_filter(Ndb_cond_stack* cond_stack,
|
int generate_scan_filter(Ndb_cond_stack* cond_stack,
|
||||||
NdbScanOperation* op);
|
NdbScanOperation* op);
|
||||||
|
@ -451,7 +451,7 @@ public:
|
|||||||
enum {NONE=0, INDEX, RND} inited;
|
enum {NONE=0, INDEX, RND} inited;
|
||||||
bool auto_increment_column_changed;
|
bool auto_increment_column_changed;
|
||||||
bool implicit_emptied; /* Can be !=0 only if HEAP */
|
bool implicit_emptied; /* Can be !=0 only if HEAP */
|
||||||
|
const COND *pushed_cond;
|
||||||
|
|
||||||
handler(TABLE *table_arg) :table(table_arg),
|
handler(TABLE *table_arg) :table(table_arg),
|
||||||
ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0),
|
ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0),
|
||||||
@ -460,7 +460,8 @@ public:
|
|||||||
create_time(0), check_time(0), update_time(0),
|
create_time(0), check_time(0), update_time(0),
|
||||||
key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
|
key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
|
||||||
ref_length(sizeof(my_off_t)), block_size(0),
|
ref_length(sizeof(my_off_t)), block_size(0),
|
||||||
raid_type(0), ft_handler(0), inited(NONE), implicit_emptied(0)
|
raid_type(0), ft_handler(0), inited(NONE), implicit_emptied(0),
|
||||||
|
pushed_cond(NULL)
|
||||||
{}
|
{}
|
||||||
virtual ~handler(void) { /* TODO: DBUG_ASSERT(inited == NONE); */ }
|
virtual ~handler(void) { /* TODO: DBUG_ASSERT(inited == NONE); */ }
|
||||||
int ha_open(const char *name, int mode, int test_if_locked);
|
int ha_open(const char *name, int mode, int test_if_locked);
|
||||||
@ -724,23 +725,34 @@ public:
|
|||||||
Condition pushdown to storage engines
|
Condition pushdown to storage engines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Push a condition to storage engine for evaluation during table
|
Push condition down to the table handler.
|
||||||
and index scans. The conditions should be stored on a stack
|
SYNOPSIS
|
||||||
for possibly storing several conditions. The stack can be popped
|
cond_push()
|
||||||
by calling cond_pop, handler::extra(HA_EXTRA_RESET) (handler::reset())
|
cond Condition to be pushed. The condition tree must not be
|
||||||
should clear the stack.
|
modified by the by the caller.
|
||||||
The condition can be traversed using Item::traverse_cond
|
RETURN
|
||||||
RETURN
|
The 'remainder' condition that caller must use to filter out records.
|
||||||
NULL The condition was supported by the handler and will be evaluated
|
NULL means the handler will not return rows that do not match the
|
||||||
for each row found during the scan
|
passed condition.
|
||||||
cond The condition was not supported and all rows will be returned from
|
NOTES
|
||||||
the scan for evaluation (and thus not saved on stack)
|
The pushed conditions form a stack (from which one can remove the
|
||||||
*/
|
last pushed condition using cond_pop).
|
||||||
|
The table handler filters out rows using (pushed_cond1 AND pushed_cond2
|
||||||
|
AND ... AND pushed_condN)
|
||||||
|
or less restrictive condition, depending on handler's capabilities.
|
||||||
|
|
||||||
|
handler->extra(HA_EXTRA_RESET) call empties the condition stack.
|
||||||
|
Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
|
||||||
|
condition stack.
|
||||||
|
*/
|
||||||
virtual const COND *cond_push(const COND *cond) { return cond; };
|
virtual const COND *cond_push(const COND *cond) { return cond; };
|
||||||
/*
|
/*
|
||||||
Pop the top condition from the condition stack of the handler instance.
|
Pop the top condition from the condition stack of the handler instance.
|
||||||
*/
|
SYNOPSIS
|
||||||
|
cond_pop()
|
||||||
|
Pops the top if condition stack, if stack is not empty
|
||||||
|
*/
|
||||||
virtual void cond_pop() { return; };
|
virtual void cond_pop() { return; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5305,7 +5305,12 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
tab->select_cond=sel->cond=tmp;
|
tab->select_cond=sel->cond=tmp;
|
||||||
if (current_thd->variables.engine_condition_pushdown)
|
if (current_thd->variables.engine_condition_pushdown)
|
||||||
tab->table->file->cond_push(tmp); // Push condition to handler
|
{
|
||||||
|
tab->table->file->pushed_cond= NULL;
|
||||||
|
/* Push condition to handler */
|
||||||
|
if (!tab->table->file->cond_push(tmp))
|
||||||
|
tab->table->file->pushed_cond= tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tab->select_cond= sel->cond= NULL;
|
tab->select_cond= sel->cond= NULL;
|
||||||
@ -5428,8 +5433,12 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
tab->cache.select->cond=tmp;
|
tab->cache.select->cond=tmp;
|
||||||
tab->cache.select->read_tables=join->const_table_map;
|
tab->cache.select->read_tables=join->const_table_map;
|
||||||
if (current_thd->variables.engine_condition_pushdown &&
|
if (current_thd->variables.engine_condition_pushdown &&
|
||||||
(tmp != tab->select_cond))
|
(!tab->table->file->pushed_cond))
|
||||||
tab->table->file->cond_push(tmp); // Push condition to handler
|
{
|
||||||
|
/* Push condition to handler */
|
||||||
|
if (!tab->table->file->cond_push(tmp))
|
||||||
|
tab->table->file->pushed_cond= tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user