Commit 67eebb43 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

IN with row item without constant optimisation (SCRUM)

renamed row item test
parent 6343013a
select row(1,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
row(1,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3))
1
select row(10,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
row(10,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3))
0
SELECT ROW(1,2,3)=ROW(1,2,3);
ROW(1,2,3)=ROW(1,2,3)
1
......@@ -48,6 +54,16 @@ select * from t1 where ROW(1,2,3)<ROW(a,b,c);
a b c
2 3 1
3 2 1
select * from t1 where ROW(a,2,3) IN(row(1,b,c), row(2,3,1));
a b c
1 2 3
select * from t1 where ROW(c,2,3) IN(row(1,b,a), row(2,3,1));
a b c
3 2 1
select * from t1 where ROW(a,b,c) IN(row(1,2,3), row(3,2,1));
a b c
1 2 3
3 2 1
drop table t1;
select ROW(1,1);
Cardinality error (more/less than 1 columns)
......
select row(1,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
select row(10,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
SELECT ROW(1,2,3)=ROW(1,2,3);
SELECT ROW(2,2,3)=ROW(1+1,2,3);
SELECT ROW(1,2,3)=ROW(1+1,2,3);
......@@ -18,6 +21,9 @@ insert into t1 values (1,2,3), (2,3,1), (3,2,1);
select * from t1 where ROW(1,2,3)=ROW(a,b,c);
select * from t1 where ROW(0,2,3)=ROW(a,b,c);
select * from t1 where ROW(1,2,3)<ROW(a,b,c);
select * from t1 where ROW(a,2,3) IN(row(1,b,c), row(2,3,1));
select * from t1 where ROW(c,2,3) IN(row(1,b,a), row(2,3,1));
select * from t1 where ROW(a,b,c) IN(row(1,2,3), row(3,2,1));
drop table t1;
-- error 1239
......
......@@ -1118,10 +1118,62 @@ byte *in_double::get_value(Item *item)
return (byte*) &tmp;
}
cmp_item* cmp_item::get_comparator (Item *item)
{
switch (item->result_type()) {
case STRING_RESULT:
if (item->binary())
return new cmp_item_binary_string;
else
return new cmp_item_sort_string;
break;
case INT_RESULT:
return new cmp_item_int;
break;
case REAL_RESULT:
return new cmp_item_real;
break;
case ROW_RESULT:
return new cmp_item_row;
break;
}
return 0; // to satisfy compiler :)
}
void cmp_item_row::store_value(Item *item)
{
n= item->cols();
if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
{
for (uint i=0; i < n; i++)
if ((comparators[i]= cmp_item::get_comparator(item->el(i))))
comparators[i]->store_value(item->el(i));
else
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
current_thd->fatal_error= 1;
return;
}
}
else
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
current_thd->fatal_error= 1;
return;
}
}
int cmp_item_row::cmp(Item *arg)
{
for(uint i=0; i < n; i++)
if(comparators[i]->cmp(arg->el(i)))
return 1;
return 0;
}
void Item_func_in::fix_length_and_dec()
{
if (const_item())
if (const_item() && item->result_type()!=ROW_RESULT)
{
switch (item->result_type()) {
case STRING_RESULT:
......@@ -1155,24 +1207,7 @@ void Item_func_in::fix_length_and_dec()
}
else
{
switch (item->result_type()) {
case STRING_RESULT:
if (item->binary())
in_item= new cmp_item_binary_string;
else
in_item= new cmp_item_sort_string;
break;
case INT_RESULT:
in_item= new cmp_item_int;
break;
case REAL_RESULT:
in_item= new cmp_item_real;
break;
case ROW_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
break;
}
in_item= cmp_item:: get_comparator(item);
}
maybe_null= item->maybe_null;
max_length=2;
......
......@@ -38,16 +38,12 @@ class Arg_comparator: public Sql_alloc
Arg_comparator() {};
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2) {};
inline void seta(Item **item) { a= item; }
inline void setb(Item **item) { b= item; }
int set_compare_func(Item_bool_func2 *owner, Item_result type);
inline int set_compare_func(Item_bool_func2 *owner)
{
return set_compare_func(owner, item_cmp_type((*a)->result_type(),
(*b)->result_type()));
}
inline int set_cmp_func(Item_bool_func2 *owner,
Item **a1, Item **a2,
Item_result type)
......@@ -437,6 +433,7 @@ class cmp_item :public Sql_alloc
virtual ~cmp_item() {}
virtual void store_value(Item *item)=0;
virtual int cmp(Item *item)=0;
static cmp_item* get_comparator(Item *);
};
......@@ -503,6 +500,14 @@ class cmp_item_real :public cmp_item
}
};
class cmp_item_row :public cmp_item
{
cmp_item **comparators;
uint n;
public:
void store_value(Item *item);
int cmp(Item *arg);
};
class Item_func_in :public Item_int_func
{
......@@ -512,12 +517,15 @@ class Item_func_in :public Item_int_func
bool have_null;
public:
Item_func_in(Item *a,List<Item> &list)
:Item_int_func(list), item(a), array(0), in_item(0), have_null(0) {}
:Item_int_func(list), item(a), array(0), in_item(0), have_null(0)
{
allowed_arg_cols= item->cols();
}
longlong val_int();
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref)
{
return (item->check_cols(1) ||
item->fix_fields(thd, tlist, &item) ||
// We do not check item->cols(), because allowed_arg_cols assigned from it
return (item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref));
}
void fix_length_and_dec();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment