Commit 9968b41d authored by unknown's avatar unknown
Browse files

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
parent a2bb52c7
Loading
Loading
Loading
Loading
+88 −30
Original line number Diff line number Diff line
DROP TABLE IF EXISTS t1,t2;
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",	
string char(10),
vstring varchar(10),
bin binary(7),
vbin varbinary(7),	
tiny tinyint(4) DEFAULT '0' NOT NULL ,
short smallint(6) DEFAULT '1' NOT NULL ,
medium mediumint(8) DEFAULT '0' NOT NULL,
@@ -233,17 +233,41 @@ auto
2
3
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;
pk1	attr1	attr2	attr3
2	2	NULL	NULL
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;
pk1	attr1	attr2	attr3	attr4
2	2	9223372036854775804	2	c
4	4	9223372036854775806	4	e
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
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;
pk1	attr1	attr2	attr3	attr4
2	2	9223372036854775804	2	c
@@ -257,8 +281,8 @@ set engine_condition_pushdown = on;
select auto from t1 where 
string = "aaaa" and 
vstring = "aaaa" and 
bin = "aaaa" and 
vbin = "aaaa" and 
/* bin = "aaaa" and 
vbin = "aaaa" and */
tiny = -1 and 
short = -1 and 
medium = -1 and 
@@ -285,8 +309,8 @@ auto
select auto from t1 where 
string != "aaaa" and 
vstring != "aaaa" and 
bin != "aaaa" and 
vbin != "aaaa" and 
/* bin != "aaaa" and 
vbin != "aaaa" and */
tiny != -1 and 
short != -1 and 
medium != -1 and 
@@ -315,8 +339,8 @@ auto
select auto from t1 where 
string > "aaaa" and 
vstring > "aaaa" and 
bin > "aaaa" and 
vbin > "aaaa" and 
/* bin > "aaaa" and 
vbin > "aaaa" and */
tiny < -1 and 
short < -1 and 
medium < -1 and 
@@ -345,8 +369,8 @@ auto
select auto from t1 where 
string >= "aaaa" and 
vstring >= "aaaa" and 
bin >= "aaaa" and 
vbin >= "aaaa" and 
/* bin >= "aaaa" and 
vbin >= "aaaa" and */
tiny <= -1 and 
short <= -1 and 
medium <= -1 and 
@@ -376,8 +400,8 @@ auto
select auto from t1 where 
string < "dddd" and 
vstring < "dddd" and 
bin < "dddd" and 
vbin < "dddd" and 
/* bin < "dddd" and 
vbin < "dddd" and */
tiny > -4 and 
short > -4 and 
medium > -4 and 
@@ -406,8 +430,8 @@ auto
select auto from t1 where 
string <= "dddd" and 
vstring <= "dddd" and 
bin <= "dddd" and 
vbin <= "dddd" and 
/* bin <= "dddd" and 
vbin <= "dddd" and */
tiny >= -4 and 
short >= -4 and 
medium >= -4 and 
@@ -438,8 +462,8 @@ create index medium_index on t1(medium);
select auto from t1 where 
string = "aaaa" and 
vstring = "aaaa" and 
bin = "aaaa" and 
vbin = "aaaa" and 
/* bin = "aaaa" and 
vbin = "aaaa" and */
tiny = -1 and 
short = -1 and 
medium = -1 and 
@@ -466,8 +490,8 @@ auto
select auto from t1 where 
string != "aaaa" and 
vstring != "aaaa" and 
bin != "aaaa" and 
vbin != "aaaa" and 
/* bin != "aaaa" and 
vbin != "aaaa" and */
tiny != -1 and 
short != -1 and 
medium != -1 and 
@@ -496,8 +520,8 @@ auto
select auto from t1 where 
string > "aaaa" and 
vstring > "aaaa" and 
bin > "aaaa" and 
vbin > "aaaa" and 
/* bin > "aaaa" and 
vbin > "aaaa" and */
tiny < -1 and 
short < -1 and 
medium < -1 and 
@@ -526,8 +550,8 @@ auto
select auto from t1 where 
string >= "aaaa" and 
vstring >= "aaaa" and 
bin >= "aaaa" and 
vbin >= "aaaa" and 
/* bin >= "aaaa" and 
vbin >= "aaaa" and */
tiny <= -1 and 
short <= -1 and 
medium <= -1 and 
@@ -557,8 +581,8 @@ auto
select auto from t1 where 
string < "dddd" and 
vstring < "dddd" and 
bin < "dddd" and 
vbin < "dddd" and 
/* bin < "dddd" and 
vbin < "dddd" and */
tiny > -4 and 
short > -4 and 
medium > -4 and 
@@ -587,8 +611,8 @@ auto
select auto from t1 where 
string <= "dddd" and 
vstring <= "dddd" and 
bin <= "dddd" and 
vbin <= "dddd" and 
/* bin <= "dddd" and 
vbin <= "dddd" and */
tiny >= -4 and 
short >= -4 and 
medium >= -4 and 
@@ -615,17 +639,41 @@ auto
2
3
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;
pk1	attr1	attr2	attr3
2	2	NULL	NULL
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;
pk1	attr1	attr2	attr3	attr4
2	2	9223372036854775804	2	c
4	4	9223372036854775806	4	e
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
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;
pk1	attr1	attr2	attr3	attr4
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
3	3	9223372036854775805	3	d	3	3	9223372036854775805	3	d
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;
DROP TABLE t1,t2,t3,t4;
+67 −30
Original line number Diff line number Diff line
@@ -9,10 +9,10 @@ DROP TABLE IF EXISTS t1,t2;
#
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",	
  string char(10),
  vstring varchar(10),
  bin binary(7),
  vbin varbinary(7),	
  tiny tinyint(4) DEFAULT '0' NOT NULL ,
  short smallint(6) DEFAULT '1' 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' 
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 
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 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 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 
string = "aaaa" and 
vstring = "aaaa" and 
bin = "aaaa" and 
vbin = "aaaa" and 
/* bin = "aaaa" and 
vbin = "aaaa" and */
tiny = -1 and 
short = -1 and 
medium = -1 and 
@@ -273,8 +289,8 @@ order by auto;
select auto from t1 where 
string != "aaaa" and 
vstring != "aaaa" and 
bin != "aaaa" and 
vbin != "aaaa" and 
/* bin != "aaaa" and 
vbin != "aaaa" and */
tiny != -1 and 
short != -1 and 
medium != -1 and 
@@ -300,8 +316,8 @@ order by auto;
select auto from t1 where 
string > "aaaa" and 
vstring > "aaaa" and 
bin > "aaaa" and 
vbin > "aaaa" and 
/* bin > "aaaa" and 
vbin > "aaaa" and */
tiny < -1 and 
short < -1 and 
medium < -1 and 
@@ -327,8 +343,8 @@ order by auto;
select auto from t1 where 
string >= "aaaa" and 
vstring >= "aaaa" and 
bin >= "aaaa" and 
vbin >= "aaaa" and 
/* bin >= "aaaa" and 
vbin >= "aaaa" and */
tiny <= -1 and 
short <= -1 and 
medium <= -1 and 
@@ -354,8 +370,8 @@ order by auto;
select auto from t1 where 
string < "dddd" and 
vstring < "dddd" and 
bin < "dddd" and 
vbin < "dddd" and 
/* bin < "dddd" and 
vbin < "dddd" and */
tiny > -4 and 
short > -4 and 
medium > -4 and 
@@ -381,8 +397,8 @@ order by auto;
select auto from t1 where 
string <= "dddd" and 
vstring <= "dddd" and 
bin <= "dddd" and 
vbin <= "dddd" and 
/* bin <= "dddd" and 
vbin <= "dddd" and */
tiny >= -4 and 
short >= -4 and 
medium >= -4 and 
@@ -412,8 +428,8 @@ create index medium_index on t1(medium);
select auto from t1 where 
string = "aaaa" and 
vstring = "aaaa" and 
bin = "aaaa" and 
vbin = "aaaa" and 
/* bin = "aaaa" and 
vbin = "aaaa" and */
tiny = -1 and 
short = -1 and 
medium = -1 and 
@@ -439,8 +455,8 @@ order by auto;
select auto from t1 where 
string != "aaaa" and 
vstring != "aaaa" and 
bin != "aaaa" and 
vbin != "aaaa" and 
/* bin != "aaaa" and 
vbin != "aaaa" and */
tiny != -1 and 
short != -1 and 
medium != -1 and 
@@ -466,8 +482,8 @@ order by auto;
select auto from t1 where 
string > "aaaa" and 
vstring > "aaaa" and 
bin > "aaaa" and 
vbin > "aaaa" and 
/* bin > "aaaa" and 
vbin > "aaaa" and */
tiny < -1 and 
short < -1 and 
medium < -1 and 
@@ -493,8 +509,8 @@ order by auto;
select auto from t1 where 
string >= "aaaa" and 
vstring >= "aaaa" and 
bin >= "aaaa" and 
vbin >= "aaaa" and 
/* bin >= "aaaa" and 
vbin >= "aaaa" and */
tiny <= -1 and 
short <= -1 and 
medium <= -1 and 
@@ -520,8 +536,8 @@ order by auto;
select auto from t1 where 
string < "dddd" and 
vstring < "dddd" and 
bin < "dddd" and 
vbin < "dddd" and 
/* bin < "dddd" and 
vbin < "dddd" and */
tiny > -4 and 
short > -4 and 
medium > -4 and 
@@ -547,8 +563,8 @@ order by auto;
select auto from t1 where 
string <= "dddd" and 
vstring <= "dddd" and 
bin <= "dddd" and 
vbin <= "dddd" and 
/* bin <= "dddd" and 
vbin <= "dddd" and */
tiny >= -4 and 
short >= -4 and 
medium >= -4 and 
@@ -571,11 +587,32 @@ time_field <= '04:04:04' and
date_time <= '1904-04-04 04:04:04' 
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 
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 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 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;
DROP TABLE t1,t2,t3,t4;
+218 −188

