MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Martin Skold Date:March 18 2008 12:25pm
Subject:bk commit into 5.0 tree (mskold:1.2572) BUG#35185
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of mskold.  When mskold does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-03-18 13:25:03+01:00, mskold@stripped +4 -0
  bug#35185  SELECT LIKE gives wrong results when ndbcluster engine is used: Disabled condition pushdown of <string> LIKE <field> until this is supported

  mysql-test/r/ndb_condition_pushdown.result@stripped, 2008-03-18 13:24:56+01:00, mskold@stripped +32 -0
    bug#35185  SELECT LIKE gives wrong results when ndbcluster engine is used: Disabled condition pushdown of <string> LIKE <field> until this is supported

  mysql-test/t/ndb_condition_pushdown.test@stripped, 2008-03-18 13:24:56+01:00, mskold@stripped +31 -0
    bug#35185  SELECT LIKE gives wrong results when ndbcluster engine is used: Disabled condition pushdown of <string> LIKE <field> until this is supported

  sql/ha_ndbcluster_cond.cc@stripped, 2008-03-18 13:24:56+01:00, mskold@stripped +17 -3
    bug#35185  SELECT LIKE gives wrong results when ndbcluster engine is used: Disabled condition pushdown of <string> LIKE <field> until this is supported

  sql/ha_ndbcluster_cond.h@stripped, 2008-03-18 13:24:56+01:00, mskold@stripped +157 -40
    bug#35185  SELECT LIKE gives wrong results when ndbcluster engine is used: Disabled condition pushdown of <string> LIKE <field> until this is supported

