mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge olga.mysql.com:/home/igor/dev-opt/mysql-4.1-opt-bug27484
into olga.mysql.com:/home/igor/mysql-5.0-opt mysql-test/t/row.test: Auto merged mysql-test/r/row.result: Manual merge sql/item_cmpfunc.cc: Manual merge
This commit is contained in:
@ -175,12 +175,24 @@ ROW(2,10) <=> ROW(3,4)
|
|||||||
SELECT ROW(NULL,10) <=> ROW(3,NULL);
|
SELECT ROW(NULL,10) <=> ROW(3,NULL);
|
||||||
ROW(NULL,10) <=> ROW(3,NULL)
|
ROW(NULL,10) <=> ROW(3,NULL)
|
||||||
0
|
0
|
||||||
SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NULL,1) = ROW(2,2,1) as `0`, ROW(1,NULL,1) = ROW(1,2,2) as `0`, ROW(1,NULL,1) = ROW(1,2,1) as `null` ;
|
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1));
|
||||||
1 0 0 0 null
|
ERROR 21000: Operand should contain 2 column(s)
|
||||||
1 0 0 0 NULL
|
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1),ROW(1,ROW(2,3)));
|
||||||
select row(NULL,1)=(2,0);
|
ERROR 21000: Operand should contain 2 column(s)
|
||||||
row(NULL,1)=(2,0)
|
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,ROW(2,2,2)));
|
||||||
0
|
ERROR 21000: Operand should contain 2 column(s)
|
||||||
|
SELECT ROW(1,ROW(2,3,4)) IN (ROW(1,ROW(2,3,4)),ROW(1,ROW(2,2)));
|
||||||
|
ERROR 21000: Operand should contain 3 column(s)
|
||||||
|
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1));
|
||||||
|
ERROR 21000: Operand should contain 2 column(s)
|
||||||
|
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1),ROW(1,ROW(2,4)));
|
||||||
|
ERROR 21000: Operand should contain 2 column(s)
|
||||||
|
SELECT ROW(1,ROW(2,3)) IN ((SELECT 1,1),ROW(1,ROW(2,3)));
|
||||||
|
ERROR 21000: Operand should contain 2 column(s)
|
||||||
|
SELECT ROW(2,1) IN (ROW(21,2),ROW(ROW(1,1,3),0));
|
||||||
|
ERROR 21000: Operand should contain 1 column(s)
|
||||||
|
SELECT ROW(2,1) IN (ROW(ROW(1,1,3),0),ROW(21,2));
|
||||||
|
ERROR 21000: Operand should contain 1 column(s)
|
||||||
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b));
|
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b));
|
||||||
INSERT INTO t1 VALUES (1,1), (2,1), (3,1), (1,2), (3,2), (3,3);
|
INSERT INTO t1 VALUES (1,1), (2,1), (3,1), (1,2), (3,2), (3,3);
|
||||||
EXPLAIN SELECT * FROM t1 WHERE a=3 AND b=2;
|
EXPLAIN SELECT * FROM t1 WHERE a=3 AND b=2;
|
||||||
|
@ -85,6 +85,31 @@ drop table t1;
|
|||||||
SELECT ROW(2,10) <=> ROW(3,4);
|
SELECT ROW(2,10) <=> ROW(3,4);
|
||||||
SELECT ROW(NULL,10) <=> ROW(3,NULL);
|
SELECT ROW(NULL,10) <=> ROW(3,NULL);
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #27484: nested row expressions in IN predicate
|
||||||
|
#
|
||||||
|
|
||||||
|
--error 1241
|
||||||
|
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1));
|
||||||
|
--error 1241
|
||||||
|
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,1),ROW(1,ROW(2,3)));
|
||||||
|
--error 1241
|
||||||
|
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),ROW(1,ROW(2,2,2)));
|
||||||
|
--error 1241
|
||||||
|
SELECT ROW(1,ROW(2,3,4)) IN (ROW(1,ROW(2,3,4)),ROW(1,ROW(2,2)));
|
||||||
|
|
||||||
|
--error 1241
|
||||||
|
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1));
|
||||||
|
--error 1241
|
||||||
|
SELECT ROW(1,ROW(2,3)) IN (ROW(1,ROW(2,3)),(SELECT 1,1),ROW(1,ROW(2,4)));
|
||||||
|
--error 1241
|
||||||
|
SELECT ROW(1,ROW(2,3)) IN ((SELECT 1,1),ROW(1,ROW(2,3)));
|
||||||
|
|
||||||
|
--error 1241
|
||||||
|
SELECT ROW(2,1) IN (ROW(21,2),ROW(ROW(1,1,3),0));
|
||||||
|
--error 1241
|
||||||
|
SELECT ROW(2,1) IN (ROW(ROW(1,1,3),0),ROW(21,2));
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -68,6 +68,42 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compare row signature of two expressions
|
||||||
|
|
||||||
|
SYNOPSIS:
|
||||||
|
cmp_row_type()
|
||||||
|
item1 the first expression
|
||||||
|
item2 the second expression
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The function checks that two expressions have compatible row signatures
|
||||||
|
i.e. that the number of columns they return are the same and that if they
|
||||||
|
are both row expressions then each component from the first expression has
|
||||||
|
a row signature compatible with the signature of the corresponding component
|
||||||
|
of the second expression.
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
1 type incompatibility has been detected
|
||||||
|
0 otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int cmp_row_type(Item* item1, Item* item2)
|
||||||
|
{
|
||||||
|
uint n= item1->cols();
|
||||||
|
if (item2->check_cols(n))
|
||||||
|
return 1;
|
||||||
|
for (uint i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
if (item2->el(i)->check_cols(item1->el(i)->cols()) ||
|
||||||
|
(item1->el(i)->result_type() == ROW_RESULT &&
|
||||||
|
cmp_row_type(item1->el(i), item2->el(i))))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Aggregates result types from the array of items.
|
Aggregates result types from the array of items.
|
||||||
|
|
||||||
@ -82,14 +118,32 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
|
|||||||
This function aggregates result types from the array of items. Found type
|
This function aggregates result types from the array of items. Found type
|
||||||
supposed to be used later for comparison of values of these items.
|
supposed to be used later for comparison of values of these items.
|
||||||
Aggregation itself is performed by the item_cmp_type() function.
|
Aggregation itself is performed by the item_cmp_type() function.
|
||||||
|
The function also checks compatibility of row signatures for the
|
||||||
|
submitted items (see the spec for the cmp_row_type function).
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
1 type incompatibility has been detected
|
||||||
|
0 otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
|
static int agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
type[0]= items[0]->result_type();
|
type[0]= items[0]->result_type();
|
||||||
for (i= 1 ; i < nitems ; i++)
|
for (i= 1 ; i < nitems ; i++)
|
||||||
|
{
|
||||||
type[0]= item_cmp_type(type[0], items[i]->result_type());
|
type[0]= item_cmp_type(type[0], items[i]->result_type());
|
||||||
|
/*
|
||||||
|
When aggregating types of two row expressions we have to check
|
||||||
|
that they have the same cardinality and that each component
|
||||||
|
of the first row expression has a compatible row signature with
|
||||||
|
the signature of the corresponding component of the second row
|
||||||
|
expression.
|
||||||
|
*/
|
||||||
|
if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
|
||||||
|
return 1; // error found: invalid usage of rows
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1305,7 +1359,8 @@ void Item_func_between::fix_length_and_dec()
|
|||||||
*/
|
*/
|
||||||
if (!args[0] || !args[1] || !args[2])
|
if (!args[0] || !args[1] || !args[2])
|
||||||
return;
|
return;
|
||||||
agg_cmp_type(thd, &cmp_type, args, 3);
|
if ( agg_cmp_type(thd, &cmp_type, args, 3))
|
||||||
|
return;
|
||||||
if (cmp_type == STRING_RESULT &&
|
if (cmp_type == STRING_RESULT &&
|
||||||
agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
|
agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
|
||||||
return;
|
return;
|
||||||
@ -2021,7 +2076,8 @@ void Item_func_case::fix_length_and_dec()
|
|||||||
for (nagg= 0; nagg < ncases/2 ; nagg++)
|
for (nagg= 0; nagg < ncases/2 ; nagg++)
|
||||||
agg[nagg+1]= args[nagg*2];
|
agg[nagg+1]= args[nagg*2];
|
||||||
nagg++;
|
nagg++;
|
||||||
agg_cmp_type(thd, &cmp_type, agg, nagg);
|
if (agg_cmp_type(thd, &cmp_type, agg, nagg))
|
||||||
|
return;
|
||||||
if ((cmp_type == STRING_RESULT) &&
|
if ((cmp_type == STRING_RESULT) &&
|
||||||
agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
|
agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
|
||||||
return;
|
return;
|
||||||
@ -2710,7 +2766,8 @@ void Item_func_in::fix_length_and_dec()
|
|||||||
uint const_itm= 1;
|
uint const_itm= 1;
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
|
|
||||||
agg_cmp_type(thd, &cmp_type, args, arg_count);
|
if (agg_cmp_type(thd, &cmp_type, args, arg_count))
|
||||||
|
return;
|
||||||
|
|
||||||
if (cmp_type == STRING_RESULT &&
|
if (cmp_type == STRING_RESULT &&
|
||||||
agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
|
agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
|
||||||
|
Reference in New Issue
Block a user