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#35185 | Martin Skold | 18 Mar |