From 35262eebdce3f0870e66ab4ad5b8ec66429738e4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Jul 2003 10:21:30 +0500 Subject: [PATCH 1/4] ctype-utf8.c: Stupid bug fix strings/ctype-utf8.c: Stupid bug fix --- strings/ctype-utf8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index f5da95571c4..1982b9e3ba8 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2030,7 +2030,7 @@ CHARSET_INFO my_charset_utf8_bin= 3, /* mbmaxlen */ 0, &my_charset_handler, - &my_collation_ci_handler + &my_collation_bin_handler }; From d5a6d17707bfda6015b60b589d38e5ad5d3ab52c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Jul 2003 16:07:56 +0500 Subject: [PATCH 2/4] CASE stores first_expr and else_expr in args[] array now. This allowed to reuse a lot of code. --- sql/item_cmpfunc.cc | 118 ++++++++------------------------------------ sql/item_cmpfunc.h | 24 ++++++--- sql/item_func.cc | 11 +++-- sql/item_func.h | 1 + 4 files changed, 46 insertions(+), 108 deletions(-) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 758733aaa2c..df02dc5fe32 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -872,9 +872,9 @@ Item *Item_func_case::find_item(String *str) LINT_INIT(first_expr_real); // 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 if (args[i]->val_int()) @@ -887,8 +887,8 @@ Item *Item_func_case::find_item(String *str) { str_used=1; // We can't use 'str' here as this may be overwritten - if (!(first_expr_str= first_expr->val_str(&str_value))) - return else_expr; // Impossible + if (!(first_expr_str= args[first_expr_num]->val_str(&str_value))) + return else_expr_num != -1 ? args[else_expr_num] : 0; // Impossible } if ((tmp=args[i]->val_str(str))) // If not null { @@ -906,9 +906,9 @@ Item *Item_func_case::find_item(String *str) if (!int_used) { int_used=1; - first_expr_int= first_expr->val_int(); - if (first_expr->null_value) - return else_expr; + first_expr_int= args[first_expr_num]->val_int(); + if (args[first_expr_num]->null_value) + return else_expr_num != -1 ? args[else_expr_num] : 0; } if (args[i]->val_int()==first_expr_int && !args[i]->null_value) return args[i+1]; @@ -917,9 +917,9 @@ Item *Item_func_case::find_item(String *str) if (!real_used) { real_used=1; - first_expr_real= first_expr->val(); - if (first_expr->null_value) - return else_expr; + first_expr_real= args[first_expr_num]->val(); + if (args[first_expr_num]->null_value) + return else_expr_num != -1 ? args[else_expr_num] : 0; } if (args[i]->val()==first_expr_real && !args[i]->null_value) return args[i+1]; @@ -932,7 +932,7 @@ Item *Item_func_case::find_item(String *str) } } // No, WHEN clauses all missed, return ELSE expression - return else_expr; + return else_expr_num != -1 ? args[else_expr_num] : 0; } @@ -989,103 +989,25 @@ double Item_func_case::val() } -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 &fields) -{ - if (first_expr) - { - if (first_expr->with_sum_func && first_expr->type() != SUM_FUNC_ITEM) - first_expr->split_sum_func(ref_pointer_array, fields); - 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() { + if (first_expr_num != -1) + first_expr_is_binary= args[first_expr_num]->charset()->state & MY_CS_BINSORT; + if (!else_expr_num != -1 || args[else_expr_num]->maybe_null) + maybe_null=1; + max_length=0; decimals=0; 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(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(decimals,else_expr->decimals); + set_if_bigger(max_length,args[else_expr_num]->max_length); + set_if_bigger(decimals,args[else_expr_num]->decimals); } } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 9de222aafaf..9953e3d87a4 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -348,27 +348,37 @@ public: 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; String tmp_value; bool first_expr_is_binary; + uint ncases; public: Item_func_case(List &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) - {} + { + 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(); longlong val_int(); String *val_str(String *); void fix_length_and_dec(); - void update_used_tables(); enum Item_result result_type () const { return cached_result_type; } const char *func_name() const { return "case"; } 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 &fields); Item *find_item(String *str); - void set_outer_resolving(); }; diff --git a/sql/item_func.cc b/sql/item_func.cc index 7e236225067..ea3c3980a50 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -102,10 +102,9 @@ eval_const_cond(COND *cond) return ((Item_func*) cond)->val_int() ? TRUE : FALSE; } - -Item_func::Item_func(List &list) - :allowed_arg_cols(1) +void Item_func::set_arguments(List &list) { + allowed_arg_cols= 1; arg_count=list.elements; if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count))) { @@ -122,6 +121,12 @@ Item_func::Item_func(List &list) list.empty(); // Fields are used } +Item_func::Item_func(List &list) + :allowed_arg_cols(1) +{ + set_arguments(list); +} + /* Resolve references to table column for a function and it's argument diff --git a/sql/item_func.h b/sql/item_func.h index a0969fc6b9a..7002f885c50 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -115,6 +115,7 @@ public: virtual const char *func_name() const { return "?"; } virtual bool const_item() const { return const_item_cache; } inline Item **arguments() const { return args; } + void set_arguments(List &list); inline uint argument_count() const { return arg_count; } inline void remove_arguments() { arg_count=0; } virtual void split_sum_func(Item **ref_pointer_array, List &fields); From 96627521e88660b3bc7f4624c06f13e435de9db9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Jul 2003 12:15:41 -0400 Subject: [PATCH 3/4] fixed bug with location of mysql_create_sytem_tables --- scripts/mysql_install_db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 9e4f35dd5e1..a69995e51a0 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -191,7 +191,7 @@ then echo "Installing all prepared tables" fi 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" then cat $fill_help_tables From 102bfc9ee8ecc51cdf39044dff7579f5746000f7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Jul 2003 22:58:05 +0500 Subject: [PATCH 4/4] CASE now aggregates all argument types instead of using the only one argument --- sql/item_cmpfunc.cc | 60 ++++++++++++++++++++++++++++++++++++++------- sql/item_cmpfunc.h | 3 ++- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index df02dc5fe32..1f1b449e9a7 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -892,13 +892,7 @@ Item *Item_func_case::find_item(String *str) } 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) - return args[i+1]; - } - else if (sortcmp(tmp,first_expr_str,tmp->charset())==0) + if (sortcmp(tmp,first_expr_str,&my_charset_bin)==0) return args[i+1]; } break; @@ -988,14 +982,62 @@ double Item_func_case::val() return res; } +static void agg_result_type(Item_result *type, Item **items, uint nitems) +{ + uint i; + type[0]= items[0]->result_type(); + for (i=1 ; i < nitems ; i++) + type[0]= item_store_type(type[0], items[i]->result_type()); +} + +static void agg_cmp_type(Item_result *type, Item **items, uint nitems) +{ + uint i; + type[0]= items[0]->result_type(); + for (i=1 ; i < nitems ; i++) + type[0]= item_cmp_type(type[0], items[i]->result_type()); +} 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) - first_expr_is_binary= args[first_expr_num]->charset()->state & MY_CS_BINSORT; + { + 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; decimals=0; cached_result_type = args[1]->result_type(); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 9953e3d87a4..a9fba76a7b8 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -351,8 +351,9 @@ class Item_func_case :public Item_func int first_expr_num, else_expr_num; enum Item_result cached_result_type; String tmp_value; - bool first_expr_is_binary; uint ncases; + Item_result cmp_type; + DTCollation cmp_collation; public: Item_func_case(List &list, Item *first_expr_arg, Item *else_expr_arg) :Item_func(), first_expr_num(-1), else_expr_num(-1),