diff options
-rw-r--r-- | mysql-test/r/ndb_condition_pushdown.result | 618 | ||||
-rw-r--r-- | mysql-test/t/ndb_condition_pushdown.test | 564 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 516 | ||||
-rw-r--r-- | sql/ha_ndbcluster.h | 106 | ||||
-rw-r--r-- | sql/item_func.cc | 4 | ||||
-rw-r--r-- | sql/mysqld.cc | 14 | ||||
-rw-r--r-- | sql/set_var.cc | 14 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 |
9 files changed, 1453 insertions, 391 deletions
diff --git a/mysql-test/r/ndb_condition_pushdown.result b/mysql-test/r/ndb_condition_pushdown.result index f87661daae9..1d000a8738d 100644 --- a/mysql-test/r/ndb_condition_pushdown.result +++ b/mysql-test/r/ndb_condition_pushdown.result @@ -1,32 +1,620 @@ DROP TABLE IF EXISTS t1,t2; -CREATE TABLE t1 (pk1 int unsigned NOT NULL PRIMARY KEY, attr1 int unsigned NOT NULL, attr2 int unsigned, attr3 VARCHAR(10) ) ENGINE=ndbcluster; -insert into t1 values (0,0,0, "a"),(1,1,1,"b"),(2,2,NULL,NULL),(3,3,3,"d"),(4,4,4,"e"),(5,5,5,"f"); -CREATE TABLE t2 (pk1 int unsigned NOT NULL PRIMARY KEY, attr1 int unsigned NOT NULL, attr2 bigint unsigned, attr3 tinyint unsigned, attr4 VARCHAR(10) ) ENGINE=ndbcluster; -insert into t2 values (0,0,0,0,"a"),(1,1,9223372036854775803,1,"b"),(2,2,9223372036854775804,2,"c"),(3,3,9223372036854775805,3,"d"),(4,4,9223372036854775806,4,"e"),(5,5,9223372036854775807,5,"f"); -set @old_ndbcpd = @@session.ndb_condition_pushdown; -set ndb_condition_pushdown = off; -select * from t1 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1; +CREATE TABLE t1 ( +auto int(5) unsigned NOT NULL auto_increment, +string char(10) default "hello", +vstring varchar(10) default "hello", +bin binary(7) default "hello", +vbin varbinary(7) default "hello", +tiny tinyint(4) DEFAULT '0' NOT NULL , +short smallint(6) DEFAULT '1' NOT NULL , +medium mediumint(8) DEFAULT '0' NOT NULL, +long_int int(11) DEFAULT '0' NOT NULL, +longlong bigint(13) DEFAULT '0' NOT NULL, +real_float float(13,1) DEFAULT 0.0 NOT NULL, +real_double double(16,4), +utiny tinyint(3) unsigned DEFAULT '0' NOT NULL, +ushort smallint(5) unsigned zerofill DEFAULT '00000' NOT NULL, +umedium mediumint(8) unsigned DEFAULT '0' NOT NULL, +ulong int(11) unsigned DEFAULT '0' NOT NULL, +ulonglong bigint(13) unsigned DEFAULT '0' NOT NULL, +bits bit(3), +options enum('zero','one','two','three','four') not null, +flags set('zero','one','two','three','four') not null, +date_field date, +year_field year, +time_field time, +date_time datetime, +time_stamp timestamp, +PRIMARY KEY (auto) +) engine=ndb; +insert into t1 values +(NULL,"aaaa","aaaa","aaaa","aaaa",-1,-1,-1,-1,-1,1.1,1.1,1,1,1,1,1, +b'001','one','one', +'1901-01-01','1901', +'01:01:01','1901-01-01 01:01:01',NULL), +(NULL,"bbbb","bbbb","bbbb","bbbb",-2,-2,-2,-2,-2,2.2,2.2,2,2,2,2,2, +b'010','two','one,two', +'1902-02-02','1902', +'02:02:02','1902-02-02 02:02:02',NULL), +(NULL,"cccc","cccc","cccc","cccc",-3,-3,-3,-3,-3,3.3,3.3,3,3,3,3,3, +b'011','three','one,two,three', +'1903-03-03','1903', +'03:03:03','1903-03-03 03:03:03',NULL), +(NULL,"dddd","dddd","dddd","dddd",-4,-4,-4,-4,-4,4.4,4.4,4,4,4,4,4, +b'100','four','one,two,three,four', +'1904-04-04','1904', +'04:04:04','1904-04-04 04:04:04',NULL); +CREATE TABLE t2 (pk1 int unsigned NOT NULL PRIMARY KEY, attr1 int unsigned NOT NULL, attr2 int unsigned, attr3 VARCHAR(10) ) ENGINE=ndbcluster; +insert into t2 values (0,0,0, "a"),(1,1,1,"b"),(2,2,NULL,NULL),(3,3,3,"d"),(4,4,4,"e"),(5,5,5,"f"); +CREATE TABLE t3 (pk1 int unsigned NOT NULL PRIMARY KEY, attr1 int unsigned NOT NULL, attr2 bigint unsigned, attr3 tinyint unsigned, attr4 VARCHAR(10) ) ENGINE=ndbcluster; +insert into t3 values (0,0,0,0,"a"),(1,1,9223372036854775803,1,"b"),(2,2,9223372036854775804,2,"c"),(3,3,9223372036854775805,3,"d"),(4,4,9223372036854775806,4,"e"),(5,5,9223372036854775807,5,"f"); +CREATE TABLE t4 (pk1 int unsigned NOT NULL PRIMARY KEY, attr1 int unsigned NOT NULL, attr2 bigint unsigned, attr3 tinyint unsigned, attr4 VARCHAR(10) , KEY (attr1)) ENGINE=ndbcluster; +insert into t4 values (0,0,0,0,"a"),(1,1,9223372036854775803,1,"b"),(2,2,9223372036854775804,2,"c"),(3,3,9223372036854775805,3,"d"),(4,4,9223372036854775806,4,"e"),(5,5,9223372036854775807,5,"f"); +set @old_ecpd = @@session.engine_condition_pushdown; +set engine_condition_pushdown = off; +select auto from t1 where +string = "aaaa" and +vstring = "aaaa" and +bin = "aaaa" and +vbin = "aaaa" and +tiny = -1 and +short = -1 and +medium = -1 and +long_int = -1 and +longlong = -1 and +real_float > 1.0 and real_float < 2.0 and +real_double > 1.0 and real_float < 2.0 and +utiny = 1 and +ushort = 1 and +umedium = 1 and +ulong = 1 and +ulonglong = 1 and +bits = b'001' and +options = 'one' and +flags = 'one' and +date_field = '1901-01-01' and +year_field = '1901' and +time_field = '01:01:01' and +date_time = '1901-01-01 01:01:01' +order by auto; +auto +1 +select auto from t1 where +string != "aaaa" and +vstring != "aaaa" and +bin != "aaaa" and +vbin != "aaaa" and +tiny != -1 and +short != -1 and +medium != -1 and +long_int != -1 and +longlong != -1 and +(real_float < 1.0 or real_float > 2.0) and +(real_double < 1.0 or real_float > 2.0) and +utiny != 1 and +ushort != 1 and +umedium != 1 and +ulong != 1 and +ulonglong != 1 and +bits != b'001' and +options != 'one' and +flags != 'one' and +date_field != '1901-01-01' and +year_field != '1901' and +time_field != '01:01:01' and +date_time != '1901-01-01 01:01:01' +order by auto; +auto +2 +3 +4 +select auto from t1 where +string > "aaaa" and +vstring > "aaaa" and +bin > "aaaa" and +vbin > "aaaa" and +tiny < -1 and +short < -1 and +medium < -1 and +long_int < -1 and +longlong < -1 and +real_float > 1.1 and +real_double > 1.1 and +utiny > 1 and +ushort > 1 and +umedium > 1 and +ulong > 1 and +ulonglong > 1 and +bits > b'001' and +(options = 'two' or options = 'three' or options = 'four') and +(flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field > '1901-01-01' and +year_field > '1901' and +time_field > '01:01:01' and +date_time > '1901-01-01 01:01:01' +order by auto; +auto +2 +3 +4 +select auto from t1 where +string >= "aaaa" and +vstring >= "aaaa" and +bin >= "aaaa" and +vbin >= "aaaa" and +tiny <= -1 and +short <= -1 and +medium <= -1 and +long_int <= -1 and +longlong <= -1 and +real_float >= 1.0 and +real_double >= 1.0 and +utiny >= 1 and +ushort >= 1 and +umedium >= 1 and +ulong >= 1 and +ulonglong >= 1 and +bits >= b'001' and +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field >= '1901-01-01' and +year_field >= '1901' and +time_field >= '01:01:01' and +date_time >= '1901-01-01 01:01:01' +order by auto; +auto +1 +2 +3 +4 +select auto from t1 where +string < "dddd" and +vstring < "dddd" and +bin < "dddd" and +vbin < "dddd" and +tiny > -4 and +short > -4 and +medium > -4 and +long_int > -4 and +longlong > -4 and +real_float < 4.4 and +real_double < 4.4 and +utiny < 4 and +ushort < 4 and +umedium < 4 and +ulong < 4 and +ulonglong < 4 and +bits < b'100' and +(options = 'one' or options = 'two' or options = 'three') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three') and +date_field < '1904-01-01' and +year_field < '1904' and +time_field < '04:04:04' and +date_time < '1904-04-04 04:04:04' +order by auto; +auto +1 +2 +3 +select auto from t1 where +string <= "dddd" and +vstring <= "dddd" and +bin <= "dddd" and +vbin <= "dddd" and +tiny >= -4 and +short >= -4 and +medium >= -4 and +long_int >= -4 and +longlong >= -4 and +real_float <= 4.5 and +real_double <= 4.5 and +utiny <= 4 and +ushort <= 4 and +umedium <= 4 and +ulong <= 4 and +ulonglong <= 4 and +bits <= b'100' and +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field <= '1904-04-04' and +year_field <= '1904' and +time_field <= '04:04:04' and +date_time <= '1904-04-04 04:04:04' +order by auto; +auto +1 +2 +3 +4 +select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1; pk1 attr1 attr2 attr3 2 2 NULL NULL 3 3 3 d -select * from t2 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 2 2 9223372036854775804 2 c 4 4 9223372036854775806 4 e 5 5 9223372036854775807 5 f -select * from t1,t2 where t1.attr1 > 1 and t1.attr2 = t2.attr2 and t2.attr1 < 5 order by t1.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 -set ndb_condition_pushdown = on; -select * from t1 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1; +select * from t4 where attr1 < 5 and attr2 > 9223372036854775803 and attr3 != 3 order by t4.pk1; +pk1 attr1 attr2 attr3 attr4 +2 2 9223372036854775804 2 c +4 4 9223372036854775806 4 e +select * from t3,t4 where t4.attr1 > 1 and t4.attr2 = t3.attr2 and t4.attr3 < 5 order by t4.pk1; +pk1 attr1 attr2 attr3 attr4 pk1 attr1 attr2 attr3 attr4 +2 2 9223372036854775804 2 c 2 2 9223372036854775804 2 c +3 3 9223372036854775805 3 d 3 3 9223372036854775805 3 d +4 4 9223372036854775806 4 e 4 4 9223372036854775806 4 e +set engine_condition_pushdown = on; +select auto from t1 where +string = "aaaa" and +vstring = "aaaa" and +bin = "aaaa" and +vbin = "aaaa" and +tiny = -1 and +short = -1 and +medium = -1 and +long_int = -1 and +longlong = -1 and +real_float > 1.0 and real_float < 2.0 and +real_double > 1.0 and real_float < 2.0 and +utiny = 1 and +ushort = 1 and +umedium = 1 and +ulong = 1 and +ulonglong = 1 and +/* bits = b'001' and */ +options = 'one' and +flags = 'one' and +date_field = '1901-01-01' and +year_field = '1901' and +time_field = '01:01:01' and +date_time = '1901-01-01 01:01:01' +order by auto; +auto +1 +select auto from t1 where +string != "aaaa" and +vstring != "aaaa" and +bin != "aaaa" and +vbin != "aaaa" and +tiny != -1 and +short != -1 and +medium != -1 and +long_int != -1 and +longlong != -1 and +(real_float < 1.0 or real_float > 2.0) and +(real_double < 1.0 or real_float > 2.0) and +utiny != 1 and +ushort != 1 and +umedium != 1 and +ulong != 1 and +ulonglong != 1 and +/* bits != b'001' and */ +options != 'one' and +flags != 'one' and +date_field != '1901-01-01' and +year_field != '1901' and +time_field != '01:01:01' and +date_time != '1901-01-01 01:01:01' +order by auto; +auto +2 +3 +4 +select auto from t1 where +string > "aaaa" and +vstring > "aaaa" and +bin > "aaaa" and +vbin > "aaaa" and +tiny < -1 and +short < -1 and +medium < -1 and +long_int < -1 and +longlong < -1 and +real_float > 1.1 and +real_double > 1.1 and +utiny > 1 and +ushort > 1 and +umedium > 1 and +ulong > 1 and +ulonglong > 1 and +/* bits > b'001' and */ +(options = 'two' or options = 'three' or options = 'four') and +(flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field > '1901-01-01' and +year_field > '1901' and +time_field > '01:01:01' and +date_time > '1901-01-01 01:01:01' +order by auto; +auto +2 +3 +4 +select auto from t1 where +string >= "aaaa" and +vstring >= "aaaa" and +bin >= "aaaa" and +vbin >= "aaaa" and +tiny <= -1 and +short <= -1 and +medium <= -1 and +long_int <= -1 and +longlong <= -1 and +real_float >= 1.0 and +real_double >= 1.0 and +utiny >= 1 and +ushort >= 1 and +umedium >= 1 and +ulong >= 1 and +ulonglong >= 1 and +/* bits >= b'001' and */ +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field >= '1901-01-01' and +year_field >= '1901' and +time_field >= '01:01:01' and +date_time >= '1901-01-01 01:01:01' +order by auto; +auto +1 +2 +3 +4 +select auto from t1 where +string < "dddd" and +vstring < "dddd" and +bin < "dddd" and +vbin < "dddd" and +tiny > -4 and +short > -4 and +medium > -4 and +long_int > -4 and +longlong > -4 and +real_float < 4.4 and +real_double < 4.4 and +utiny < 4 and +ushort < 4 and +umedium < 4 and +ulong < 4 and +ulonglong < 4 and +/* bits < b'100' and */ +(options = 'one' or options = 'two' or options = 'three') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three') and +date_field < '1904-01-01' and +year_field < '1904' and +time_field < '04:04:04' and +date_time < '1904-04-04 04:04:04' +order by auto; +auto +1 +2 +3 +select auto from t1 where +string <= "dddd" and +vstring <= "dddd" and +bin <= "dddd" and +vbin <= "dddd" and +tiny >= -4 and +short >= -4 and +medium >= -4 and +long_int >= -4 and +longlong >= -4 and +real_float <= 4.5 and +real_double <= 4.5 and +utiny <= 4 - 1 + 1 and /* Checking function composition */ +ushort <= 4 and +umedium <= 4 and +ulong <= 4 and +ulonglong <= 4 and +/* bits <= b'100' and */ +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field <= '1904-04-04' and +year_field <= '1904' and +time_field <= '04:04:04' and +date_time <= '1904-04-04 04:04:04' +order by auto; +auto +1 +2 +3 +4 +create index medium_index on t1(medium); +select auto from t1 where +string = "aaaa" and +vstring = "aaaa" and +bin = "aaaa" and +vbin = "aaaa" and +tiny = -1 and +short = -1 and +medium = -1 and +long_int = -1 and +longlong = -1 and +real_float > 1.0 and real_float < 2.0 and +real_double > 1.0 and real_float < 2.0 and +utiny = 1 and +ushort = 1 and +umedium = 1 and +ulong = 1 and +ulonglong = 1 and +/* bits = b'001' and */ +options = 'one' and +flags = 'one' and +date_field = '1901-01-01' and +year_field = '1901' and +time_field = '01:01:01' and +date_time = '1901-01-01 01:01:01' +order by auto; +auto +1 +select auto from t1 where +string != "aaaa" and +vstring != "aaaa" and +bin != "aaaa" and +vbin != "aaaa" and +tiny != -1 and +short != -1 and +medium != -1 and +long_int != -1 and +longlong != -1 and +(real_float < 1.0 or real_float > 2.0) and +(real_double < 1.0 or real_float > 2.0) and +utiny != 1 and +ushort != 1 and +umedium != 1 and +ulong != 1 and +ulonglong != 1 and +/* bits != b'001' and */ +options != 'one' and +flags != 'one' and +date_field != '1901-01-01' and +year_field != '1901' and +time_field != '01:01:01' and +date_time != '1901-01-01 01:01:01' +order by auto; +auto +2 +3 +4 +select auto from t1 where +string > "aaaa" and +vstring > "aaaa" and +bin > "aaaa" and +vbin > "aaaa" and +tiny < -1 and +short < -1 and +medium < -1 and +long_int < -1 and +longlong < -1 and +real_float > 1.1 and +real_double > 1.1 and +utiny > 1 and +ushort > 1 and +umedium > 1 and +ulong > 1 and +ulonglong > 1 and +/* bits > b'001' and */ +(options = 'two' or options = 'three' or options = 'four') and +(flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field > '1901-01-01' and +year_field > '1901' and +time_field > '01:01:01' and +date_time > '1901-01-01 01:01:01' +order by auto; +auto +2 +3 +4 +select auto from t1 where +string >= "aaaa" and +vstring >= "aaaa" and +bin >= "aaaa" and +vbin >= "aaaa" and +tiny <= -1 and +short <= -1 and +medium <= -1 and +long_int <= -1 and +longlong <= -1 and +real_float >= 1.0 and +real_double >= 1.0 and +utiny >= 1 and +ushort >= 1 and +umedium >= 1 and +ulong >= 1 and +ulonglong >= 1 and +/* bits >= b'001' and */ +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field >= '1901-01-01' and +year_field >= '1901' and +time_field >= '01:01:01' and +date_time >= '1901-01-01 01:01:01' +order by auto; +auto +1 +2 +3 +4 +select auto from t1 where +string < "dddd" and +vstring < "dddd" and +bin < "dddd" and +vbin < "dddd" and +tiny > -4 and +short > -4 and +medium > -4 and +long_int > -4 and +longlong > -4 and +real_float < 4.4 and +real_double < 4.4 and +utiny < 4 and +ushort < 4 and +umedium < 4 and +ulong < 4 and +ulonglong < 4 and +/* bits < b'100' and */ +(options = 'one' or options = 'two' or options = 'three') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three') and +date_field < '1904-01-01' and +year_field < '1904' and +time_field < '04:04:04' and +date_time < '1904-04-04 04:04:04' +order by auto; +auto +1 +2 +3 +select auto from t1 where +string <= "dddd" and +vstring <= "dddd" and +bin <= "dddd" and +vbin <= "dddd" and +tiny >= -4 and +short >= -4 and +medium >= -4 and +long_int >= -4 and +longlong >= -4 and +real_float <= 4.5 and +real_double <= 4.5 and +utiny <= 4 - 1 + 1 and /* Checking function composition */ +ushort <= 4 and +umedium <= 4 and +ulong <= 4 and +ulonglong <= 4 and +/* bits <= b'100' and */ +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field <= '1904-04-04' and +year_field <= '1904' and +time_field <= '04:04:04' and +date_time <= '1904-04-04 04:04:04' +order by auto; +auto +1 +2 +3 +4 +select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1; pk1 attr1 attr2 attr3 2 2 NULL NULL 3 3 3 d -select * from t2 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 2 2 9223372036854775804 2 c 4 4 9223372036854775806 4 e 5 5 9223372036854775807 5 f -select * from t1,t2 where t1.attr1 > 1 and t1.attr2 = t2.attr2 and t2.attr1 < 5 order by t1.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 -set ndb_condition_pushdown = @old_ndbcpd; -DROP TABLE t1,t2; +select * from t4 where attr1 < 5 and attr2 > 9223372036854775803 and attr3 != 3 order by t4.pk1; +pk1 attr1 attr2 attr3 attr4 +2 2 9223372036854775804 2 c +4 4 9223372036854775806 4 e +select * from t3,t4 where t4.attr1 > 1 and t4.attr2 = t3.attr2 and t4.attr3 < 5 order by t4.pk1; +pk1 attr1 attr2 attr3 attr4 pk1 attr1 attr2 attr3 attr4 +2 2 9223372036854775804 2 c 2 2 9223372036854775804 2 c +3 3 9223372036854775805 3 d 3 3 9223372036854775805 3 d +4 4 9223372036854775806 4 e 4 4 9223372036854775806 4 e +set engine_condition_pushdown = @old_ecpd; +DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/t/ndb_condition_pushdown.test b/mysql-test/t/ndb_condition_pushdown.test index dcf42773f4c..1fd538f6c7c 100644 --- a/mysql-test/t/ndb_condition_pushdown.test +++ b/mysql-test/t/ndb_condition_pushdown.test @@ -7,22 +7,556 @@ DROP TABLE IF EXISTS t1,t2; # # Test of condition pushdown to storage engine # -CREATE TABLE t1 (pk1 int unsigned NOT NULL PRIMARY KEY, attr1 int unsigned NOT NULL, attr2 int unsigned, attr3 VARCHAR(10) ) ENGINE=ndbcluster; +CREATE TABLE t1 ( + auto int(5) unsigned NOT NULL auto_increment, + string char(10) default "hello", + vstring varchar(10) default "hello", + bin binary(7) default "hello", + vbin varbinary(7) default "hello", + tiny tinyint(4) DEFAULT '0' NOT NULL , + short smallint(6) DEFAULT '1' NOT NULL , + medium mediumint(8) DEFAULT '0' NOT NULL, + long_int int(11) DEFAULT '0' NOT NULL, + longlong bigint(13) DEFAULT '0' NOT NULL, + real_float float(13,1) DEFAULT 0.0 NOT NULL, + real_double double(16,4), + utiny tinyint(3) unsigned DEFAULT '0' NOT NULL, + ushort smallint(5) unsigned zerofill DEFAULT '00000' NOT NULL, + umedium mediumint(8) unsigned DEFAULT '0' NOT NULL, + ulong int(11) unsigned DEFAULT '0' NOT NULL, + ulonglong bigint(13) unsigned DEFAULT '0' NOT NULL, + bits bit(3), + options enum('zero','one','two','three','four') not null, + flags set('zero','one','two','three','four') not null, + date_field date, + year_field year, + time_field time, + date_time datetime, + time_stamp timestamp, + PRIMARY KEY (auto) +) engine=ndb; -insert into t1 values (0,0,0, "a"),(1,1,1,"b"),(2,2,NULL,NULL),(3,3,3,"d"),(4,4,4,"e"),(5,5,5,"f"); +insert into t1 values +(NULL,"aaaa","aaaa","aaaa","aaaa",-1,-1,-1,-1,-1,1.1,1.1,1,1,1,1,1, + b'001','one','one', + '1901-01-01','1901', +'01:01:01','1901-01-01 01:01:01',NULL), +(NULL,"bbbb","bbbb","bbbb","bbbb",-2,-2,-2,-2,-2,2.2,2.2,2,2,2,2,2, + b'010','two','one,two', + '1902-02-02','1902', +'02:02:02','1902-02-02 02:02:02',NULL), +(NULL,"cccc","cccc","cccc","cccc",-3,-3,-3,-3,-3,3.3,3.3,3,3,3,3,3, + b'011','three','one,two,three', + '1903-03-03','1903', +'03:03:03','1903-03-03 03:03:03',NULL), +(NULL,"dddd","dddd","dddd","dddd",-4,-4,-4,-4,-4,4.4,4.4,4,4,4,4,4, + b'100','four','one,two,three,four', + '1904-04-04','1904', +'04:04:04','1904-04-04 04:04:04',NULL); -CREATE TABLE t2 (pk1 int unsigned NOT NULL PRIMARY KEY, attr1 int unsigned NOT NULL, attr2 bigint unsigned, attr3 tinyint unsigned, attr4 VARCHAR(10) ) ENGINE=ndbcluster; +CREATE TABLE t2 (pk1 int unsigned NOT NULL PRIMARY KEY, attr1 int unsigned NOT NULL, attr2 int unsigned, attr3 VARCHAR(10) ) ENGINE=ndbcluster; -insert into t2 values (0,0,0,0,"a"),(1,1,9223372036854775803,1,"b"),(2,2,9223372036854775804,2,"c"),(3,3,9223372036854775805,3,"d"),(4,4,9223372036854775806,4,"e"),(5,5,9223372036854775807,5,"f"); +insert into t2 values (0,0,0, "a"),(1,1,1,"b"),(2,2,NULL,NULL),(3,3,3,"d"),(4,4,4,"e"),(5,5,5,"f"); -set @old_ndbcpd = @@session.ndb_condition_pushdown; -set ndb_condition_pushdown = off; -select * from t1 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1; -select * from t2 where attr2 > 9223372036854775803 and attr3 != 3 order by pk1; -select * from t1,t2 where t1.attr1 > 1 and t1.attr2 = t2.attr2 and t2.attr1 < 5 order by t1.pk1; -set ndb_condition_pushdown = on; -select * from t1 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1; -select * from t2 where attr2 > 9223372036854775803 and attr3 != 3 order by pk1; -select * from t1,t2 where t1.attr1 > 1 and t1.attr2 = t2.attr2 and t2.attr1 < 5 order by t1.pk1; -set ndb_condition_pushdown = @old_ndbcpd; -DROP TABLE t1,t2; +CREATE TABLE t3 (pk1 int unsigned NOT NULL PRIMARY KEY, attr1 int unsigned NOT NULL, attr2 bigint unsigned, attr3 tinyint unsigned, attr4 VARCHAR(10) ) ENGINE=ndbcluster; + +insert into t3 values (0,0,0,0,"a"),(1,1,9223372036854775803,1,"b"),(2,2,9223372036854775804,2,"c"),(3,3,9223372036854775805,3,"d"),(4,4,9223372036854775806,4,"e"),(5,5,9223372036854775807,5,"f"); + +CREATE TABLE t4 (pk1 int unsigned NOT NULL PRIMARY KEY, attr1 int unsigned NOT NULL, attr2 bigint unsigned, attr3 tinyint unsigned, attr4 VARCHAR(10) , KEY (attr1)) ENGINE=ndbcluster; + +insert into t4 values (0,0,0,0,"a"),(1,1,9223372036854775803,1,"b"),(2,2,9223372036854775804,2,"c"),(3,3,9223372036854775805,3,"d"),(4,4,9223372036854775806,4,"e"),(5,5,9223372036854775807,5,"f"); + +set @old_ecpd = @@session.engine_condition_pushdown; +set engine_condition_pushdown = off; + +# Test all types and compare operators +select auto from t1 where +string = "aaaa" and +vstring = "aaaa" and +bin = "aaaa" and +vbin = "aaaa" and +tiny = -1 and +short = -1 and +medium = -1 and +long_int = -1 and +longlong = -1 and +real_float > 1.0 and real_float < 2.0 and +real_double > 1.0 and real_float < 2.0 and +utiny = 1 and +ushort = 1 and +umedium = 1 and +ulong = 1 and +ulonglong = 1 and +bits = b'001' and +options = 'one' and +flags = 'one' and +date_field = '1901-01-01' and +year_field = '1901' and +time_field = '01:01:01' and +date_time = '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string != "aaaa" and +vstring != "aaaa" and +bin != "aaaa" and +vbin != "aaaa" and +tiny != -1 and +short != -1 and +medium != -1 and +long_int != -1 and +longlong != -1 and +(real_float < 1.0 or real_float > 2.0) and +(real_double < 1.0 or real_float > 2.0) and +utiny != 1 and +ushort != 1 and +umedium != 1 and +ulong != 1 and +ulonglong != 1 and +bits != b'001' and +options != 'one' and +flags != 'one' and +date_field != '1901-01-01' and +year_field != '1901' and +time_field != '01:01:01' and +date_time != '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string > "aaaa" and +vstring > "aaaa" and +bin > "aaaa" and +vbin > "aaaa" and +tiny < -1 and +short < -1 and +medium < -1 and +long_int < -1 and +longlong < -1 and +real_float > 1.1 and +real_double > 1.1 and +utiny > 1 and +ushort > 1 and +umedium > 1 and +ulong > 1 and +ulonglong > 1 and +bits > b'001' and +(options = 'two' or options = 'three' or options = 'four') and +(flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field > '1901-01-01' and +year_field > '1901' and +time_field > '01:01:01' and +date_time > '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string >= "aaaa" and +vstring >= "aaaa" and +bin >= "aaaa" and +vbin >= "aaaa" and +tiny <= -1 and +short <= -1 and +medium <= -1 and +long_int <= -1 and +longlong <= -1 and +real_float >= 1.0 and +real_double >= 1.0 and +utiny >= 1 and +ushort >= 1 and +umedium >= 1 and +ulong >= 1 and +ulonglong >= 1 and +bits >= b'001' and +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field >= '1901-01-01' and +year_field >= '1901' and +time_field >= '01:01:01' and +date_time >= '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string < "dddd" and +vstring < "dddd" and +bin < "dddd" and +vbin < "dddd" and +tiny > -4 and +short > -4 and +medium > -4 and +long_int > -4 and +longlong > -4 and +real_float < 4.4 and +real_double < 4.4 and +utiny < 4 and +ushort < 4 and +umedium < 4 and +ulong < 4 and +ulonglong < 4 and +bits < b'100' and +(options = 'one' or options = 'two' or options = 'three') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three') and +date_field < '1904-01-01' and +year_field < '1904' and +time_field < '04:04:04' and +date_time < '1904-04-04 04:04:04' +order by auto; + +select auto from t1 where +string <= "dddd" and +vstring <= "dddd" and +bin <= "dddd" and +vbin <= "dddd" and +tiny >= -4 and +short >= -4 and +medium >= -4 and +long_int >= -4 and +longlong >= -4 and +real_float <= 4.5 and +real_double <= 4.5 and +utiny <= 4 and +ushort <= 4 and +umedium <= 4 and +ulong <= 4 and +ulonglong <= 4 and +bits <= b'100' and +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field <= '1904-04-04' and +year_field <= '1904' and +time_field <= '04:04:04' and +date_time <= '1904-04-04 04:04:04' +order by auto; + +# Various tests +select * from t2 where attr3 is null or attr1 > 2 and pk1= 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 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; + +set engine_condition_pushdown = on; + +# Test all types and compare operators +select auto from t1 where +string = "aaaa" and +vstring = "aaaa" and +bin = "aaaa" and +vbin = "aaaa" and +tiny = -1 and +short = -1 and +medium = -1 and +long_int = -1 and +longlong = -1 and +real_float > 1.0 and real_float < 2.0 and +real_double > 1.0 and real_float < 2.0 and +utiny = 1 and +ushort = 1 and +umedium = 1 and +ulong = 1 and +ulonglong = 1 and +/* bits = b'001' and */ +options = 'one' and +flags = 'one' and +date_field = '1901-01-01' and +year_field = '1901' and +time_field = '01:01:01' and +date_time = '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string != "aaaa" and +vstring != "aaaa" and +bin != "aaaa" and +vbin != "aaaa" and +tiny != -1 and +short != -1 and +medium != -1 and +long_int != -1 and +longlong != -1 and +(real_float < 1.0 or real_float > 2.0) and +(real_double < 1.0 or real_float > 2.0) and +utiny != 1 and +ushort != 1 and +umedium != 1 and +ulong != 1 and +ulonglong != 1 and +/* bits != b'001' and */ +options != 'one' and +flags != 'one' and +date_field != '1901-01-01' and +year_field != '1901' and +time_field != '01:01:01' and +date_time != '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string > "aaaa" and +vstring > "aaaa" and +bin > "aaaa" and +vbin > "aaaa" and +tiny < -1 and +short < -1 and +medium < -1 and +long_int < -1 and +longlong < -1 and +real_float > 1.1 and +real_double > 1.1 and +utiny > 1 and +ushort > 1 and +umedium > 1 and +ulong > 1 and +ulonglong > 1 and +/* bits > b'001' and */ +(options = 'two' or options = 'three' or options = 'four') and +(flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field > '1901-01-01' and +year_field > '1901' and +time_field > '01:01:01' and +date_time > '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string >= "aaaa" and +vstring >= "aaaa" and +bin >= "aaaa" and +vbin >= "aaaa" and +tiny <= -1 and +short <= -1 and +medium <= -1 and +long_int <= -1 and +longlong <= -1 and +real_float >= 1.0 and +real_double >= 1.0 and +utiny >= 1 and +ushort >= 1 and +umedium >= 1 and +ulong >= 1 and +ulonglong >= 1 and +/* bits >= b'001' and */ +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field >= '1901-01-01' and +year_field >= '1901' and +time_field >= '01:01:01' and +date_time >= '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string < "dddd" and +vstring < "dddd" and +bin < "dddd" and +vbin < "dddd" and +tiny > -4 and +short > -4 and +medium > -4 and +long_int > -4 and +longlong > -4 and +real_float < 4.4 and +real_double < 4.4 and +utiny < 4 and +ushort < 4 and +umedium < 4 and +ulong < 4 and +ulonglong < 4 and +/* bits < b'100' and */ +(options = 'one' or options = 'two' or options = 'three') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three') and +date_field < '1904-01-01' and +year_field < '1904' and +time_field < '04:04:04' and +date_time < '1904-04-04 04:04:04' +order by auto; + +select auto from t1 where +string <= "dddd" and +vstring <= "dddd" and +bin <= "dddd" and +vbin <= "dddd" and +tiny >= -4 and +short >= -4 and +medium >= -4 and +long_int >= -4 and +longlong >= -4 and +real_float <= 4.5 and +real_double <= 4.5 and +utiny <= 4 - 1 + 1 and /* Checking function composition */ +ushort <= 4 and +umedium <= 4 and +ulong <= 4 and +ulonglong <= 4 and +/* bits <= b'100' and */ +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field <= '1904-04-04' and +year_field <= '1904' and +time_field <= '04:04:04' and +date_time <= '1904-04-04 04:04:04' +order by auto; + +# Test index scan with filter +create index medium_index on t1(medium); + +# Test all types and compare operators +select auto from t1 where +string = "aaaa" and +vstring = "aaaa" and +bin = "aaaa" and +vbin = "aaaa" and +tiny = -1 and +short = -1 and +medium = -1 and +long_int = -1 and +longlong = -1 and +real_float > 1.0 and real_float < 2.0 and +real_double > 1.0 and real_float < 2.0 and +utiny = 1 and +ushort = 1 and +umedium = 1 and +ulong = 1 and +ulonglong = 1 and +/* bits = b'001' and */ +options = 'one' and +flags = 'one' and +date_field = '1901-01-01' and +year_field = '1901' and +time_field = '01:01:01' and +date_time = '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string != "aaaa" and +vstring != "aaaa" and +bin != "aaaa" and +vbin != "aaaa" and +tiny != -1 and +short != -1 and +medium != -1 and +long_int != -1 and +longlong != -1 and +(real_float < 1.0 or real_float > 2.0) and +(real_double < 1.0 or real_float > 2.0) and +utiny != 1 and +ushort != 1 and +umedium != 1 and +ulong != 1 and +ulonglong != 1 and +/* bits != b'001' and */ +options != 'one' and +flags != 'one' and +date_field != '1901-01-01' and +year_field != '1901' and +time_field != '01:01:01' and +date_time != '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string > "aaaa" and +vstring > "aaaa" and +bin > "aaaa" and +vbin > "aaaa" and +tiny < -1 and +short < -1 and +medium < -1 and +long_int < -1 and +longlong < -1 and +real_float > 1.1 and +real_double > 1.1 and +utiny > 1 and +ushort > 1 and +umedium > 1 and +ulong > 1 and +ulonglong > 1 and +/* bits > b'001' and */ +(options = 'two' or options = 'three' or options = 'four') and +(flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field > '1901-01-01' and +year_field > '1901' and +time_field > '01:01:01' and +date_time > '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string >= "aaaa" and +vstring >= "aaaa" and +bin >= "aaaa" and +vbin >= "aaaa" and +tiny <= -1 and +short <= -1 and +medium <= -1 and +long_int <= -1 and +longlong <= -1 and +real_float >= 1.0 and +real_double >= 1.0 and +utiny >= 1 and +ushort >= 1 and +umedium >= 1 and +ulong >= 1 and +ulonglong >= 1 and +/* bits >= b'001' and */ +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field >= '1901-01-01' and +year_field >= '1901' and +time_field >= '01:01:01' and +date_time >= '1901-01-01 01:01:01' +order by auto; + +select auto from t1 where +string < "dddd" and +vstring < "dddd" and +bin < "dddd" and +vbin < "dddd" and +tiny > -4 and +short > -4 and +medium > -4 and +long_int > -4 and +longlong > -4 and +real_float < 4.4 and +real_double < 4.4 and +utiny < 4 and +ushort < 4 and +umedium < 4 and +ulong < 4 and +ulonglong < 4 and +/* bits < b'100' and */ +(options = 'one' or options = 'two' or options = 'three') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three') and +date_field < '1904-01-01' and +year_field < '1904' and +time_field < '04:04:04' and +date_time < '1904-04-04 04:04:04' +order by auto; + +select auto from t1 where +string <= "dddd" and +vstring <= "dddd" and +bin <= "dddd" and +vbin <= "dddd" and +tiny >= -4 and +short >= -4 and +medium >= -4 and +long_int >= -4 and +longlong >= -4 and +real_float <= 4.5 and +real_double <= 4.5 and +utiny <= 4 - 1 + 1 and /* Checking function composition */ +ushort <= 4 and +umedium <= 4 and +ulong <= 4 and +ulonglong <= 4 and +/* bits <= b'100' and */ +(options = 'one' or options = 'two' or options = 'three' or options = 'four') and +(flags = 'one' or flags = 'one,two' or flags = 'one,two,three' or flags = 'one,two,three,four') and +date_field <= '1904-04-04' and +year_field <= '1904' and +time_field <= '04:04:04' and +date_time <= '1904-04-04 04:04:04' +order by auto; + +# Various tests +select * from t2 where attr3 is null or attr1 > 2 and pk1= 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 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; +set engine_condition_pushdown = @old_ecpd; +DROP TABLE t1,t2,t3,t4; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index c12055a1d63..05bc6345d24 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -244,210 +244,6 @@ int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans) } /* - CPDH condition storage support -*/ -Ndb_item::Ndb_item(NDB_ITEM_TYPE item_type, - NDB_ITEM_QUALIFICATION item_qualification, - const Item *item_value) - : type(item_type), qualification(item_qualification) -{ - switch(item_type) { - case(NDB_VALUE): - { - switch(item_qualification.value_type) { - case(Item::STRING_ITEM): { - Ndb_item_string_value *string_value = new Ndb_item_string_value(); - Item_string *string_item= (Item_string *)item_value; - string_value->s= string_item->str_value; - string_value->c= string_item->collation.collation; - value.string_value= string_value; - break; - } - case(Item::INT_ITEM): { - value.int_value= ((Item_int *)item_value)->val_int(); - break; - } - case(Item::REAL_ITEM): { - value.real_value= ((Item_real *)item_value)->val_real(); - break; - } - case(Item::NULL_ITEM): - break; - case(Item::VARBIN_ITEM): { - Ndb_item_string_value *string_value = new Ndb_item_string_value(); - Item_bin_string *varbin_item= (Item_bin_string *)item_value; - string_value->s= varbin_item->str_value; - string_value->c= varbin_item->collation.collation; - value.string_value= string_value; - break; - } - default: - break; - } - } - break; - case(NDB_FIELD): { - NDB_ITEM_FIELD_VALUE *field_value= new NDB_ITEM_FIELD_VALUE(); - Item_field *field_item= (Item_field *) item_value; - field_value->field= field_item->field; - field_value->column_no= -1; // Will be fetched at scan filter generation - value.field_value= field_value; - break; - } - case(NDB_FUNCTION): - case(NDB_END_COND): - break; - } -} - -Ndb_item::Ndb_item(longlong int_value) : type(NDB_VALUE) -{ - qualification.value_type= Item::INT_ITEM; - value.int_value= int_value; -} - -Ndb_item::Ndb_item(double real_value) : type(NDB_VALUE) -{ - qualification.value_type= Item::REAL_ITEM; - value.real_value= real_value; -} - -Ndb_item::Ndb_item(NDB_ITEM_TYPE item_type): type(item_type) {} - -Ndb_item::Ndb_item(Field *field, int column_no) : type(NDB_FIELD) -{ - NDB_ITEM_FIELD_VALUE *field_value= new NDB_ITEM_FIELD_VALUE(); - qualification.field_type= field->type(); - field_value->field= field; - field_value->column_no= column_no; - value.field_value= field_value; -} - -Ndb_item::Ndb_item(Item_func::Functype func_type) : type(NDB_FUNCTION) -{ - qualification.function_type= func_type; -} - -Ndb_item::~Ndb_item() -{ - if (type == NDB_VALUE && - (qualification.value_type == Item::STRING_ITEM || - qualification.value_type == Item::VARBIN_ITEM)) - { - delete value.string_value; - value.string_value= NULL; - } - else if (type == NDB_FIELD) - { - delete value.field_value; - value.field_value= NULL; - } -} - -void Ndb_item::print(String* str) -{ - switch(type) { - case(NDB_VALUE): - str->append("[#NDB_VALUE "); - switch(qualification.value_type) { - case (Item::INT_ITEM): { - String tmp; - tmp.set(value.int_value, &my_charset_bin); - str->append(tmp); - break; - } - case (Item::REAL_ITEM): { - String tmp; - tmp.set(value.real_value, 4 , &my_charset_bin); - str->append(tmp); - break; - } - case (Item::STRING_ITEM): { - str->append(value.string_value->s.ptr()); - break; - } - case (Item::VARBIN_ITEM): { - str->append(value.string_value->s.ptr()); - break; - } - case (Item::NULL_ITEM): - str->append("NULL"); - break; - default: - str->append("ILLEGAL VALUE"); - } - str->append("]"); - break; - case(NDB_FIELD): - str->append("[#NDB_FIELD "); - str->append(value.field_value->field->field_name); - str->append("]"); - break; - case(NDB_FUNCTION): - str->append("[#NDB_FUNCTION "); - switch(qualification.function_type) { - case(Item_func::UNKNOWN_FUNC): { - str->append("UNKNOWN]"); - break; - } - case(Item_func::EQ_FUNC): { - str->append("=]"); - break; - } - case(Item_func::NE_FUNC): { - str->append("!=]"); - break; - } - case(Item_func::LT_FUNC): { - str->append("<]"); - break; - } - case(Item_func::LE_FUNC): { - str->append("<=]"); - break; - } - case(Item_func::GE_FUNC): { - str->append(">=]"); - break; - } - case(Item_func::GT_FUNC): { - str->append(">]"); - break; - } - case(Item_func::LIKE_FUNC): { - str->append("like]"); - break; - } - case(Item_func::NOTLIKE_FUNC): { - str->append("notlike]"); - break; - } - case(Item_func::ISNULL_FUNC): { - str->append("isnull]"); - break; - } - case(Item_func::ISNOTNULL_FUNC): { - str->append("isnotnull]"); - break; - } - case(Item_func::COND_AND_FUNC): { - str->append("and]"); - break; - } - case(Item_func::COND_OR_FUNC): { - str->append("or]"); - break; - } - default: - str->append("UNSUPPORTED]"); - } - break; - case(NDB_END_COND): - str->append("[#NDB_END_COND]"); - } -} - -/* Place holder for ha_ndbcluster thread specific data */ Thd_ndb::Thd_ndb() @@ -4219,8 +4015,8 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_autoincrement_prefetch(32), m_transaction_on(TRUE), m_use_local_query_cache(FALSE), - m_multi_cursor(NULL), - m_cond_stack(NULL) + m_cond_stack(NULL), + m_multi_cursor(NULL) { int i; @@ -5583,28 +5379,24 @@ const COND* ha_ndbcluster::cond_push(const COND *cond) { - THD *thd= current_thd; Ndb_cond_stack *ndb_cond = new Ndb_cond_stack(); DBUG_ENTER("cond_push"); - - if (thd->variables.ndb_condition_pushdown) + DBUG_EXECUTE("where",print_where((COND *)cond, m_tabname);); + if (m_cond_stack) + ndb_cond->next= m_cond_stack; + else + ndb_cond->next= NULL; + m_cond_stack= ndb_cond; + + if (serialize_cond(cond, ndb_cond)) { - DBUG_EXECUTE("where",print_where((COND *)cond, m_tabname);); - if (m_cond_stack) - ndb_cond->next= m_cond_stack; - else - ndb_cond->next= NULL; - m_cond_stack= ndb_cond; - - if (serialize_cond(cond, ndb_cond)) - { - DBUG_RETURN(NULL); - } - else - { - cond_pop(); - } + DBUG_RETURN(NULL); } + else + { + cond_pop(); + } + DBUG_RETURN(cond); } @@ -5618,7 +5410,7 @@ ha_ndbcluster::cond_pop() m_cond_stack= ndb_cond_stack->next; delete ndb_cond_stack; } -}; +} void ha_ndbcluster::cond_clear() @@ -5635,6 +5427,30 @@ void ndb_serialize_cond(const Item *item, void *arg) Ndb_cond_traverse_context *context= (Ndb_cond_traverse_context *) arg; DBUG_ENTER("ndb_serialize_cond"); + // Check if we are skipping arguments to a function to be evaluated + if (context->skip) + { + DBUG_PRINT("info", ("Skiping argument %d", context->skip)); + context->skip--; + switch(item->type()) { + case (Item::FUNC_ITEM): { + Item_func *func_item= (Item_func *) item; + context->skip+= func_item->argument_count(); + break; + } + case(Item::INT_ITEM): + case(Item::REAL_ITEM): + case(Item::STRING_ITEM): + case(Item::VARBIN_ITEM): + break; + default: + *context->supported_ptr= FALSE; + break; + } + + DBUG_VOID_RETURN; + } + if (*context->supported_ptr) { Ndb_cond_stack *ndb_stack= context->stack_ptr; @@ -5645,9 +5461,13 @@ void ndb_serialize_cond(const Item *item, void *arg) curr_cond->prev= prev_cond; if (prev_cond) prev_cond->next= curr_cond; + // Check for end of AND/OR expression if (!item) + { // End marker for condition group + DBUG_PRINT("info", ("End of condition group")); curr_cond->ndb_item= new Ndb_item(NDB_END_COND); + } else switch(item->type()) { case(Item::FIELD_ITEM): { @@ -5669,9 +5489,15 @@ void ndb_serialize_cond(const Item *item, void *arg) // Check that we are expecting a field and with the correct // result type if(context->expecting(Item::FIELD_ITEM) && - ((type == MYSQL_TYPE_DATE || type == MYSQL_TYPE_YEAR) - ? context->expecting_field_result(STRING_RESULT) : true) && - context->expecting_field_result(field->result_type())) + (context->expecting_field_result(field->result_type()) || + // Date and year can be written as strings + (type == MYSQL_TYPE_TIME || + type == MYSQL_TYPE_DATE || + type == MYSQL_TYPE_YEAR || + type == MYSQL_TYPE_DATETIME) + ? context->expecting_field_result(STRING_RESULT) : true) + // Bit fields no yet supported in scan filter + && type != MYSQL_TYPE_BIT) { const NDBCOL *col= tab->getColumn(field->field_name); DBUG_ASSERT(col); @@ -5681,18 +5507,27 @@ void ndb_serialize_cond(const Item *item, void *arg) if (context->expect_mask) { // We have not seen second argument yet - if (type == MYSQL_TYPE_DATE || type == MYSQL_TYPE_YEAR) + if (type == MYSQL_TYPE_TIME || + type == MYSQL_TYPE_DATE || + type == MYSQL_TYPE_YEAR || + type == MYSQL_TYPE_DATETIME) + { context->expect_only(Item::STRING_ITEM); + context->expect(Item::INT_ITEM); + } else switch(field->result_type()) { case(STRING_RESULT): + // Expect char string or binary string context->expect_only(Item::STRING_ITEM); + context->expect(Item::VARBIN_ITEM); break; case(REAL_RESULT): context->expect_only(Item::REAL_ITEM); break; case(INT_RESULT): context->expect_only(Item::INT_ITEM); + context->expect(Item::VARBIN_ITEM); break; default: break; @@ -5710,19 +5545,82 @@ void ndb_serialize_cond(const Item *item, void *arg) context->expect_nothing(); switch(func_item->functype()) { case(Item_func::UNKNOWN_FUNC): { - DBUG_PRINT("info", ("UNKNOWN_FUNC")); - DBUG_PRINT("info", ("value %d", func_item->val_int())); + DBUG_PRINT("info", ("UNKNOWN_FUNC %s", + func_item->const_item()?"const":"")); + DBUG_PRINT("info", ("result type %d", func_item->result_type())); + if (func_item->const_item()) + switch(func_item->result_type()) { + case(STRING_RESULT): { + NDB_ITEM_QUALIFICATION q; + q.value_type= Item::STRING_ITEM; + curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item); + if (context->expect_field_result_mask) + { + // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); + context->expect_only_field_result(STRING_RESULT); + } + else + context->expect_nothing(); + + // Skip any arguments since we will evaluate function instead + DBUG_PRINT("info", ("Skip until end of arguments marker")); + context->skip= func_item->argument_count(); + break; + } + case(REAL_RESULT): { + NDB_ITEM_QUALIFICATION q; + q.value_type= Item::REAL_ITEM; + curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item); + if (context->expect_field_result_mask) + { + // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); + context->expect_only_field_result(REAL_RESULT); + } + else + context->expect_nothing(); + + // Skip any arguments since we will evaluate function instead + DBUG_PRINT("info", ("Skip until end of arguments marker")); + context->skip= func_item->argument_count(); + break; + } + case(INT_RESULT): { + NDB_ITEM_QUALIFICATION q; + q.value_type= Item::INT_ITEM; + curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item); + if (context->expect_field_result_mask) + { + // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); + context->expect_only_field_result(INT_RESULT); + } + else + context->expect_nothing(); + + // Skip any arguments since we will evaluate function instead + DBUG_PRINT("info", ("Skip until end of arguments marker")); + context->skip= func_item->argument_count(); + break; + } + default: + break; + } + else + // Function does not return constant expression + *context->supported_ptr= FALSE; break; } case(Item_func::EQ_FUNC): { DBUG_PRINT("info", ("EQ_FUNC")); curr_cond->ndb_item= new Ndb_item(func_item->functype()); - //context->expect(Item::STRING_ITEM); + context->expect(Item::STRING_ITEM); context->expect(Item::INT_ITEM); context->expect(Item::REAL_ITEM); context->expect(Item::VARBIN_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(INT_RESULT); break; @@ -5730,12 +5628,12 @@ void ndb_serialize_cond(const Item *item, void *arg) case(Item_func::NE_FUNC): { DBUG_PRINT("info", ("NE_FUNC")); curr_cond->ndb_item= new Ndb_item(func_item->functype()); - //context->expect(Item::STRING_ITEM); + context->expect(Item::STRING_ITEM); context->expect(Item::INT_ITEM); context->expect(Item::REAL_ITEM); context->expect(Item::VARBIN_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(INT_RESULT); break; @@ -5743,12 +5641,12 @@ void ndb_serialize_cond(const Item *item, void *arg) case(Item_func::LT_FUNC): { DBUG_PRINT("info", ("LT_FUNC")); curr_cond->ndb_item= new Ndb_item(func_item->functype()); - //context->expect(Item::STRING_ITEM); + context->expect(Item::STRING_ITEM); context->expect(Item::INT_ITEM); context->expect(Item::REAL_ITEM); context->expect(Item::VARBIN_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(INT_RESULT); break; @@ -5756,12 +5654,12 @@ void ndb_serialize_cond(const Item *item, void *arg) case(Item_func::LE_FUNC): { DBUG_PRINT("info", ("LE_FUNC")); curr_cond->ndb_item= new Ndb_item(func_item->functype()); - //context->expect(Item::STRING_ITEM); + context->expect(Item::STRING_ITEM); context->expect(Item::INT_ITEM); context->expect(Item::REAL_ITEM); context->expect(Item::VARBIN_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(INT_RESULT); break; @@ -5769,12 +5667,12 @@ void ndb_serialize_cond(const Item *item, void *arg) case(Item_func::GE_FUNC): { DBUG_PRINT("info", ("GE_FUNC")); curr_cond->ndb_item= new Ndb_item(func_item->functype()); - //context->expect(Item::STRING_ITEM); + context->expect(Item::STRING_ITEM); context->expect(Item::INT_ITEM); context->expect(Item::REAL_ITEM); context->expect(Item::VARBIN_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(INT_RESULT); break; @@ -5782,12 +5680,12 @@ void ndb_serialize_cond(const Item *item, void *arg) case(Item_func::GT_FUNC): { DBUG_PRINT("info", ("GT_FUNC")); curr_cond->ndb_item= new Ndb_item(func_item->functype()); - //context->expect(Item::STRING_ITEM); + context->expect(Item::STRING_ITEM); context->expect(Item::REAL_ITEM); context->expect(Item::INT_ITEM); context->expect(Item::VARBIN_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(INT_RESULT); break; @@ -5833,73 +5731,93 @@ void ndb_serialize_cond(const Item *item, void *arg) break; } case(Item::STRING_ITEM): + DBUG_PRINT("info", ("STRING_ITEM")); if (context->expecting(Item::STRING_ITEM)) { char buff[256]; String str(buff,(uint32) sizeof(buff), system_charset_info); str.length(0); - Item_string *string_item= (Item_string *) item; - DBUG_PRINT("info", ("STRING_ITEM")); + Item_string *string_item= (Item_string *) item; DBUG_PRINT("info", ("value \"%s\"", string_item->val_str(&str)->ptr())); NDB_ITEM_QUALIFICATION q; q.value_type= Item::STRING_ITEM; curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item); - context->dont_expect(Item::STRING_ITEM); if (context->expect_field_result_mask) + { // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); context->expect_only_field_result(STRING_RESULT); + } + else + context->expect_nothing(); } else *context->supported_ptr= FALSE; break; case(Item::INT_ITEM): + DBUG_PRINT("info", ("INT_ITEM")); if (context->expecting(Item::INT_ITEM)) { Item_int *int_item= (Item_int *) item; - DBUG_PRINT("info", ("INT_ITEM")); DBUG_PRINT("info", ("value %d", int_item->value)); - curr_cond->ndb_item= new Ndb_item(int_item->value); - context->dont_expect(Item::INT_ITEM); - if (context->expect_field_result_mask) + NDB_ITEM_QUALIFICATION q; + q.value_type= Item::INT_ITEM; + curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item); + if (context->expect_field_result_mask) + { // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); context->expect_only_field_result(INT_RESULT); + } + else + context->expect_nothing(); } else *context->supported_ptr= FALSE; break; case(Item::REAL_ITEM): + DBUG_PRINT("info", ("REAL_ITEM %s")); if (context->expecting(Item::REAL_ITEM)) { Item_real *real_item= (Item_real *) item; - DBUG_PRINT("info", ("REAL_ITEM %s")); DBUG_PRINT("info", ("value %f", real_item->value)); - curr_cond->ndb_item= new Ndb_item(real_item->value); - context->dont_expect(Item::REAL_ITEM); - if (context->expect_field_result_mask) + NDB_ITEM_QUALIFICATION q; + q.value_type= Item::REAL_ITEM; + curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item); + if (context->expect_field_result_mask) + { // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); context->expect_only_field_result(REAL_RESULT); + } + else + context->expect_nothing(); } else *context->supported_ptr= FALSE; break; case(Item::VARBIN_ITEM): + DBUG_PRINT("info", ("VARBIN_ITEM")); if (context->expecting(Item::VARBIN_ITEM)) { char buff[256]; String str(buff,(uint32) sizeof(buff), system_charset_info); str.length(0); Item_hex_string *varbin_item= (Item_hex_string *) item; - DBUG_PRINT("info", ("VARBIN_ITEM %s")); DBUG_PRINT("info", ("value \"%s\"", varbin_item->val_str(&str)->ptr())); NDB_ITEM_QUALIFICATION q; q.value_type= Item::VARBIN_ITEM; curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item); - context->dont_expect(Item::VARBIN_ITEM); if (context->expect_field_result_mask) + { // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); context->expect_only_field_result(STRING_RESULT); + } + else + context->expect_nothing(); } else *context->supported_ptr= FALSE; @@ -5970,15 +5888,14 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, : (b->type == NDB_FIELD)? b : NULL; if (!value || !field) break; + // Save value in right format for the field type + value->save_in_field(field); DBUG_PRINT("info", ("Generating EQ filter")); - const void* value_ptr = value->get_value(); - if (filter->cmp(NdbScanFilter::COND_EQ, field->get_field_no(), - value_ptr, + field->get_val(), field->pack_length()) == -1) DBUG_RETURN(1); - cond= cond->next->next->next; DBUG_RETURN(0); } @@ -5995,15 +5912,14 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, : (b->type == NDB_FIELD)? b : NULL; if (!value || !field) break; + // Save value in right format for the field type + value->save_in_field(field); DBUG_PRINT("info", ("Generating NE filter")); - const void* value_ptr = value->get_value(); - if (filter->cmp(NdbScanFilter::COND_NE, field->get_field_no(), - value_ptr, + field->get_val(), field->pack_length()) == -1) DBUG_RETURN(1); - cond= cond->next->next->next; DBUG_RETURN(0); } @@ -6020,14 +5936,14 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, : (b->type == NDB_FIELD)? b : NULL; if (!value || !field) break; - const void* value_ptr = value->get_value(); - + // Save value in right format for the field type + value->save_in_field(field); if (a == field) { DBUG_PRINT("info", ("Generating LT filter")); if (filter->cmp(NdbScanFilter::COND_LT, field->get_field_no(), - value_ptr, + field->get_val(), field->pack_length()) == -1) DBUG_RETURN(1); } @@ -6036,11 +5952,10 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, DBUG_PRINT("info", ("Generating GT filter")); if (filter->cmp(NdbScanFilter::COND_GT, field->get_field_no(), - value_ptr, + field->get_val(), field->pack_length()) == -1) DBUG_RETURN(1); } - cond= cond->next->next->next; DBUG_RETURN(0); } @@ -6057,27 +5972,26 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, : (b->type == NDB_FIELD)? b : NULL; if (!value || !field) break; - const void* value_ptr = value->get_value(); - + // Save value in right format for the field type + value->save_in_field(field); if (a == field) { DBUG_PRINT("info", ("Generating LE filter")); if (filter->cmp(NdbScanFilter::COND_LE, field->get_field_no(), - value_ptr, + field->get_val(), field->pack_length()) == -1) - DBUG_RETURN(1); + DBUG_RETURN(1); } else { DBUG_PRINT("info", ("Generating GE filter")); if (filter->cmp(NdbScanFilter::COND_GE, field->get_field_no(), - value_ptr, + field->get_val(), field->pack_length()) == -1) DBUG_RETURN(1); } - cond= cond->next->next->next; DBUG_RETURN(0); } @@ -6094,14 +6008,14 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, : (b->type == NDB_FIELD)? b : NULL; if (!value || !field) break; - const void* value_ptr = value->get_value(); - + // Save value in right format for the field type + value->save_in_field(field); if (a == field) { DBUG_PRINT("info", ("Generating GE filter")); if (filter->cmp(NdbScanFilter::COND_GE, field->get_field_no(), - value_ptr, + field->get_val(), field->pack_length()) == -1) DBUG_RETURN(1); } @@ -6110,11 +6024,10 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, DBUG_PRINT("info", ("Generating LE filter")); if (filter->cmp(NdbScanFilter::COND_LE, field->get_field_no(), - value_ptr, + field->get_val(), field->pack_length()) == -1) DBUG_RETURN(1); } - cond= cond->next->next->next; DBUG_RETURN(0); } @@ -6131,17 +6044,14 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, : (b->type == NDB_FIELD)? b : NULL; if (!value || !field) break; - const void* value_ptr = value->get_value(); - - if (!value) - DBUG_RETURN(1); - + // Save value in right format for the field type + value->save_in_field(field); if (a == field) { DBUG_PRINT("info", ("Generating GT filter")); if (filter->cmp(NdbScanFilter::COND_GT, field->get_field_no(), - value_ptr, + field->get_val(), field->pack_length()) == -1) DBUG_RETURN(1); } @@ -6150,11 +6060,10 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, DBUG_PRINT("info", ("Generating LT filter")); if (filter->cmp(NdbScanFilter::COND_LT, field->get_field_no(), - value_ptr, + field->get_val(), field->pack_length()) == -1) DBUG_RETURN(1); } - cond= cond->next->next->next; DBUG_RETURN(0); } @@ -6172,11 +6081,17 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, : NULL; if (!value || !field) break; if (value->qualification.value_type != Item::STRING_ITEM) break; - String *str= value->get_string_value(); - DBUG_PRINT("info", ("Generating LIKE filter: like(%d,%s,%d)", field->get_field_no(), str->ptr(), str->length())); - //if (filter->like(field->get_field_no(), - // str->ptr(), str->length(), TRUE) == -1) - // DBUG_RETURN(1); + // Save value in right format for the field type + value->save_in_field(field); + DBUG_PRINT("info", ("Generating LIKE filter: like(%d,%s,%d)", + field->get_field_no(), field->get_val(), + field->pack_length())); + /* + if (filter->like(field->get_field_no(), + field->get_val(), + field->pack_length()) == -1) + DBUG_RETURN(1); + */ cond= cond->next->next->next; DBUG_RETURN(0); } @@ -6194,11 +6109,16 @@ ha_ndbcluster::build_scan_filter_predicate(Ndb_cond * &cond, : NULL; if (!value || !field) break; if (value->qualification.value_type != Item::STRING_ITEM) break; - String *str= value->get_string_value(); - DBUG_PRINT("info", ("Generating NOTLIKE filter: notlike(%d,%s,%d)", field->get_field_no(), str->ptr(), str->length())); - //if (filter->notlike(field->get_field_no(), - // str->ptr(), str->length()) == -1) - // DBUG_RETURN(1); + // Save value in right format for the field type + value->save_in_field(field); + DBUG_PRINT("info", ("Generating NOTLIKE filter: notlike(%d,%s,%d)", + field->get_field_no(), field->get_val(), + field->pack_length())); + /* + if (filter->notlike(field->get_field_no(), + field->get_val(), field->pack_length()) == -1) + DBUG_RETURN(1); + */ cond= cond->next->next->next; DBUG_RETURN(0); } diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index c660d8f618d..1c502db6d32 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -75,74 +75,89 @@ typedef union ndb_item_qualification { Item_func::Functype function_type; // Instead of Item::FUNC_ITEM } NDB_ITEM_QUALIFICATION; -class Ndb_item_string_value { - public: - String s; - CHARSET_INFO *c; -}; - typedef struct ndb_item_field_value { Field* field; int column_no; } NDB_ITEM_FIELD_VALUE; typedef union ndb_item_value { - longlong int_value; - double real_value; - Ndb_item_string_value *string_value; + const Item *item; NDB_ITEM_FIELD_VALUE *field_value; } NDB_ITEM_VALUE; class Ndb_item { public: - Ndb_item(NDB_ITEM_TYPE item_type); + Ndb_item(NDB_ITEM_TYPE item_type) : type(item_type) {}; Ndb_item(NDB_ITEM_TYPE item_type, NDB_ITEM_QUALIFICATION item_qualification, - const Item *item_value); - Ndb_item(longlong int_value); - Ndb_item(double real_value); - Ndb_item(Field *field, int column_no); - Ndb_item(Item_func::Functype func_type); - ~Ndb_item(); - void print(String *str); - uint32 pack_length() { return value.field_value->field->pack_length(); }; - // Getters and Setters - longlong get_int_value() { return value.int_value; }; - double get_real_value() { return value.real_value; }; - String * get_string_value() { return &value.string_value->s; }; - CHARSET_INFO * get_string_charset() { return value.string_value->c; }; - Field * get_field() { return value.field_value->field; }; - int get_field_no() { return value.field_value->column_no; }; - - const void * get_value() - { - switch(qualification.value_type) { - case(Item::INT_ITEM): { - return (void *) &value.int_value; - } - case(Item::REAL_ITEM): { - return (void *) &value.real_value; + const Item *item_value) + : type(item_type), qualification(item_qualification) + { + switch(item_type) { + case(NDB_VALUE): + value.item= item_value; + break; + case(NDB_FIELD): { + NDB_ITEM_FIELD_VALUE *field_value= new NDB_ITEM_FIELD_VALUE(); + Item_field *field_item= (Item_field *) item_value; + field_value->field= field_item->field; + field_value->column_no= -1; // Will be fetched at scan filter generation + value.field_value= field_value; break; } - case(Item::STRING_ITEM): - case(Item::VARBIN_ITEM): { - return value.string_value->s.ptr(); + case(NDB_FUNCTION): + case(NDB_END_COND): + break; } + }; + Ndb_item(Field *field, int column_no) : type(NDB_FIELD) + { + NDB_ITEM_FIELD_VALUE *field_value= new NDB_ITEM_FIELD_VALUE(); + qualification.field_type= field->type(); + field_value->field= field; + field_value->column_no= column_no; + value.field_value= field_value; + }; + Ndb_item(Item_func::Functype func_type) : type(NDB_FUNCTION) + { + qualification.function_type= func_type; + }; + ~Ndb_item() + { + if (type == NDB_FIELD) + { + delete value.field_value; + value.field_value= NULL; + } + }; + + uint32 pack_length() + { + switch(type) { + case(NDB_FIELD): + return value.field_value->field->pack_length(); default: break; } + + return 0; + }; + Field * get_field() { return value.field_value->field; }; + int get_field_no() { return value.field_value->column_no; }; + char* get_val() { return value.field_value->field->ptr; }; + void save_in_field(Ndb_item *field_item) + { + Field *field = field_item->value.field_value->field; + const Item *item= value.item; - return NULL; + if (item && field) + ((Item *)item)->save_in_field(field, false); } - - public: + NDB_ITEM_TYPE type; NDB_ITEM_QUALIFICATION qualification; - - private: NDB_ITEM_VALUE value; - }; class Ndb_cond { @@ -179,7 +194,7 @@ class Ndb_cond_traverse_context { bool *supported, Ndb_cond_stack* stack) : table(tab), ndb_table(ndb_tab), supported_ptr(supported), stack_ptr(stack), cond_ptr(NULL), - expect_mask(0), expect_field_result_mask(0) + expect_mask(0), expect_field_result_mask(0), skip(0) { if (stack) cond_ptr= stack->ndb_cond; @@ -231,6 +246,7 @@ class Ndb_cond_traverse_context { Ndb_cond* cond_ptr; uint expect_mask; uint expect_field_result_mask; + uint skip; }; /* @@ -406,7 +422,7 @@ class ha_ndbcluster: public handler void no_uncommitted_rows_reset(THD *); /* - Condition Pushdown to Handler (CPDH), private methods + Condition pushdown */ void cond_clear(); bool serialize_cond(const COND *cond, Ndb_cond_stack *ndb_cond); diff --git a/sql/item_func.cc b/sql/item_func.cc index 607efe06e77..4c20c5adcaf 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -352,7 +352,7 @@ void Item_func::traverse_cond(Item_cond_traverser traverser, switch (order) { case(PREFIX): - (traverser)(this, argument); + (*traverser)(this, argument); for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++) { (*arg)->traverse_cond(traverser, argument, order); @@ -363,7 +363,7 @@ void Item_func::traverse_cond(Item_cond_traverser traverser, { (*arg)->traverse_cond(traverser, argument, order); } - (traverser)(this, argument); + (*traverser)(this, argument); } } } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ae27af1e755..84830fc04a7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4172,9 +4172,9 @@ enum options_mysqld OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG, OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG, OPT_INNODB, OPT_ISAM, + OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT, OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ, - OPT_NDB_CONDITION_PUSHDOWN, OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_SKIP_SAFEMALLOC, OPT_TEMP_POOL, OPT_TX_ISOLATION, @@ -4424,6 +4424,12 @@ Disable with --skip-bdb (will save memory).", {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.", (gptr*) &opt_do_pstack, (gptr*) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"engine-condition-pushdown", + OPT_ENGINE_CONDITION_PUSHDOWN, + "Push supported query conditions to the storage engine.", + (gptr*) &global_system_variables.engine_condition_pushdown, + (gptr*) &global_system_variables.engine_condition_pushdown, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running.", @@ -4657,12 +4663,6 @@ Disable with --skip-ndbcluster (will save memory).", (gptr*) &opt_ndbcluster, (gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG, OPT_NDBCLUSTER_DEFAULT, 0, 0, 0, 0, 0}, #ifdef HAVE_NDBCLUSTER_DB - {"ndb-condition-pushdown", - OPT_NDB_CONDITION_PUSHDOWN, - "Push supported query conditions to the ndbcluster storage engine.", - (gptr*) &global_system_variables.ndb_condition_pushdown, - (gptr*) &global_system_variables.ndb_condition_pushdown, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"ndb-connectstring", OPT_NDB_CONNECTSTRING, "Connect string for ndbcluster.", (gptr*) &opt_ndbcluster_connectstring, diff --git a/sql/set_var.cc b/sql/set_var.cc index d09de8550f0..d140a6abb38 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -388,6 +388,11 @@ sys_var_long_ptr sys_innodb_thread_concurrency("innodb_thread_concurrency", &srv_thread_concurrency); #endif +/* Condition pushdown to storage engine */ +sys_var_thd_bool +sys_engine_condition_pushdown("engine_condition_pushdown", + &SV::engine_condition_pushdown); + #ifdef HAVE_NDBCLUSTER_DB /* ndb thread specific variable settings */ sys_var_thd_ulong @@ -399,9 +404,6 @@ sys_var_thd_bool sys_ndb_use_exact_count("ndb_use_exact_count", &SV::ndb_use_exact_count); sys_var_thd_bool sys_ndb_use_transactions("ndb_use_transactions", &SV::ndb_use_transactions); -sys_var_thd_bool -sys_ndb_condition_pushdown("ndb_condition_pushdown", - &SV::ndb_condition_pushdown); #endif /* Time/date/datetime formats */ @@ -668,12 +670,12 @@ sys_var *sys_variables[]= &sys_innodb_thread_sleep_delay, &sys_innodb_thread_concurrency, #endif + &sys_engine_condition_pushdown, #ifdef HAVE_NDBCLUSTER_DB &sys_ndb_autoincrement_prefetch_sz, &sys_ndb_force_send, &sys_ndb_use_exact_count, &sys_ndb_use_transactions, - &sys_ndb_condition_pushdown, #endif &sys_unique_checks, &sys_updatable_views_with_limit, @@ -847,14 +849,14 @@ struct show_var_st init_vars[]= { #ifdef __NT__ {"named_pipe", (char*) &opt_enable_named_pipe, SHOW_MY_BOOL}, #endif + {sys_engine_condition_pushdown.name, + (char*) &sys_engine_condition_pushdown, SHOW_SYS}, #ifdef HAVE_NDBCLUSTER_DB {sys_ndb_autoincrement_prefetch_sz.name, (char*) &sys_ndb_autoincrement_prefetch_sz, SHOW_SYS}, {sys_ndb_force_send.name, (char*) &sys_ndb_force_send, SHOW_SYS}, {sys_ndb_use_exact_count.name,(char*) &sys_ndb_use_exact_count, SHOW_SYS}, {sys_ndb_use_transactions.name,(char*) &sys_ndb_use_transactions, SHOW_SYS}, - {sys_ndb_condition_pushdown.name, (char*) &sys_ndb_condition_pushdown, - SHOW_SYS}, #endif {sys_net_buffer_length.name,(char*) &sys_net_buffer_length, SHOW_SYS}, {sys_net_read_timeout.name, (char*) &sys_net_read_timeout, SHOW_SYS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index 240208584e7..502ce2e52a2 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -430,6 +430,7 @@ struct system_variables my_bool low_priority_updates; my_bool new_mode; my_bool query_cache_wlock_invalidate; + my_bool engine_condition_pushdown; #ifdef HAVE_INNOBASE_DB my_bool innodb_table_locks; #endif /* HAVE_INNOBASE_DB */ @@ -438,7 +439,6 @@ struct system_variables my_bool ndb_force_send; my_bool ndb_use_exact_count; my_bool ndb_use_transactions; - my_bool ndb_condition_pushdown; #endif /* HAVE_NDBCLUSTER_DB */ my_bool old_passwords; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 60273d21d9f..78d625f59bb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5300,7 +5300,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (!(tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0))) DBUG_RETURN(1); tab->select_cond=sel->cond=tmp; - tab->table->file->cond_push(tmp); // Push condition to handler + if (current_thd->variables.engine_condition_pushdown) + tab->table->file->cond_push(tmp); // Push condition to handler } else tab->select_cond= sel->cond= NULL; @@ -5422,7 +5423,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) join->thd->memdup((gptr) sel, sizeof(SQL_SELECT)); tab->cache.select->cond=tmp; tab->cache.select->read_tables=join->const_table_map; - if (tmp != tab->select_cond) + if (current_thd->variables.engine_condition_pushdown && + (tmp != tab->select_cond)) tab->table->file->cond_push(tmp); // Push condition to handler } } |