diff -Nrup a/mysql-test/r/ndb_condition_pushdown.result b/mysql-test/r/ndb_condition_pushdown.result
--- a/mysql-test/r/ndb_condition_pushdown.result	2008-01-31 13:57:37 +01:00
+++ b/mysql-test/r/ndb_condition_pushdown.result	2008-03-18 13:24:56 +01:00
@@ -1889,6 +1889,38 @@ SELECT fname, lname FROM t1 WHERE (fname
 fname	lname
 Young	Foo
 drop table t1;
+CREATE TABLE NodeAlias (
+id int(10) unsigned NOT NULL AUTO_INCREMENT,
+nodeId int(10) unsigned NOT NULL,
+displayName varchar(45) DEFAULT NULL,
+aliasKey varchar(45) DEFAULT NULL,
+objectVersion int(10) unsigned NOT NULL DEFAULT '0',
+changed timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+PRIMARY KEY (id),
+KEY NodeAlias_identifies_1_Node (nodeId),
+KEY NodeAlias_KeyIndex (aliasKey)
+) engine=ndb;
+insert into NodeAlias VALUES(null, 2 , '49', '49',  0,'2008-03-07 14:54:59');
+insert into NodeAlias VALUES(null, 3 , '49' , '49' , 0 , '2008-03-07 14:55:24');
+insert into NodeAlias VALUES(null, 4 , '49' , '49' , 0 , '2008-03-07 14:55:51');
+insert into NodeAlias VALUES(null, 5 , '150' , '150' , 0 , '2008-03-10 10:48:30');
+insert into NodeAlias VALUES(null, 6 , '154' , '154' , 0 , '2008-03-10 10:48:43');
+insert into NodeAlias VALUES(null, 7 , '158' , '158' , 0 , '2008-03-10 10:48:57');
+insert into NodeAlias VALUES(null, 8 , '491803%' , '491803%' , 0 , '2008-03-10
+12:22:26');
+explain select * from NodeAlias where (aliasKey LIKE '491803%');
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	NodeAlias	range	NodeAlias_KeyIndex	NodeAlias_KeyIndex	48	NULL	10	Using where with pushed condition
+select * from NodeAlias where (aliasKey LIKE '491803%') order by id;
+id	nodeId	displayName	aliasKey	objectVersion	changed
+7	8	491803%	491803%	0	2008-03-10 12:22:26
+explain select * from NodeAlias where ('4918031215220' LIKE aliasKey OR aliasKey LIKE '4918031215220');
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	NodeAlias	ALL	NodeAlias_KeyIndex	NULL	NULL	NULL	7	Using where
+select * from NodeAlias where ('4918031215220' LIKE aliasKey OR aliasKey LIKE '4918031215220') order by id;
+id	nodeId	displayName	aliasKey	objectVersion	changed
+7	8	491803%	491803%	0	2008-03-10 12:22:26
+drop table NodeAlias;
 create table t1 (a int, b int, c int, d int, primary key using hash(a))
 engine=ndbcluster;
 insert into t1 values (10,1,100,0+0x1111);
diff -Nrup a/mysql-test/t/ndb_condition_pushdown.test b/mysql-test/t/ndb_condition_pushdown.test
--- a/mysql-test/t/ndb_condition_pushdown.test	2008-01-31 13:57:37 +01:00
+++ b/mysql-test/t/ndb_condition_pushdown.test	2008-03-18 13:24:56 +01:00
@@ -1723,6 +1723,37 @@ SELECT fname, lname FROM t1 WHERE (fname
 
 drop table t1;
 
+# bug#35185  SELECT LIKE gives wrong results when ndbcluster engine is used
+ 
+CREATE TABLE NodeAlias (
+id int(10) unsigned NOT NULL AUTO_INCREMENT,
+nodeId int(10) unsigned NOT NULL,
+displayName varchar(45) DEFAULT NULL,
+aliasKey varchar(45) DEFAULT NULL,
+objectVersion int(10) unsigned NOT NULL DEFAULT '0',
+changed timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+PRIMARY KEY (id),
+KEY NodeAlias_identifies_1_Node (nodeId),
+KEY NodeAlias_KeyIndex (aliasKey)
+) engine=ndb;
+
+insert into NodeAlias VALUES(null, 2 , '49', '49',  0,'2008-03-07 14:54:59');
+insert into NodeAlias VALUES(null, 3 , '49' , '49' , 0 , '2008-03-07 14:55:24');
+insert into NodeAlias VALUES(null, 4 , '49' , '49' , 0 , '2008-03-07 14:55:51');
+insert into NodeAlias VALUES(null, 5 , '150' , '150' , 0 , '2008-03-10 10:48:30');
+insert into NodeAlias VALUES(null, 6 , '154' , '154' , 0 , '2008-03-10 10:48:43');
+insert into NodeAlias VALUES(null, 7 , '158' , '158' , 0 , '2008-03-10 10:48:57');
+insert into NodeAlias VALUES(null, 8 , '491803%' , '491803%' , 0 , '2008-03-10
+12:22:26');
+
+explain select * from NodeAlias where (aliasKey LIKE '491803%'); 
+select * from NodeAlias where (aliasKey LIKE '491803%') order by id; 
+
+explain select * from NodeAlias where ('4918031215220' LIKE aliasKey OR aliasKey LIKE '4918031215220'); 
+select * from NodeAlias where ('4918031215220' LIKE aliasKey OR aliasKey LIKE '4918031215220') order by id; 
+
+drop table NodeAlias;
+
 create table t1 (a int, b int, c int, d int, primary key using hash(a))
     engine=ndbcluster;
 
diff -Nrup a/sql/ha_ndbcluster_cond.cc b/sql/ha_ndbcluster_cond.cc
--- a/sql/ha_ndbcluster_cond.cc	2007-10-04 10:52:14 +02:00
+++ b/sql/ha_ndbcluster_cond.cc	2008-03-18 13:24:56 +01:00
@@ -151,7 +151,7 @@ void ndb_serialize_cond(const Item *item
     }
     else
     {
-      Ndb_cond_stack *ndb_stack= context->stack_ptr;
+      Ndb_cond_stack *ndb_stack= context->cond_stack;
       Ndb_cond *prev_cond= context->cond_ptr;
       Ndb_cond *curr_cond= context->cond_ptr= new Ndb_cond();
       if (!ndb_stack->ndb_cond)
@@ -247,6 +247,8 @@ void ndb_serialize_cond(const Item *item
       }
       else
       {
+        bool pop= TRUE;
+
         switch (item->type()) {
         case Item::FIELD_ITEM:
         {
@@ -484,16 +486,27 @@ void ndb_serialize_cond(const Item *item
           }
           case Item_func::LIKE_FUNC:
           {
+            Ndb_expect_stack* expect_next= new Ndb_expect_stack();
             DBUG_PRINT("info", ("LIKE_FUNC"));      
             curr_cond->ndb_item= new Ndb_item(func_item->functype(),
                                               func_item);      
-            context->expect(Item::STRING_ITEM);
+
+            /*
+              Ndb currently only supports pushing
+              <field> LIKE <string> | <func>
+              we thus push <string> | <func>
+              on the expect stack to catch that we
+              don't support <string> LIKE <field>.
+             */
             context->expect(Item::FIELD_ITEM);
             context->expect_only_field_type(MYSQL_TYPE_STRING);
             context->expect_field_type(MYSQL_TYPE_VAR_STRING);
             context->expect_field_type(MYSQL_TYPE_VARCHAR);
             context->expect_field_result(STRING_RESULT);
-            context->expect(Item::FUNC_ITEM);
+            expect_next->expect(Item::STRING_ITEM);
+            expect_next->expect(Item::FUNC_ITEM);
+            context->expect_stack.push(expect_next);
+            pop= FALSE;
             break;
           }
           case Item_func::ISNULL_FUNC:
@@ -883,6 +896,7 @@ void ndb_serialize_cond(const Item *item
           context->supported= FALSE;
         }
         }
+        if (pop) context->expect_stack.pop();
       }
       if (context->supported && context->rewrite_stack)
       {
diff -Nrup a/sql/ha_ndbcluster_cond.h b/sql/ha_ndbcluster_cond.h
--- a/sql/ha_ndbcluster_cond.h	2007-06-19 13:56:00 +02:00
+++ b/sql/ha_ndbcluster_cond.h	2008-03-18 13:24:56 +01:00
@@ -302,52 +302,44 @@ class Ndb_cond_stack : public Sql_alloc
   Ndb_cond_stack *next;
 };
 
-class Ndb_rewrite_context : public Sql_alloc
-{
-public:
-  Ndb_rewrite_context(Item_func *func) 
-    : func_item(func), left_hand_item(NULL), count(0) {};
-  ~Ndb_rewrite_context()
-  {
-    if (next) delete next;
-  }
-  const Item_func *func_item;
-  const Item *left_hand_item;
-  uint count;
-  Ndb_rewrite_context *next;
-};
-
-/*
-  This class is used for storing the context when traversing
-  the Item tree. It stores a reference to the table the condition
-  is defined on, the serialized representation being generated, 
-  if the condition found is supported, and information what is
-  expected next in the tree inorder for the condition to be supported.
-*/
-class Ndb_cond_traverse_context : public Sql_alloc
+class Ndb_expect_stack : public Sql_alloc
 {
  public:
-   Ndb_cond_traverse_context(TABLE *tab, const NdbDictionary::Table *ndb_tab,
-			     Ndb_cond_stack* stack)
-    : table(tab), ndb_table(ndb_tab), 
-    supported(TRUE), stack_ptr(stack), cond_ptr(NULL),
-    skip(0), collation(NULL), rewrite_stack(NULL)
+  Ndb_expect_stack(): collation(NULL), next(NULL) 
   {
     // Allocate type checking bitmaps   
     bitmap_init(&expect_mask, 0, 512, FALSE);
     bitmap_init(&expect_field_type_mask, 0, 512, FALSE);
     bitmap_init(&expect_field_result_mask, 0, 512, FALSE);
-
-    if (stack)
-      cond_ptr= stack->ndb_cond;
   };
-  ~Ndb_cond_traverse_context()
+  ~Ndb_expect_stack()
   {
     bitmap_free(&expect_mask);
     bitmap_free(&expect_field_type_mask);
     bitmap_free(&expect_field_result_mask);
-    if (rewrite_stack) delete rewrite_stack;
+    if (next) delete next;
+    next= NULL;
   }
+  void push(Ndb_expect_stack* expect_next)
+  {
+    next= expect_next;
+  };
+  void pop()
+  {
+    if (next)
+    {
+      Ndb_expect_stack* expect_next= next;
+      bitmap_clear_all(&expect_mask);
+      bitmap_union(&expect_mask, &next->expect_mask);
+      bitmap_clear_all(&expect_field_type_mask);
+      bitmap_union(&expect_field_type_mask, &next->expect_field_type_mask);
+      bitmap_clear_all(&expect_field_result_mask);
+      bitmap_union(&expect_field_result_mask, &next->expect_field_result_mask);
+      collation= next->collation;
+      next= next->next;
+      delete expect_next;
+    }
+  };
   void expect(Item::Type type)
   {
     bitmap_set_bit(&expect_mask, (uint) type);
@@ -407,7 +399,8 @@ class Ndb_cond_traverse_context : public
   };
   bool expecting_field_result(Item_result result)
   {
-    return bitmap_is_set(&expect_field_result_mask, (uint) result);
+    return bitmap_is_set(&expect_field_result_mask,
+                         (uint) result);
   };
   void expect_no_field_result()
   {
@@ -428,22 +421,146 @@ class Ndb_cond_traverse_context : public
   };
   bool expecting_collation(CHARSET_INFO* col)
   {
-    bool matching= (!collation) ? true : (collation == col);
+    bool matching= (!collation)
+      ? true
+      : (collation == col);
     collation= NULL;
 
     return matching;
   };
 
+private:
+  MY_BITMAP expect_mask;
+  MY_BITMAP expect_field_type_mask;
+  MY_BITMAP expect_field_result_mask;
+  CHARSET_INFO* collation;
+  Ndb_expect_stack* next;
+};
+
+class Ndb_rewrite_context : public Sql_alloc
+{
+public:
+  Ndb_rewrite_context(Item_func *func) 
+    : func_item(func), left_hand_item(NULL), count(0) {};
+  ~Ndb_rewrite_context()
+  {
+    if (next) delete next;
+  }
+  const Item_func *func_item;
+  const Item *left_hand_item;
+  uint count;
+  Ndb_rewrite_context *next;
+};
+
+/*
+  This class is used for storing the context when traversing
+  the Item tree. It stores a reference to the table the condition
+  is defined on, the serialized representation being generated, 
+  if the condition found is supported, and information what is
+  expected next in the tree inorder for the condition to be supported.
+*/
+class Ndb_cond_traverse_context : public Sql_alloc
+{
+ public:
+   Ndb_cond_traverse_context(TABLE *tab, const NdbDictionary::Table *ndb_tab,
+			     Ndb_cond_stack* stack)
+    : table(tab), ndb_table(ndb_tab), 
+    supported(TRUE), cond_stack(stack), cond_ptr(NULL),
+    skip(0), rewrite_stack(NULL)
+  {
+    if (stack)
+      cond_ptr= stack->ndb_cond;
+  };
+  ~Ndb_cond_traverse_context()
+  {
+    if (rewrite_stack) delete rewrite_stack;
+  }
+  inline void expect(Item::Type type)
+  {
+    expect_stack.expect(type);
+  };
+  inline void dont_expect(Item::Type type)
+  {
+    expect_stack.dont_expect(type);
+  };
+  inline bool expecting(Item::Type type)
+  {
+    return expect_stack.expecting(type);
+  };
+  inline void expect_nothing()
+  {
+    expect_stack.expect_nothing();
+  };
+  inline bool expecting_nothing()
+  {
+    return expect_stack.expecting_nothing();
+  }
+  inline void expect_only(Item::Type type)
+  {
+    expect_stack.expect_only(type);
+  };
+
+  inline void expect_field_type(enum_field_types type)
+  {
+    expect_stack.expect_field_type(type);
+  };
+  inline void expect_all_field_types()
+  {
+    expect_stack.expect_all_field_types();
+  };
+  inline bool expecting_field_type(enum_field_types type)
+  {
+    return expect_stack.expecting_field_type(type);
+  };
+  inline void expect_no_field_type()
+  {
+    expect_stack.expect_no_field_type();
+  };
+  inline bool expecting_no_field_type()
+  {
+    return expect_stack.expecting_no_field_type();
+  };
+  inline void expect_only_field_type(enum_field_types result)
+  {
+    expect_stack.expect_only_field_type(result);
+  };
+
+  inline void expect_field_result(Item_result result)
+  {
+    expect_stack.expect_field_result(result);
+  };
+  inline bool expecting_field_result(Item_result result)
+  {
+    return expect_stack.expecting_field_result(result);
+  };
+  inline void expect_no_field_result()
+  {
+    expect_stack.expect_no_field_result();
+  };
+  inline bool expecting_no_field_result()
+  {
+    return expect_stack.expecting_no_field_result();
+  };
+  inline void expect_only_field_result(Item_result result)
+  {
+    expect_stack.expect_only_field_result(result);
+  };
+  inline void expect_collation(CHARSET_INFO* col)
+  {
+    expect_stack.expect_collation(col);
+  };
+  inline bool expecting_collation(CHARSET_INFO* col)
+  {
+    return expect_stack.expecting_collation(col);
+  };
+
   TABLE* table;
   const NdbDictionary::Table *ndb_table;
   bool supported;
-  Ndb_cond_stack* stack_ptr;
+  Ndb_cond_stack* cond_stack;
   Ndb_cond* cond_ptr;
-  MY_BITMAP expect_mask;
-  MY_BITMAP expect_field_type_mask;
-  MY_BITMAP expect_field_result_mask;
+  Ndb_expect_stack expect_stack;
   uint skip;
-  CHARSET_INFO* collation;
   Ndb_rewrite_context *rewrite_stack;
 };
 
Thread
bk commit into 5.0 tree (mskold:1.2572) BUG#35185Martin Skold18 Mar