mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge olga.mysql.com:/home/igor/mysql-5.0-opt
into olga.mysql.com:/home/igor/mysql-5.1-opt mysql-test/r/distinct.result: Auto merged mysql-test/r/row.result: Auto merged mysql-test/r/select.result: Auto merged mysql-test/r/strict.result: Auto merged mysql-test/t/select.test: Auto merged mysql-test/t/strict.test: Auto merged sql/sql_select.cc: Auto merged sql/sql_table.cc: Auto merged sql/item_cmpfunc.cc: Manual merge
This commit is contained in:
@@ -68,57 +68,81 @@ 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->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
|
||||
(item1->element_index(i)->result_type() == ROW_RESULT &&
|
||||
cmp_row_type(item1->element_index(i), item2->element_index(i))))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Aggregates result types from the array of items.
|
||||
|
||||
SYNOPSIS
|
||||
SYNOPSIS:
|
||||
agg_cmp_type()
|
||||
items array of items to aggregate the type from
|
||||
nitems number of items in the array
|
||||
type [out] the aggregated type
|
||||
items array of items to aggregate the type from
|
||||
nitems number of items in the array
|
||||
|
||||
DESCRIPTION
|
||||
This function aggregates result types from the array of items. Found type
|
||||
supposed to be used later for comparison of values of these items.
|
||||
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 Item_result agg_cmp_type(Item **items, uint nitems)
|
||||
static int agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
|
||||
{
|
||||
uint i;
|
||||
Item_result type= items[0]->result_type();
|
||||
type[0]= items[0]->result_type();
|
||||
for (i= 1 ; i < nitems ; i++)
|
||||
type= item_cmp_type(type, items[i]->result_type());
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Collects different types for comparison of first item with each other items
|
||||
|
||||
SYNOPSIS
|
||||
collect_cmp_types()
|
||||
items Array of items to collect types from
|
||||
nitems Number of items in the array
|
||||
|
||||
DESCRIPTION
|
||||
This function collects different result types for comparison of the first
|
||||
item in the list with each of the remaining items in the 'items' array.
|
||||
|
||||
RETURN
|
||||
Bitmap of collected types
|
||||
*/
|
||||
|
||||
static uint collect_cmp_types(Item **items, uint nitems)
|
||||
{
|
||||
uint i;
|
||||
uint found_types;
|
||||
Item_result left_result= items[0]->result_type();
|
||||
DBUG_ASSERT(nitems > 1);
|
||||
found_types= 0;
|
||||
for (i= 1; i < nitems ; i++)
|
||||
found_types|= 1<< (uint)item_cmp_type(left_result,
|
||||
items[i]->result_type());
|
||||
return found_types;
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1355,7 +1379,8 @@ void Item_func_between::fix_length_and_dec()
|
||||
*/
|
||||
if (!args[0] || !args[1] || !args[2])
|
||||
return;
|
||||
cmp_type= agg_cmp_type(args, 3);
|
||||
if ( agg_cmp_type(&cmp_type, args, 3))
|
||||
return;
|
||||
if (cmp_type == STRING_RESULT &&
|
||||
agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1))
|
||||
return;
|
||||
@@ -2060,6 +2085,23 @@ void Item_func_case::fix_length_and_dec()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
found_types= collect_cmp_types(agg, nagg);
|
||||
|
||||
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
|
||||
{
|
||||
if (found_types & (1 << i) && !cmp_items[i])
|
||||
{
|
||||
DBUG_ASSERT((Item_result)i != ROW_RESULT);
|
||||
if ((Item_result)i == STRING_RESULT &&
|
||||
agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
|
||||
return;
|
||||
if (!(cmp_items[i]=
|
||||
cmp_item::get_comparator((Item_result)i,
|
||||
cmp_collation.collation)))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
|
||||
|
Reference in New Issue
Block a user