Below is the list of changes that have just been committed into a local
5.0 repository of marty. When marty 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
1.1953 05/05/18 14:32:05 mskold@stripped +4 -0
Added support for BETWEEN and IN in condition pushdown to ndbcluster by rewriting them as AND and OR expressions
sql/ha_ndbcluster.h
1.83 05/05/18 14:31:45 mskold@stripped +33 -3
Added support for BETWEEN and IN in condition pushdown to ndbcluster by rewriting them as AND and OR expressions
sql/ha_ndbcluster.cc
1.188 05/05/18 14:31:45 mskold@stripped +728 -510
Added support for BETWEEN and IN in condition pushdown to ndbcluster by rewriting them as AND and OR expressions
mysql-test/t/ndb_condition_pushdown.test
1.13 05/05/18 14:31:45 mskold@stripped +296 -0
Added support for BETWEEN and IN in condition pushdown to ndbcluster by rewriting them as AND and OR expressions
mysql-test/r/ndb_condition_pushdown.result
1.12 05/05/18 14:31:45 mskold@stripped +309 -1
Added support for BETWEEN and IN in condition pushdown to ndbcluster by rewriting them as AND and OR expressions
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: mskold
# Host: blowfish.ndb.mysql.com
# Root: /usr/local/home/marty/MySQL/mysql-5.0
--- 1.187/sql/ha_ndbcluster.cc Sun May 8 22:41:59 2005
+++ 1.188/sql/ha_ndbcluster.cc Wed May 18 14:31:45 2005
@@ -6184,572 +6184,784 @@
context->supported= FALSE;
break;
}
-
+
DBUG_VOID_RETURN;
}
if (context->supported)
{
- Ndb_cond_stack *ndb_stack= context->stack_ptr;
- Ndb_cond *prev_cond= context->cond_ptr;
- Ndb_cond *curr_cond= context->cond_ptr= new Ndb_cond();
- if (!ndb_stack->ndb_cond)
- ndb_stack->ndb_cond= curr_cond;
- curr_cond->prev= prev_cond;
- if (prev_cond) prev_cond->next= curr_cond;
-
- // Check for end of AND/OR expression
- if (!item)
+ Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
+ const Item_func *func_item;
+ // Check if we are rewriting some unsupported function call
+ if (rewrite_context &&
+ (func_item= rewrite_context->func_item) &&
+ rewrite_context->count++ == 0)
{
- // End marker for condition group
- DBUG_PRINT("info", ("End of condition group"));
- curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
- }
- else
- switch(item->type()) {
- case(Item::FIELD_ITEM): {
- Item_field *field_item= (Item_field *) item;
- Field *field= field_item->field;
- enum_field_types type= field->type();
+ switch(func_item->functype()) {
+ case(Item_func::BETWEEN):
/*
- Check that the field is part of the table of the handler
- instance and that we expect a field with of this result type.
+ Rewrite
+ <field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
+ to <field>|<const> > <const1>|<field1> AND
+ <field>|<const> < <const2>|<field2>
+ or actually in prefix format
+ BEGIN(AND) GT(<field>|<const>, <const1>|<field1>),
+ LT(<field>|<const>, <const2>|<field2>), END()
*/
- if (context->table == field->table)
- {
- const NDBTAB *tab= (const NDBTAB *) context->ndb_table;
- DBUG_PRINT("info", ("FIELD_ITEM"));
- DBUG_PRINT("info", ("table %s", tab->getName()));
- DBUG_PRINT("info", ("column %s", field->field_name));
- DBUG_PRINT("info", ("result type %d", field->result_type()));
-
- // Check that we are expecting a field and with the correct
- // result type
- if(context->expecting(Item::FIELD_ITEM) &&
- (context->expecting_field_result(field->result_type()) ||
- // Date and year can be written as strings
- (type == MYSQL_TYPE_TIME ||
- type == MYSQL_TYPE_DATE ||
- type == MYSQL_TYPE_YEAR ||
- type == MYSQL_TYPE_DATETIME)
- ? context->expecting_field_result(STRING_RESULT) : true)
- // Bit fields no yet supported in scan filter
- && type != MYSQL_TYPE_BIT)
- {
- const NDBCOL *col= tab->getColumn(field->field_name);
- DBUG_ASSERT(col);
- curr_cond->ndb_item= new Ndb_item(field, col->getColumnNo());
- context->dont_expect(Item::FIELD_ITEM);
- context->expect_no_field_result();
- if (context->expect_mask)
- {
- // We have not seen second argument yet
- if (type == MYSQL_TYPE_TIME ||
- type == MYSQL_TYPE_DATE ||
- type == MYSQL_TYPE_YEAR ||
- type == MYSQL_TYPE_DATETIME)
- {
- context->expect_only(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- }
- else
- switch(field->result_type()) {
- case(STRING_RESULT):
- // Expect char string or binary string
- context->expect_only(Item::STRING_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect_collation(field_item->collation.collation);
- break;
- case(REAL_RESULT):
- context->expect_only(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- break;
- case(INT_RESULT):
- context->expect_only(Item::INT_ITEM);
- context->expect(Item::VARBIN_ITEM);
- break;
- case(DECIMAL_RESULT):
- context->expect_only(Item::DECIMAL_ITEM);
- context->expect(Item::REAL_ITEM);
- break;
- default:
- break;
- }
+ case(Item_func::IN_FUNC): {
+ /*
+ Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
+ to <field>|<const> = <const1>|<field1> OR
+ <field> = <const2>|<field2> ...
+ or actually in prefix format
+ BEGIN(OR) EQ(<field>|<const>, <const1><field1>),
+ EQ(<field>|<const>, <const2>|<field2>), ... END()
+ Each part of the disjunction is added for each call
+ to ndb_serialize_cond and end of rewrite statement
+ is wrapped in end of ndb_serialize_cond
+ */
+ if (context->expecting(item->type()))
+ {
+ // This is the <field>|<const> item, save it in the rewrite context
+ rewrite_context->left_hand_item= item;
+ if (item->type() == Item::FUNC_ITEM)
+ {
+ Item_func *func_item= (Item_func *) item;
+ if (func_item->functype() == Item_func::UNKNOWN_FUNC &&
+ func_item->const_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();
}
else
{
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
- // Check that field and string constant collations are the same
- if ((field->result_type() == STRING_RESULT) &&
- !context->expecting_collation(item->collation.collation))
- {
- DBUG_PRINT("info", ("Found non-matching collation %s",
- item->collation.collation->name));
- context->supported= FALSE;
- }
+ DBUG_PRINT("info", ("Found unsupported functional expression in BETWEEN|IN"));
+ context->supported= FALSE;
+ DBUG_VOID_RETURN;
+
}
- break;
}
}
- DBUG_PRINT("info", ("Was not expecting field of type %u",
- field->result_type()));
- context->supported= FALSE;
- break;
- }
- case(Item::FUNC_ITEM): {
- Item_func *func_item= (Item_func *) item;
- // Check that we expect a function or functional expression here
- if (context->expecting(Item::FUNC_ITEM) ||
- func_item->functype() == Item_func::UNKNOWN_FUNC)
- context->expect_nothing();
else
{
- // Did not expect function here
+ // Non-supported BETWEEN|IN expression
+ DBUG_PRINT("info", ("Found unexpected item of type %u in BETWEEN|IN",
+ item->type()));
context->supported= FALSE;
- break;
+ DBUG_VOID_RETURN;
}
-
+ break;
+ }
+ default:
+ context->supported= FALSE;
+ break;
+ }
+ DBUG_VOID_RETURN;
+ }
+ else
+ {
+ Ndb_cond_stack *ndb_stack= context->stack_ptr;
+ Ndb_cond *prev_cond= context->cond_ptr;
+ Ndb_cond *curr_cond= context->cond_ptr= new Ndb_cond();
+ if (!ndb_stack->ndb_cond)
+ ndb_stack->ndb_cond= curr_cond;
+ curr_cond->prev= prev_cond;
+ if (prev_cond) prev_cond->next= curr_cond;
+ // Check if we are rewriting some unsupported function call
+ if (context->rewrite_stack)
+ {
+ Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
+ const Item_func *func_item= rewrite_context->func_item;
switch(func_item->functype()) {
- case(Item_func::EQ_FUNC): {
+ case(Item_func::BETWEEN): {
+ /*
+ Rewrite
+ <field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
+ to <field>|<const> > <const1>|<field1> AND
+ <field>|<const> < <const2>|<field2>
+ or actually in prefix format
+ BEGIN(AND) GT(<field>|<const>, <const1>|<field1>),
+ LT(<field>|<const>, <const2>|<field2>), END()
+ */
+ if (rewrite_context->count == 2)
+ {
+ // Lower limit of BETWEEN
+ DBUG_PRINT("info", ("GE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(Item_func::GE_FUNC, 2);
+ }
+ else if (rewrite_context->count == 3)
+ {
+ // Upper limit of BETWEEN
+ DBUG_PRINT("info", ("LE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(Item_func::LE_FUNC, 2);
+ }
+ else
+ {
+ // Illegal BETWEEN expression
+ DBUG_PRINT("info", ("Illegal BETWEEN expression"));
+ context->supported= FALSE;
+ DBUG_VOID_RETURN;
+ }
+ break;
+ }
+ case(Item_func::IN_FUNC): {
+ /*
+ Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
+ to <field>|<const> = <const1>|<field1> OR
+ <field> = <const2>|<field2> ...
+ or actually in prefix format
+ BEGIN(OR) EQ(<field>|<const>, <const1><field1>),
+ EQ(<field>|<const>, <const2>|<field2>), ... END()
+ Each part of the disjunction is added for each call
+ to ndb_serialize_cond and end of rewrite statement
+ is wrapped in end of ndb_serialize_cond
+ */
DBUG_PRINT("info", ("EQ_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::NE_FUNC): {
- DBUG_PRINT("info", ("NE_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::LT_FUNC): {
- DBUG_PRINT("info", ("LT_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::LE_FUNC): {
- DBUG_PRINT("info", ("LE_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::GE_FUNC): {
- DBUG_PRINT("info", ("GE_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::GT_FUNC): {
- DBUG_PRINT("info", ("GT_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::LIKE_FUNC): {
- DBUG_PRINT("info", ("LIKE_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- break;
- }
- case(Item_func::NOTLIKE_FUNC): {
- DBUG_PRINT("info", ("NOTLIKE_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- break;
- }
- case(Item_func::ISNULL_FUNC): {
- DBUG_PRINT("info", ("ISNULL_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::ISNOTNULL_FUNC): {
- DBUG_PRINT("info", ("ISNOTNULL_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::NOT_FUNC): {
- DBUG_PRINT("info", ("NOT_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
- break;
- }
- case(Item_func::UNKNOWN_FUNC): {
- DBUG_PRINT("info", ("UNKNOWN_FUNC %s",
- func_item->const_item()?"const":""));
- 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->expect_field_result_mask)
+ curr_cond->ndb_item= new Ndb_item(Item_func::EQ_FUNC, 2);
+ break;
+ }
+ default:
+ context->supported= FALSE;
+ }
+ // Handle left hand <field>|<const>
+ context->rewrite_stack= NULL; // Disable rewrite mode
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FUNC_ITEM);
+ ndb_serialize_cond(rewrite_context->left_hand_item, arg);
+ context->skip= 0; // Any FUNC_ITEM expression has already been parsed
+ context->rewrite_stack= rewrite_context; // Enable rewrite mode
+ if (!context->supported)
+ DBUG_VOID_RETURN;
+
+ prev_cond= context->cond_ptr;
+ curr_cond= context->cond_ptr= new Ndb_cond();
+ prev_cond->next= curr_cond;
+ }
+
+ // Check for end of AND/OR expression
+ if (!item)
+ {
+ // End marker for condition group
+ DBUG_PRINT("info", ("End of condition group"));
+ curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
+ }
+ else
+ switch(item->type()) {
+ case(Item::FIELD_ITEM): {
+ Item_field *field_item= (Item_field *) item;
+ Field *field= field_item->field;
+ enum_field_types type= field->type();
+ /*
+ Check that the field is part of the table of the handler
+ instance and that we expect a field with of this result type.
+ */
+ if (context->table == field->table)
+ {
+ const NDBTAB *tab= (const NDBTAB *) context->ndb_table;
+ DBUG_PRINT("info", ("FIELD_ITEM"));
+ DBUG_PRINT("info", ("table %s", tab->getName()));
+ DBUG_PRINT("info", ("column %s", field->field_name));
+ DBUG_PRINT("info", ("result type %d", field->result_type()));
+
+ // Check that we are expecting a field and with the correct
+ // result type
+ if (context->expecting(Item::FIELD_ITEM) &&
+ (context->expecting_field_result(field->result_type()) ||
+ // Date and year can be written as strings
+ ((type == MYSQL_TYPE_TIME ||
+ type == MYSQL_TYPE_DATE ||
+ type == MYSQL_TYPE_YEAR ||
+ type == MYSQL_TYPE_DATETIME)
+ ? context->expecting_field_result(STRING_RESULT) : true)) &&
+ // Bit fields no yet supported in scan filter
+ type != MYSQL_TYPE_BIT)
+ {
+ const NDBCOL *col= tab->getColumn(field->field_name);
+ DBUG_ASSERT(col);
+ curr_cond->ndb_item= new Ndb_item(field, col->getColumnNo());
+ context->dont_expect(Item::FIELD_ITEM);
+ context->expect_no_field_result();
+ if (context->expect_mask)
{
- // 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);
+ // We have not seen second argument yet
+ if (type == MYSQL_TYPE_TIME ||
+ type == MYSQL_TYPE_DATE ||
+ type == MYSQL_TYPE_YEAR ||
+ type == MYSQL_TYPE_DATETIME)
+ {
+ context->expect_only(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ }
+ else
+ switch(field->result_type()) {
+ case(STRING_RESULT):
+ // Expect char string or binary string
+ context->expect_only(Item::STRING_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect_collation(field_item->collation.collation);
+ break;
+ case(REAL_RESULT):
+ context->expect_only(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ break;
+ case(INT_RESULT):
+ context->expect_only(Item::INT_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ break;
+ case(DECIMAL_RESULT):
+ context->expect_only(Item::DECIMAL_ITEM);
+ context->expect(Item::REAL_ITEM);
+ break;
+ default:
+ break;
+ }
}
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))
+ // Check that field and string constant collations are the same
+ if ((field->result_type() == STRING_RESULT) &&
+ !context->expecting_collation(item->collation.collation)
+ && type != MYSQL_TYPE_TIME
+ && type != MYSQL_TYPE_DATE
+ && type != MYSQL_TYPE_YEAR
+ && type != MYSQL_TYPE_DATETIME)
{
DBUG_PRINT("info", ("Found non-matching collation %s",
- item->collation.collation->name));
- context->supported= FALSE;
+ 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->expect_field_result_mask)
- {
- // 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->expect_field_result_mask)
- {
- // 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->expect_field_result_mask)
- {
- // 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;
+ else
+ {
+ DBUG_PRINT("info", ("Was not expecting field of type %u",
+ field->result_type()));
+ context->supported= FALSE;
}
+ }
else
- // Function does not return constant expression
+ {
+ DBUG_PRINT("info", ("Was not expecting field from table %s(%s)",
+ context->table->s->table_name,
+ field->table->s->table_name));
context->supported= FALSE;
+ }
break;
}
- default: {
- DBUG_PRINT("info", ("Found func_item of type %d",
- func_item->functype()));
- context->supported= FALSE;
- }
- }
- break;
- }
- case(Item::STRING_ITEM):
- DBUG_PRINT("info", ("STRING_ITEM"));
- if (context->expecting(Item::STRING_ITEM))
- {
-#ifndef DBUG_OFF
- char buff[256];
- String str(buff,(uint32) sizeof(buff), system_charset_info);
- str.length(0);
- Item_string *string_item= (Item_string *) item;
- DBUG_PRINT("info", ("value \"%s\"",
- string_item->val_str(&str)->ptr()));
-#endif
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::STRING_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
+ case(Item::FUNC_ITEM): {
+ Item_func *func_item= (Item_func *) item;
+ // Check that we expect a function or functional expression here
+ if (context->expecting(Item::FUNC_ITEM) ||
+ func_item->functype() == Item_func::UNKNOWN_FUNC)
+ context->expect_nothing();
+ else
{
- // 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);
+ // Did not expect function here
+ context->supported= FALSE;
+ break;
}
- else
- {
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
- // Check that we are comparing with a field with same collation
- if (!context->expecting_collation(item->collation.collation))
- {
- DBUG_PRINT("info", ("Found non-matching collation %s",
- item->collation.collation->name));
- context->supported= FALSE;
- }
+
+ switch(func_item->functype()) {
+ case(Item_func::EQ_FUNC): {
+ DBUG_PRINT("info", ("EQ_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ context->expect(Item::FUNC_ITEM);
+ break;
}
- }
- else
- context->supported= FALSE;
- break;
- case(Item::INT_ITEM):
- DBUG_PRINT("info", ("INT_ITEM"));
- if (context->expecting(Item::INT_ITEM))
- {
- Item_int *int_item= (Item_int *) item;
- DBUG_PRINT("info", ("value %d", int_item->value));
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::INT_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
- {
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(INT_RESULT);
+ case(Item_func::NE_FUNC): {
+ DBUG_PRINT("info", ("NE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ context->expect(Item::FUNC_ITEM);
+ break;
}
- else
- {
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
+ case(Item_func::LT_FUNC): {
+ DBUG_PRINT("info", ("LT_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ context->expect(Item::FUNC_ITEM);
+ break;
+ }
+ case(Item_func::LE_FUNC): {
+ DBUG_PRINT("info", ("LE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ context->expect(Item::FUNC_ITEM);
+ break;
+ }
+ case(Item_func::GE_FUNC): {
+ DBUG_PRINT("info", ("GE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ context->expect(Item::FUNC_ITEM);
+ break;
+ }
+ case(Item_func::GT_FUNC): {
+ DBUG_PRINT("info", ("GT_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ context->expect(Item::FUNC_ITEM);
+ break;
+ }
+ case(Item_func::LIKE_FUNC): {
+ DBUG_PRINT("info", ("LIKE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect(Item::FUNC_ITEM);
+ break;
+ }
+ case(Item_func::NOTLIKE_FUNC): {
+ DBUG_PRINT("info", ("NOTLIKE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect(Item::FUNC_ITEM);
+ break;
+ }
+ case(Item_func::ISNULL_FUNC): {
+ DBUG_PRINT("info", ("ISNULL_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ break;
+ }
+ case(Item_func::ISNOTNULL_FUNC): {
+ DBUG_PRINT("info", ("ISNOTNULL_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ break;
+ }
+ case(Item_func::NOT_FUNC): {
+ DBUG_PRINT("info", ("NOT_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::FUNC_ITEM);
context->expect(Item::COND_ITEM);
+ break;
}
- }
- else
- context->supported= FALSE;
- break;
- case(Item::REAL_ITEM):
- DBUG_PRINT("info", ("REAL_ITEM %s"));
- if (context->expecting(Item::REAL_ITEM))
- {
- Item_float *float_item= (Item_float *) item;
- DBUG_PRINT("info", ("value %f", float_item->value));
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::REAL_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
- {
- // We have not seen the field argument yet
+ case(Item_func::BETWEEN) : {
+ DBUG_PRINT("info", ("BETWEEN, rewriting using AND"));
+ Ndb_rewrite_context *rewrite_context=
+ new Ndb_rewrite_context(func_item);
+ rewrite_context->next= context->rewrite_stack;
+ context->rewrite_stack= rewrite_context;
+ DBUG_PRINT("info", ("COND_AND_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(Item_func::COND_AND_FUNC,
+ func_item->argument_count() - 1);
context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(REAL_RESULT);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FUNC_ITEM);
+ break;
+ }
+ case(Item_func::IN_FUNC) : {
+ DBUG_PRINT("info", ("IN_FUNC, rewriting using OR"));
+ Ndb_rewrite_context *rewrite_context=
+ new Ndb_rewrite_context(func_item);
+ rewrite_context->next= context->rewrite_stack;
+ context->rewrite_stack= rewrite_context;
+ DBUG_PRINT("info", ("COND_OR_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(Item_func::COND_OR_FUNC,
+ func_item->argument_count() - 1);
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FUNC_ITEM);
+ break;
+ }
+ case(Item_func::UNKNOWN_FUNC): {
+ DBUG_PRINT("info", ("UNKNOWN_FUNC %s",
+ func_item->const_item()?"const":""));
+ 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->expect_field_result_mask)
+ {
+ // 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->expect_field_result_mask)
+ {
+ // 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->expect_field_result_mask)
+ {
+ // 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->expect_field_result_mask)
+ {
+ // 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;
+ }
+ else
+ // Function does not return constant expression
+ context->supported= FALSE;
+ break;
+ }
+ default: {
+ DBUG_PRINT("info", ("Found func_item of type %d",
+ func_item->functype()));
+ context->supported= FALSE;
}
- else
- {
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
}
+ break;
}
- else
- context->supported= FALSE;
- break;
- case(Item::VARBIN_ITEM):
- DBUG_PRINT("info", ("VARBIN_ITEM"));
- if (context->expecting(Item::VARBIN_ITEM))
- {
+ case(Item::STRING_ITEM):
+ DBUG_PRINT("info", ("STRING_ITEM"));
+ if (context->expecting(Item::STRING_ITEM))
+ {
#ifndef DBUG_OFF
- char buff[256];
- String str(buff,(uint32) sizeof(buff), system_charset_info);
- str.length(0);
- Item_hex_string *varbin_item= (Item_hex_string *) item;
- DBUG_PRINT("info", ("value \"%s\"",
- varbin_item->val_str(&str)->ptr()));
+ char buff[256];
+ String str(buff,(uint32) sizeof(buff), system_charset_info);
+ str.length(0);
+ Item_string *string_item= (Item_string *) item;
+ DBUG_PRINT("info", ("value \"%s\"",
+ string_item->val_str(&str)->ptr()));
#endif
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::VARBIN_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::STRING_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // 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 we are comparing with a field with same collation
+ if (!context->expecting_collation(item->collation.collation))
+ {
+ DBUG_PRINT("info", ("Found non-matching collation %s",
+ item->collation.collation->name));
+ context->supported= FALSE;
+ }
+ }
+ }
+ else
+ context->supported= FALSE;
+ break;
+ case(Item::INT_ITEM):
+ DBUG_PRINT("info", ("INT_ITEM"));
+ if (context->expecting(Item::INT_ITEM))
{
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(STRING_RESULT);
+ Item_int *int_item= (Item_int *) item;
+ DBUG_PRINT("info", ("value %d", int_item->value));
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::INT_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // 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);
+ }
}
else
+ context->supported= FALSE;
+ break;
+ case(Item::REAL_ITEM):
+ DBUG_PRINT("info", ("REAL_ITEM %s"));
+ if (context->expecting(Item::REAL_ITEM))
{
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
+ Item_float *float_item= (Item_float *) item;
+ DBUG_PRINT("info", ("value %f", float_item->value));
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::REAL_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // 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);
+ }
}
- }
- else
- context->supported= FALSE;
- break;
- case(Item::DECIMAL_ITEM):
- DBUG_PRINT("info", ("DECIMAL_ITEM %s"));
- if (context->expecting(Item::DECIMAL_ITEM))
- {
- Item_decimal *decimal_item= (Item_decimal *) item;
- DBUG_PRINT("info", ("value %f", decimal_item->val_real()));
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::DECIMAL_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
+ else
+ context->supported= FALSE;
+ break;
+ case(Item::VARBIN_ITEM):
+ DBUG_PRINT("info", ("VARBIN_ITEM"));
+ if (context->expecting(Item::VARBIN_ITEM))
{
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(REAL_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::VARBIN_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(STRING_RESULT);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ }
}
else
+ context->supported= FALSE;
+ break;
+ case(Item::DECIMAL_ITEM):
+ DBUG_PRINT("info", ("DECIMAL_ITEM %s"));
+ if (context->expecting(Item::DECIMAL_ITEM))
{
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
+ Item_decimal *decimal_item= (Item_decimal *) item;
+ DBUG_PRINT("info", ("value %f", decimal_item->val_real()));
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::DECIMAL_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(REAL_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ }
}
+ else
+ context->supported= FALSE;
+ break;
+ case(Item::COND_ITEM): {
+ Item_cond *cond_item= (Item_cond *) item;
+
+ if (context->expecting(Item::COND_ITEM))
+ switch(cond_item->functype()) {
+ case(Item_func::COND_AND_FUNC):
+ DBUG_PRINT("info", ("COND_AND_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
+ cond_item);
+ break;
+ case(Item_func::COND_OR_FUNC):
+ DBUG_PRINT("info", ("COND_OR_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
+ cond_item);
+ break;
+ default:
+ DBUG_PRINT("info", ("COND_ITEM %d", cond_item->functype()));
+ context->supported= FALSE;
+ break;
+ }
+ else
+ // Did not expect condition
+ context->supported= FALSE;
+ break;
}
- else
+ default: {
+ DBUG_PRINT("info", ("Found item of type %d", item->type()));
context->supported= FALSE;
- break;
- case(Item::COND_ITEM): {
- Item_cond *cond_item= (Item_cond *) item;
-
- if (context->expecting(Item::COND_ITEM))
- switch(cond_item->functype()) {
- case(Item_func::COND_AND_FUNC):
- DBUG_PRINT("info", ("COND_AND_FUNC"));
- curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
- cond_item);
- break;
- case(Item_func::COND_OR_FUNC):
- DBUG_PRINT("info", ("COND_OR_FUNC"));
- curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
- cond_item);
- break;
- default:
- DBUG_PRINT("info", ("COND_ITEM %d", cond_item->functype()));
- context->supported= FALSE;
- break;
- }
- else
- // Did not expect condition
- context->supported= FALSE;
- break;
- }
- default: {
- DBUG_PRINT("info", ("Found item of type %d", item->type()));
- context->supported= FALSE;
- }
+ }
+ }
+
+ if (context->supported && context->rewrite_stack)
+ {
+ Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
+ if (rewrite_context->count ==
+ rewrite_context->func_item->argument_count())
+ {
+ // Rewrite is done, wrap an END() at the en
+ DBUG_PRINT("info", ("End of condition group"));
+ prev_cond= curr_cond;
+ curr_cond= context->cond_ptr= new Ndb_cond();
+ prev_cond->next= curr_cond;
+ curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
+ // Pop rewrite stack
+ context->rewrite_stack= context->rewrite_stack->next;
+ }
}
+ }
}
-
+
DBUG_VOID_RETURN;
}
@@ -7065,14 +7277,20 @@
bool simple_cond= TRUE;
DBUG_ENTER("build_scan_filter");
- switch(cond->ndb_item->type) {
- case(Item_func::COND_AND_FUNC):
- case(Item_func::COND_OR_FUNC):
- simple_cond= FALSE;
- break;
- default:
- break;
- }
+ switch(cond->ndb_item->type) {
+ case(NDB_FUNCTION):
+ switch(cond->ndb_item->qualification.function_type) {
+ case(Item_func::COND_AND_FUNC):
+ case(Item_func::COND_OR_FUNC):
+ simple_cond= FALSE;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
if (simple_cond && filter->begin() == -1)
DBUG_RETURN(1);
if (build_scan_filter_group(cond, filter))
--- 1.82/sql/ha_ndbcluster.h Thu Apr 28 10:28:51 2005
+++ 1.83/sql/ha_ndbcluster.h Wed May 18 14:31:45 2005
@@ -86,6 +86,7 @@
typedef union ndb_item_value {
const Item *item;
NDB_ITEM_FIELD_VALUE *field_value;
+ uint arg_count;
} NDB_ITEM_VALUE;
struct negated_function_mapping
@@ -144,6 +145,7 @@
}
case(NDB_FUNCTION):
value.item= item_value;
+ value.arg_count= ((Item_func *) item_value)->argument_count();
break;
case(NDB_END_COND):
break;
@@ -162,6 +164,13 @@
{
qualification.function_type= func_type;
value.item= item_value;
+ value.arg_count= ((Item_func *) item_value)->argument_count();
+ };
+ Ndb_item(Item_func::Functype func_type, uint no_args)
+ : type(NDB_FUNCTION)
+ {
+ qualification.function_type= func_type;
+ value.arg_count= no_args;
};
~Ndb_item()
{
@@ -194,7 +203,7 @@
int argument_count()
{
- return ((Item_func *) value.item)->argument_count();
+ return value.arg_count;
};
const char* get_val()
@@ -273,12 +282,28 @@
{
if (ndb_cond) delete ndb_cond;
ndb_cond= NULL;
+ if (next) delete next;
next= NULL;
};
Ndb_cond *ndb_cond;
Ndb_cond_stack *next;
};
+class Ndb_rewrite_context
+{
+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
@@ -292,11 +317,16 @@
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), collation(NULL)
+ expect_mask(0), expect_field_result_mask(0), skip(0), collation(NULL),
+ rewrite_stack(NULL)
{
if (stack)
cond_ptr= stack->ndb_cond;
};
+ ~Ndb_cond_traverse_context()
+ {
+ if (rewrite_stack) delete rewrite_stack;
+ }
void expect(Item::Type type)
{
expect_mask|= (1 << type);
@@ -357,7 +387,7 @@
uint expect_field_result_mask;
uint skip;
CHARSET_INFO* collation;
-
+ Ndb_rewrite_context *rewrite_stack;
};
/*
--- 1.11/mysql-test/r/ndb_condition_pushdown.result Mon May 9 18:44:22 2005
+++ 1.12/mysql-test/r/ndb_condition_pushdown.result Wed May 18 14:31:45 2005
@@ -251,6 +251,108 @@
1
3
4
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+(bits between b'001' and b'011') and
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+auto
+1
+3
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+(b'001' between bits and bits) and
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+auto
+1
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+bits in(b'001',b'011') and
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+auto
+1
+3
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+/* -1 in(tiny) and */
+/* -1 in (short) and */
+/* -1 in(medium) and */
+/* -1 in(long_int) and */
+/* -1 in(longlong) and */
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+b'001' in(bits) and
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+order by auto;
+auto
+1
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
pk1 attr1 attr2 attr3
2 2 NULL NULL
@@ -1023,6 +1125,212 @@
1
3
4
+explain
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+/* (bits between b'001' and b'011') and */
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range medium_index medium_index 3 NULL 10 Using where with pushed condition; Using filesort
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+/* (bits between b'001' and b'011') and */
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+auto
+1
+3
+explain
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+/* (b'001' between bits and bits) and */
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where with pushed condition; Using filesort
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+/* (b'001' between bits and bits) and */
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+auto
+1
+explain
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+/* bits in(b'001',b'011') and */
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range medium_index medium_index 3 NULL 20 Using where with pushed condition; Using filesort
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+/* bits in(b'001',b'011') and */
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+auto
+1
+3
+explain
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+/* -1 in(tiny) and */
+/* -1 in (short) and */
+/* -1 in(medium) and */
+/* -1 in(long_int) and */
+/* -1 in(longlong) and */
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+/* b'001' in(bits) and */
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where with pushed condition; Using filesort
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+/* -1 in(tiny) and */
+/* -1 in (short) and */
+/* -1 in(medium) and */
+/* -1 in(long_int) and */
+/* -1 in(longlong) and */
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+/* b'001' in(bits) and */
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+order by auto;
+auto
+1
update t1
set medium = 17
where
@@ -1138,7 +1446,7 @@
explain
select * from t2 where (attr1 < 2) = (attr2 < 2) order by pk1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where with pushed condition; Using filesort
explain
select * from t3 left join t4 on t4.attr2 = t3.attr2 where t4.attr1 > 1 and t4.attr3 < 5 or t4.attr1 is null order by t4.pk1;
id select_type table type possible_keys key key_len ref rows Extra
--- 1.12/mysql-test/t/ndb_condition_pushdown.test Mon May 9 18:44:22 2005
+++ 1.13/mysql-test/t/ndb_condition_pushdown.test Wed May 18 14:31:45 2005
@@ -249,6 +249,104 @@
vbin not like concat(0xBB, '%')
order by auto;
+# BETWEEN
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+(bits between b'001' and b'011') and
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+(b'001' between bits and bits) and
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+
+# IN
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+bits in(b'001',b'011') and
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+/* -1 in(tiny) and */
+/* -1 in (short) and */
+/* -1 in(medium) and */
+/* -1 in(long_int) and */
+/* -1 in(longlong) and */
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+b'001' in(bits) and
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+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;
@@ -953,6 +1051,204 @@
vstring not like "b%" and
bin not like concat(0xBB, '%') and
vbin not like concat(0xBB, '%')
+order by auto;
+
+# BETWEEN
+explain
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+/* (bits between b'001' and b'011') and */
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+/* (bits between b'001' and b'011') and */
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+
+explain
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+/* (b'001' between bits and bits) and */
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+/* (b'001' between bits and bits) and */
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+
+# IN
+explain
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+/* bits in(b'001',b'011') and */
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+/* bits in(b'001',b'011') and */
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+
+explain
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+/* -1 in(tiny) and */
+/* -1 in (short) and */
+/* -1 in(medium) and */
+/* -1 in(long_int) and */
+/* -1 in(longlong) and */
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+/* b'001' in(bits) and */
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+order by auto;
+
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+/* -1 in(tiny) and */
+/* -1 in (short) and */
+/* -1 in(medium) and */
+/* -1 in(long_int) and */
+/* -1 in(longlong) and */
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+/* b'001' in(bits) and */
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
order by auto;
# Update test
| Thread |
|---|
| • bk commit into 5.0 tree (mskold:1.1953) | Martin Skold | 18 May |