summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/ndb/t/disabled.def1
-rw-r--r--sql/ha_ndbcluster_cond.cc227
-rw-r--r--sql/item.cc3
-rw-r--r--sql/item.h10
4 files changed, 135 insertions, 106 deletions
diff --git a/mysql-test/suite/ndb/t/disabled.def b/mysql-test/suite/ndb/t/disabled.def
index d38f60d6a54..c3c046e7ece 100644
--- a/mysql-test/suite/ndb/t/disabled.def
+++ b/mysql-test/suite/ndb/t/disabled.def
@@ -11,7 +11,6 @@
##############################################################################
ndb_binlog_discover : Bug#54851 2010-07-02 alik ndb.ndb_binlog_discover crashes the server
-ndb_condition_pushdown : Bug#49746 2010-02-08 alik ndb_condition_pushdown fails in mysql-next-mr
ndb_partition_error2 : Bug#40989 ndb_partition_error2 needs maintenance
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()));
diff --git a/sql/item.cc b/sql/item.cc
index 1decb5ec426..24f57342668 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5931,7 +5931,8 @@ bool Item::cache_const_expr_analyzer(uchar **arg)
a subselect (they use their own cache).
*/
if (const_item() &&
- !(item->basic_const_item() || item->type() == Item::FIELD_ITEM ||
+ !(basic_const_item() || item->basic_const_item() ||
+ item->type() == Item::FIELD_ITEM ||
item->type() == SUBSELECT_ITEM ||
/*
Do not cache GET_USER_VAR() function as its const_item() may
diff --git a/sql/item.h b/sql/item.h
index c7a97ca716a..d1957c46d25 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -3266,6 +3266,12 @@ public:
bool basic_const_item() const
{ return test(example && example->basic_const_item());}
virtual void clear() { null_value= TRUE; value_cached= FALSE; }
+ Item_result result_type() const
+ {
+ if (!example)
+ return INT_RESULT;
+ return Field::result_merge_type(example->field_type());
+ }
};
@@ -3335,7 +3341,9 @@ public:
is_varbinary(item->type() == FIELD_ITEM &&
cached_field_type == MYSQL_TYPE_VARCHAR &&
!((const Item_field *) item)->field->has_charset())
- {}
+ {
+ collation.set(const_cast<DTCollation&>(item->collation));
+ }
double val_real();
longlong val_int();
String* val_str(String *);