Commit bdeb6fe2 authored by paul@ice.snake.net's avatar paul@ice.snake.net

Merge paul@bk-internal.mysql.com:/home/bk/mysql-4.1

into ice.snake.net:/Users/paul/mysql-4.1
parents 7fb37ad8 a2f7ef9c
...@@ -191,7 +191,7 @@ then ...@@ -191,7 +191,7 @@ then
echo "Installing all prepared tables" echo "Installing all prepared tables"
fi fi
if ( if (
$pkgdatadir/mysql_create_system_tables $create_option $mdata $hostname $windows $bindir/mysql_create_system_tables $create_option $mdata $hostname $windows
if test -n "$fill_help_tables" if test -n "$fill_help_tables"
then then
cat $fill_help_tables cat $fill_help_tables
......
...@@ -872,9 +872,9 @@ Item *Item_func_case::find_item(String *str) ...@@ -872,9 +872,9 @@ Item *Item_func_case::find_item(String *str)
LINT_INIT(first_expr_real); LINT_INIT(first_expr_real);
// Compare every WHEN argument with it and return the first match // Compare every WHEN argument with it and return the first match
for (uint i=0 ; i < arg_count ; i+=2) for (uint i=0 ; i < ncases ; i+=2)
{ {
if (!first_expr) if (first_expr_num == -1)
{ {
// No expression between CASE and first WHEN // No expression between CASE and first WHEN
if (args[i]->val_int()) if (args[i]->val_int())
...@@ -887,18 +887,12 @@ Item *Item_func_case::find_item(String *str) ...@@ -887,18 +887,12 @@ Item *Item_func_case::find_item(String *str)
{ {
str_used=1; str_used=1;
// We can't use 'str' here as this may be overwritten // We can't use 'str' here as this may be overwritten
if (!(first_expr_str= first_expr->val_str(&str_value))) if (!(first_expr_str= args[first_expr_num]->val_str(&str_value)))
return else_expr; // Impossible return else_expr_num != -1 ? args[else_expr_num] : 0; // Impossible
} }
if ((tmp=args[i]->val_str(str))) // If not null if ((tmp=args[i]->val_str(str))) // If not null
{ {
/* QQ: COERCIBILITY */ if (sortcmp(tmp,first_expr_str,&my_charset_bin)==0)
if (first_expr_is_binary || (args[i]->charset()->state & MY_CS_BINSORT))
{
if (sortcmp(tmp,first_expr_str,&my_charset_bin)==0)
return args[i+1];
}
else if (sortcmp(tmp,first_expr_str,tmp->charset())==0)
return args[i+1]; return args[i+1];
} }
break; break;
...@@ -906,9 +900,9 @@ Item *Item_func_case::find_item(String *str) ...@@ -906,9 +900,9 @@ Item *Item_func_case::find_item(String *str)
if (!int_used) if (!int_used)
{ {
int_used=1; int_used=1;
first_expr_int= first_expr->val_int(); first_expr_int= args[first_expr_num]->val_int();
if (first_expr->null_value) if (args[first_expr_num]->null_value)
return else_expr; return else_expr_num != -1 ? args[else_expr_num] : 0;
} }
if (args[i]->val_int()==first_expr_int && !args[i]->null_value) if (args[i]->val_int()==first_expr_int && !args[i]->null_value)
return args[i+1]; return args[i+1];
...@@ -917,9 +911,9 @@ Item *Item_func_case::find_item(String *str) ...@@ -917,9 +911,9 @@ Item *Item_func_case::find_item(String *str)
if (!real_used) if (!real_used)
{ {
real_used=1; real_used=1;
first_expr_real= first_expr->val(); first_expr_real= args[first_expr_num]->val();
if (first_expr->null_value) if (args[first_expr_num]->null_value)
return else_expr; return else_expr_num != -1 ? args[else_expr_num] : 0;
} }
if (args[i]->val()==first_expr_real && !args[i]->null_value) if (args[i]->val()==first_expr_real && !args[i]->null_value)
return args[i+1]; return args[i+1];
...@@ -932,7 +926,7 @@ Item *Item_func_case::find_item(String *str) ...@@ -932,7 +926,7 @@ Item *Item_func_case::find_item(String *str)
} }
} }
// No, WHEN clauses all missed, return ELSE expression // No, WHEN clauses all missed, return ELSE expression
return else_expr; return else_expr_num != -1 ? args[else_expr_num] : 0;
} }
...@@ -988,104 +982,74 @@ double Item_func_case::val() ...@@ -988,104 +982,74 @@ double Item_func_case::val()
return res; return res;
} }
static void agg_result_type(Item_result *type, Item **items, uint nitems)
bool
Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
if (first_expr && (first_expr->fix_fields(thd, tables, &first_expr) ||
first_expr->check_cols(1)) ||
else_expr && (else_expr->fix_fields(thd, tables, &else_expr) ||
else_expr->check_cols(1)))
return 1;
if (Item_func::fix_fields(thd, tables, ref))
return 1;
if (first_expr)
{
used_tables_cache|=(first_expr)->used_tables();
const_item_cache&= (first_expr)->const_item();
with_sum_func= with_sum_func || (first_expr)->with_sum_func;
first_expr_is_binary= first_expr->charset()->state & MY_CS_BINSORT;
}
if (else_expr)
{
used_tables_cache|=(else_expr)->used_tables();
const_item_cache&= (else_expr)->const_item();
with_sum_func= with_sum_func || (else_expr)->with_sum_func;
}
if (!else_expr || else_expr->maybe_null)
maybe_null=1; // The result may be NULL
return 0;
}
void Item_func_case::split_sum_func(Item **ref_pointer_array,
List<Item> &fields)
{ {
if (first_expr) uint i;
{ type[0]= items[0]->result_type();
if (first_expr->with_sum_func && first_expr->type() != SUM_FUNC_ITEM) for (i=1 ; i < nitems ; i++)
first_expr->split_sum_func(ref_pointer_array, fields); type[0]= item_store_type(type[0], items[i]->result_type());
else if (first_expr->used_tables() || first_expr->type() == SUM_FUNC_ITEM)
{
uint el= fields.elements;
fields.push_front(first_expr);
ref_pointer_array[el]= first_expr;
first_expr= new Item_ref(ref_pointer_array + el, 0, first_expr->name);
}
}
if (else_expr)
{
if (else_expr->with_sum_func && else_expr->type() != SUM_FUNC_ITEM)
else_expr->split_sum_func(ref_pointer_array, fields);
else if (else_expr->used_tables() || else_expr->type() == SUM_FUNC_ITEM)
{
uint el= fields.elements;
fields.push_front(else_expr);
ref_pointer_array[el]= else_expr;
else_expr= new Item_ref(ref_pointer_array + el, 0, else_expr->name);
}
}
Item_func::split_sum_func(ref_pointer_array, fields);
}
void Item_func_case::set_outer_resolving()
{
first_expr->set_outer_resolving();
else_expr->set_outer_resolving();
Item_func::set_outer_resolving();
} }
void Item_func_case::update_used_tables() static void agg_cmp_type(Item_result *type, Item **items, uint nitems)
{ {
Item_func::update_used_tables(); uint i;
if (first_expr) type[0]= items[0]->result_type();
{ for (i=1 ; i < nitems ; i++)
used_tables_cache|=(first_expr)->used_tables(); type[0]= item_cmp_type(type[0], items[i]->result_type());
const_item_cache&= (first_expr)->const_item();
}
if (else_expr)
{
used_tables_cache|=(else_expr)->used_tables();
const_item_cache&= (else_expr)->const_item();
}
} }
void Item_func_case::fix_length_and_dec() void Item_func_case::fix_length_and_dec()
{ {
Item **agg;
uint nagg;
if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
return;
// Aggregate all THEN and ELSE expression types
// and collations when string result
for (nagg= 0 ; nagg < ncases/2 ; nagg++)
agg[nagg]= args[nagg*2+1];
if (else_expr_num != -1)
agg[nagg++]= args[else_expr_num];
agg_result_type(&cached_result_type, agg, nagg);
if ((cached_result_type == STRING_RESULT) &&
agg_arg_collations(collation, agg, nagg))
return;
// Aggregate first expression and all THEN expression types
// and collations when string comparison
if (first_expr_num != -1)
{
agg[0]= args[first_expr_num];
for (nagg= 0; nagg < ncases/2 ; nagg++)
agg[nagg+1]= args[nagg];
nagg++;
agg_cmp_type(&cmp_type, agg, nagg);
if ((cmp_type == STRING_RESULT) &&
agg_arg_collations_for_comparison(cmp_collation, agg, nagg))
return;
}
if (!else_expr_num != -1 || args[else_expr_num]->maybe_null)
maybe_null=1;
max_length=0; max_length=0;
decimals=0; decimals=0;
cached_result_type = args[1]->result_type(); cached_result_type = args[1]->result_type();
for (uint i=0 ; i < arg_count ; i+=2) for (uint i=0 ; i < ncases ; i+=2)
{ {
set_if_bigger(max_length,args[i+1]->max_length); set_if_bigger(max_length,args[i+1]->max_length);
set_if_bigger(decimals,args[i+1]->decimals); set_if_bigger(decimals,args[i+1]->decimals);
} }
if (else_expr != NULL) if (else_expr_num != -1)
{ {
set_if_bigger(max_length,else_expr->max_length); set_if_bigger(max_length,args[else_expr_num]->max_length);
set_if_bigger(decimals,else_expr->decimals); set_if_bigger(decimals,args[else_expr_num]->decimals);
} }
} }
......
...@@ -348,27 +348,38 @@ class Item_func_coalesce :public Item_func ...@@ -348,27 +348,38 @@ class Item_func_coalesce :public Item_func
class Item_func_case :public Item_func class Item_func_case :public Item_func
{ {
Item * first_expr, *else_expr; int first_expr_num, else_expr_num;
enum Item_result cached_result_type; enum Item_result cached_result_type;
String tmp_value; String tmp_value;
bool first_expr_is_binary; uint ncases;
Item_result cmp_type;
DTCollation cmp_collation;
public: public:
Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg) Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
:Item_func(list), first_expr(first_expr_arg), else_expr(else_expr_arg), :Item_func(), first_expr_num(-1), else_expr_num(-1),
cached_result_type(INT_RESULT) cached_result_type(INT_RESULT)
{} {
ncases= list.elements;
if (first_expr_arg)
{
first_expr_num= list.elements;
list.push_back(first_expr_arg);
}
if (else_expr_arg)
{
else_expr_num= list.elements;
list.push_back(else_expr_arg);
}
set_arguments(list);
}
double val(); double val();
longlong val_int(); longlong val_int();
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec(); void fix_length_and_dec();
void update_used_tables();
enum Item_result result_type () const { return cached_result_type; } enum Item_result result_type () const { return cached_result_type; }
const char *func_name() const { return "case"; } const char *func_name() const { return "case"; }
void print(String *str); void print(String *str);
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
Item *find_item(String *str); Item *find_item(String *str);
void set_outer_resolving();
}; };
......
...@@ -102,10 +102,9 @@ eval_const_cond(COND *cond) ...@@ -102,10 +102,9 @@ eval_const_cond(COND *cond)
return ((Item_func*) cond)->val_int() ? TRUE : FALSE; return ((Item_func*) cond)->val_int() ? TRUE : FALSE;
} }
void Item_func::set_arguments(List<Item> &list)
Item_func::Item_func(List<Item> &list)
:allowed_arg_cols(1)
{ {
allowed_arg_cols= 1;
arg_count=list.elements; arg_count=list.elements;
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count))) if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
{ {
...@@ -122,6 +121,12 @@ Item_func::Item_func(List<Item> &list) ...@@ -122,6 +121,12 @@ Item_func::Item_func(List<Item> &list)
list.empty(); // Fields are used list.empty(); // Fields are used
} }
Item_func::Item_func(List<Item> &list)
:allowed_arg_cols(1)
{
set_arguments(list);
}
/* /*
Resolve references to table column for a function and it's argument Resolve references to table column for a function and it's argument
......
...@@ -115,6 +115,7 @@ class Item_func :public Item_result_field ...@@ -115,6 +115,7 @@ class Item_func :public Item_result_field
virtual const char *func_name() const { return "?"; } virtual const char *func_name() const { return "?"; }
virtual bool const_item() const { return const_item_cache; } virtual bool const_item() const { return const_item_cache; }
inline Item **arguments() const { return args; } inline Item **arguments() const { return args; }
void set_arguments(List<Item> &list);
inline uint argument_count() const { return arg_count; } inline uint argument_count() const { return arg_count; }
inline void remove_arguments() { arg_count=0; } inline void remove_arguments() { arg_count=0; }
virtual void split_sum_func(Item **ref_pointer_array, List<Item> &fields); virtual void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
......
...@@ -2030,7 +2030,7 @@ CHARSET_INFO my_charset_utf8_bin= ...@@ -2030,7 +2030,7 @@ CHARSET_INFO my_charset_utf8_bin=
3, /* mbmaxlen */ 3, /* mbmaxlen */
0, 0,
&my_charset_handler, &my_charset_handler,
&my_collation_ci_handler &my_collation_bin_handler
}; };
......
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