Merge paul@bk-internal.mysql.com:/home/bk/mysql-4.1
into ice.snake.net:/Users/paul/mysql-4.1
This commit is contained in:
commit
926b05ed0e
@ -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)
|
|||||||
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,28 +887,22 @@ 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 (first_expr_is_binary || (args[i]->charset()->state & MY_CS_BINSORT))
|
|
||||||
{
|
{
|
||||||
if (sortcmp(tmp,first_expr_str,&my_charset_bin)==0)
|
if (sortcmp(tmp,first_expr_str,&my_charset_bin)==0)
|
||||||
return args[i+1];
|
return args[i+1];
|
||||||
}
|
}
|
||||||
else if (sortcmp(tmp,first_expr_str,tmp->charset())==0)
|
|
||||||
return args[i+1];
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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()
|
|||||||
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) ||
|
uint i;
|
||||||
first_expr->check_cols(1)) ||
|
type[0]= items[0]->result_type();
|
||||||
else_expr && (else_expr->fix_fields(thd, tables, &else_expr) ||
|
for (i=1 ; i < nitems ; i++)
|
||||||
else_expr->check_cols(1)))
|
type[0]= item_store_type(type[0], items[i]->result_type());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void agg_cmp_type(Item_result *type, Item **items, uint nitems)
|
||||||
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_cmp_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()
|
|
||||||
{
|
|
||||||
Item_func::update_used_tables();
|
|
||||||
if (first_expr)
|
|
||||||
{
|
|
||||||
used_tables_cache|=(first_expr)->used_tables();
|
|
||||||
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 @@ public:
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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 @@ public:
|
|||||||
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=
|
|||||||
3, /* mbmaxlen */
|
3, /* mbmaxlen */
|
||||||
0,
|
0,
|
||||||
&my_charset_handler,
|
&my_charset_handler,
|
||||||
&my_collation_ci_handler
|
&my_collation_bin_handler
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user