diff options
author | Evgeny Potemkin <epotemkin@mysql.com> | 2010-08-14 13:11:33 +0400 |
---|---|---|
committer | Evgeny Potemkin <epotemkin@mysql.com> | 2010-08-14 13:11:33 +0400 |
commit | 827a89996a06255b471ae9f24d3f3d3cbf9f99fd (patch) | |
tree | e62f523aa32ed6704ce025ceef21724a2e6c29a3 /sql/ha_ndbcluster_cond.cc | |
parent | 0058f16d933d6de41e670348080ce625d8109b47 (diff) | |
download | mariadb-git-827a89996a06255b471ae9f24d3f3d3cbf9f99fd.tar.gz |
Bug#49746: Const expression caching led to NDB not using engine condition
pushdown.
NDB supports only a limited set of item nodes for use in engine condition
pushdown. Because of this adding cache for const expression effectively
disabled this optimization.
The ndb_serialize_cond function is extended to support Item_cache and treat
it as a constant values.
A helper function called ndb_serialize_const is added. It is used to create
Ndb_cond value node from given const item.
mysql-test/suite/ndb/t/disabled.def:
Bug#49746: Const expression caching led to NDB not using engine condition
pushdown.
Enabled ndb_condition_pushdown test after fixing appropriate bug.
sql/ha_ndbcluster_cond.cc:
Bug#49746: Const expression caching led to NDB not using engine condition
pushdown.
The ndb_serialize_cond function is extended to support Item_cache and treat
it as a constant values.
A helper function called ndb_serialize_const is added. It is used to create
Ndb_cond value node from given const item.
sql/item.cc:
Bug#49746: Const expression caching led to NDB not using engine condition
pushdown.
The Item::cache_const_expr_analyzer function is adjusted to not create
cache for Item_int_with_ref objects.
sql/item.h:
Bug#49746: Const expression caching led to NDB not using engine condition
pushdown.
The result_type() method is added to Item_cache class.
The Item_cache_str now initializes its collation.
Diffstat (limited to 'sql/ha_ndbcluster_cond.cc')
-rw-r--r-- | sql/ha_ndbcluster_cond.cc | 227 |
1 files changed, 124 insertions, 103 deletions
diff --git a/sql/ha_ndbcluster_cond.cc b/sql/ha_ndbcluster_cond.cc index 6df1f4881c3..8a96ae41453 100644 --- a/sql/ha_ndbcluster_cond.cc +++ b/sql/ha_ndbcluster_cond.cc @@ -35,6 +35,110 @@ typedef NdbDictionary::Column NDBCOL; typedef NdbDictionary::Table NDBTAB; + +/** + Serialize a constant item into a Ndb_cond node. + + @param const_type item's result type + @param item item to be serialized + @param curr_cond Ndb_cond node the item to be serialized into + @param context Traverse context +*/ + +static void ndb_serialize_const(Item_result const_type, const Item *item, + Ndb_cond *curr_cond, + Ndb_cond_traverse_context *context) +{ + DBUG_ASSERT(item->const_item()); + switch (const_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->expecting_no_field_result()) + { + // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); + context->expect_only_field_result(STRING_RESULT); + context->expect_collation(item->collation.collation); + } + else + { + // Expect another logical expression + context->expect_only(Item::FUNC_ITEM); + context->expect(Item::COND_ITEM); + // Check that string result have correct collation + if (!context->expecting_collation(item->collation.collation)) + { + DBUG_PRINT("info", ("Found non-matching collation %s", + item->collation.collation->name)); + context->supported= FALSE; + } + } + 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->expecting_no_field_result()) + { + // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); + context->expect_only_field_result(REAL_RESULT); + } + else + { + // Expect another logical expression + context->expect_only(Item::FUNC_ITEM); + context->expect(Item::COND_ITEM); + } + 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->expecting_no_field_result()) + { + // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); + context->expect_only_field_result(INT_RESULT); + } + else + { + // Expect another logical expression + context->expect_only(Item::FUNC_ITEM); + context->expect(Item::COND_ITEM); + } + break; + } + case DECIMAL_RESULT: + { + NDB_ITEM_QUALIFICATION q; + q.value_type= Item::DECIMAL_ITEM; + curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item); + if (! context->expecting_no_field_result()) + { + // We have not seen the field argument yet + context->expect_only(Item::FIELD_ITEM); + context->expect_only_field_result(DECIMAL_RESULT); + } + else + { + // Expect another logical expression + context->expect_only(Item::FUNC_ITEM); + context->expect(Item::COND_ITEM); + } + break; + } + default: + break; + } +} /* Serialize the item tree into a linked list represented by Ndb_cond for fast generation of NbdScanFilter. Adds information such as @@ -113,7 +217,7 @@ void ndb_serialize_cond(const Item *item, void *arg) to ndb_serialize_cond and end of rewrite statement is wrapped in end of ndb_serialize_cond */ - if (context->expecting(item->type())) + if (context->expecting(item->type()) || item->const_item()) { // This is the <field>|<const> item, save it in the rewrite context rewrite_context2->left_hand_item= item; @@ -597,108 +701,12 @@ void ndb_serialize_cond(const Item *item, void *arg) 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->expecting_no_field_result()) - { - // We have not seen the field argument yet - context->expect_only(Item::FIELD_ITEM); - context->expect_only_field_result(STRING_RESULT); - context->expect_collation(func_item->collation.collation); - } - else - { - // Expect another logical expression - context->expect_only(Item::FUNC_ITEM); - context->expect(Item::COND_ITEM); - // Check that string result have correct collation - if (!context->expecting_collation(item->collation.collation)) - { - DBUG_PRINT("info", ("Found non-matching collation %s", - item->collation.collation->name)); - context->supported= FALSE; - } - } - // 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->expecting_no_field_result()) - { - // We have not seen the field argument yet - context->expect_only(Item::FIELD_ITEM); - context->expect_only_field_result(REAL_RESULT); - } - else - { - // Expect another logical expression - context->expect_only(Item::FUNC_ITEM); - context->expect(Item::COND_ITEM); - } - - // 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->expecting_no_field_result()) - { - // We have not seen the field argument yet - context->expect_only(Item::FIELD_ITEM); - context->expect_only_field_result(INT_RESULT); - } - else - { - // Expect another logical expression - context->expect_only(Item::FUNC_ITEM); - context->expect(Item::COND_ITEM); - } - - // 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 DECIMAL_RESULT: - { - NDB_ITEM_QUALIFICATION q; - q.value_type= Item::DECIMAL_ITEM; - curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item); - if (! context->expecting_no_field_result()) - { - // We have not seen the field argument yet - context->expect_only(Item::FIELD_ITEM); - context->expect_only_field_result(DECIMAL_RESULT); - } - else - { - // Expect another logical expression - context->expect_only(Item::FUNC_ITEM); - context->expect(Item::COND_ITEM); - } - // 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; - } + ndb_serialize_const(func_item->result_type(), item, curr_cond, + context); + + // Skip any arguments since we will evaluate function instead + DBUG_PRINT("info", ("Skip until end of arguments marker")); + context->skip= func_item->argument_count(); } else // Function does not return constant expression @@ -883,6 +891,19 @@ void ndb_serialize_cond(const Item *item, void *arg) } break; } + case Item::CACHE_ITEM: + { + DBUG_PRINT("info", ("CACHE_ITEM")); + if (item->const_item()) + { + ndb_serialize_const(((Item_cache*)item)->result_type(), item, + curr_cond, context); + } + else + context->supported= FALSE; + + break; + } default: { DBUG_PRINT("info", ("Found item of type %d", item->type())); |