File changed.

Preview size limit exceeded, changes collapsed.

+70 −28
Original line number Diff line number Diff line
@@ -109,9 +109,17 @@ static const negated_function_mapping neg_map[]=
};
  
/*
  This class is used for serialization of the Item tree for
  condition pushdown. It is stored in a linked list implemented
  by Ndb_cond class.
  This class is the construction element for serialization of Item tree 
  in condition pushdown.
  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 {
 public:
@@ -134,6 +142,8 @@ class Ndb_item {
      break;
    }
    case(NDB_FUNCTION):
      value.item= item_value;
      break;
    case(NDB_END_COND):
      break;
    }
@@ -146,9 +156,11 @@ class Ndb_item {
    field_value->column_no= column_no;
    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;
    value.item= item_value;
  };
  ~Ndb_item()
  { 
@@ -179,6 +191,11 @@ class Ndb_item {

  int get_field_no() { return value.field_value->column_no; };

  int argument_count() 
  { 
    return ((Item_func *) value.item)->argument_count(); 
  };

  const char* get_val() 
  {  
    switch(type) {
@@ -274,7 +291,7 @@ class Ndb_cond_traverse_context
  Ndb_cond_traverse_context(TABLE *tab, void* ndb_tab, Ndb_cond_stack* stack)
    : table(tab), ndb_table(ndb_tab), 
    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)
      cond_ptr= stack->ndb_cond;
@@ -318,6 +335,17 @@ class Ndb_cond_traverse_context
    expect_field_result_mask= 0;
    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;
  void* ndb_table;
@@ -327,6 +355,8 @@ class Ndb_cond_traverse_context
  uint expect_mask;
  uint expect_field_result_mask;
  uint skip;
  CHARSET_INFO* collation;

};

/*
@@ -428,26 +458,39 @@ class ha_ndbcluster: public handler
  /*
    Condition pushdown
  */

 /*
  Push a condition to ndbcluster storage engine for evaluation 
  during table   and index scans. The conditions will be stored on a stack
  for possibly storing several conditions. The stack can be popped
  by calling cond_pop, handler::extra(HA_EXTRA_RESET) (handler::reset())
  will clear the stack.
   Push condition down to the table handler.
   SYNOPSIS
     cond_push()
     cond   Condition to be pushed. The condition tree must not be
     modified by the by the caller.
   RETURN
     The 'remainder' condition that caller must use to filter out records.
     NULL means the handler will not return rows that do not match the
     passed condition.
   NOTES
   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.
   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:
  =, !=, >, >=, <, <=, "is null", and "is not null".
  
  RETURN
    NULL The condition was supported and will be evaluated for each 
    row found during the scan
    cond The condition was not supported and all rows will be returned from
         the scan for evaluation (and thus not saved on stack)
   =, !=, >, >=, <, <=, 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);
 /*
   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();

@@ -536,8 +579,7 @@ class ha_ndbcluster: public handler
                                  NdbScanFilter* filter,
                                  bool negated= false);
  int build_scan_filter_group(Ndb_cond* &cond, 
                              NdbScanFilter* filter,
                              bool negated= false);
                              NdbScanFilter* filter);
  int build_scan_filter(Ndb_cond* &cond, NdbScanFilter* filter);
  int generate_scan_filter(Ndb_cond_stack* cond_stack, 
                           NdbScanOperation* op);
+30 −18
Original line number Diff line number Diff line
@@ -451,7 +451,7 @@ class handler :public Sql_alloc
  enum {NONE=0, INDEX, RND} inited;
  bool  auto_increment_column_changed;
  bool implicit_emptied;                /* Can be !=0 only if HEAP */

  const COND *pushed_cond;

  handler(TABLE *table_arg) :table(table_arg),
    ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0),
@@ -460,7 +460,8 @@ class handler :public Sql_alloc
    create_time(0), check_time(0), update_time(0),
    key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
    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); */ }
  int ha_open(const char *name, int mode, int test_if_locked);
@@ -725,21 +726,32 @@ class handler :public Sql_alloc
 */

 /*
  Push a condition to storage engine for evaluation during table
  and index scans. The conditions should be stored on a stack
  for possibly storing several conditions. The stack can be popped
  by calling cond_pop, handler::extra(HA_EXTRA_RESET) (handler::reset())
  should clear the stack.
  The condition can be traversed using Item::traverse_cond
   Push condition down to the table handler.
   SYNOPSIS
     cond_push()
     cond   Condition to be pushed. The condition tree must not be            
     modified by the by the caller.
   RETURN
    NULL The condition was supported by the handler and will be evaluated
         for each row found during the scan
    cond The condition was not supported and all rows will be returned from
         the scan for evaluation (and thus not saved on stack)
     The 'remainder' condition that caller must use to filter out records.
     NULL means the handler will not return rows that do not match the
     passed condition.
   NOTES
   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; };
 /*
   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; };
};
Loading