diff options
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 536 |
1 files changed, 318 insertions, 218 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 919015140c1..19809ed08c7 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -109,7 +109,6 @@ static int cmp_row_type(Item* item1, Item* item2) SYNOPSIS: agg_cmp_type() - thd thread handle type [out] the aggregated type items array of items to aggregate the type from nitems number of items in the array @@ -126,7 +125,7 @@ static int cmp_row_type(Item* item1, Item* item2) 0 otherwise */ -static int agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) +static int agg_cmp_type(Item_result *type, Item **items, uint nitems) { uint i; type[0]= items[0]->result_type(); @@ -147,6 +146,42 @@ static int agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) } +/* + 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 + 0 - if row type incompatibility has been detected (see cmp_row_type) + Bitmap of collected types - otherwise +*/ + +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++) + { + if ((left_result == ROW_RESULT || + items[i]->result_type() == ROW_RESULT) && + cmp_row_type(items[0], items[i])) + return 0; + found_types|= 1<< (uint)item_cmp_type(left_result, + items[i]->result_type()); + } + return found_types; +} + static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { @@ -312,27 +347,45 @@ longlong Item_func_nop_all::val_int() static bool convert_constant_item(THD *thd, Field *field, Item **item) { + int result= 0; + if (!(*item)->with_subselect && (*item)->const_item()) { - /* For comparison purposes allow invalid dates like 2000-01-32 */ + TABLE *table= field->table; ulong orig_sql_mode= thd->variables.sql_mode; enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields; + my_bitmap_map *old_write_map; + my_bitmap_map *old_read_map; + + LINT_INIT(old_write_map); + LINT_INIT(old_read_map); + + if (table) + { + old_write_map= dbug_tmp_use_all_columns(table, table->write_set); + old_read_map= dbug_tmp_use_all_columns(table, table->read_set); + } + /* For comparison purposes allow invalid dates like 2000-01-32 */ thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) | MODE_INVALID_DATES; thd->count_cuted_fields= CHECK_FIELD_IGNORE; if (!(*item)->save_in_field(field, 1) && !((*item)->null_value)) { - Item *tmp=new Item_int_with_ref(field->val_int(), *item, - test(field->flags & UNSIGNED_FLAG)); - thd->variables.sql_mode= orig_sql_mode; + Item *tmp= new Item_int_with_ref(field->val_int(), *item, + test(field->flags & UNSIGNED_FLAG)); if (tmp) thd->change_item_tree(item, tmp); - return 1; // Item was replaced + result= 1; // Item was replaced } thd->variables.sql_mode= orig_sql_mode; thd->count_cuted_fields= orig_count_cuted_fields; + if (table) + { + dbug_tmp_restore_column_map(table->write_set, old_write_map); + dbug_tmp_restore_column_map(table->read_set, old_read_map); + } } - return 0; + return result; } @@ -478,8 +531,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) which would be transformed to: WHERE col= 'j' */ - (*a)->walk(&Item::set_no_const_sub, (byte*) 0); - (*b)->walk(&Item::set_no_const_sub, (byte*) 0); + (*a)->walk(&Item::set_no_const_sub, FALSE, (uchar*) 0); + (*b)->walk(&Item::set_no_const_sub, FALSE, (uchar*) 0); } break; } @@ -1290,7 +1343,8 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref) } not_null_tables_cache= args[0]->not_null_tables(); with_sum_func= args[0]->with_sum_func; - const_item_cache= args[0]->const_item(); + if ((const_item_cache= args[0]->const_item())) + cache->store(args[0]); return 0; } @@ -1517,8 +1571,10 @@ bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const void Item_func_interval::fix_length_and_dec() { - use_decimal_comparison= (row->element_index(0)->result_type() == DECIMAL_RESULT) || - (row->element_index(0)->result_type() == INT_RESULT); + use_decimal_comparison= ((row->element_index(0)->result_type() == + DECIMAL_RESULT) || + (row->element_index(0)->result_type() == + INT_RESULT)); if (row->cols() > 8) { bool consts=1; @@ -1713,7 +1769,6 @@ bool Item_func_between::fix_fields(THD *thd, Item **ref) void Item_func_between::fix_length_and_dec() { max_length= 1; - THD *thd= current_thd; int i; bool datetime_found= FALSE; compare_as_dates= TRUE; @@ -1724,7 +1779,7 @@ void Item_func_between::fix_length_and_dec() */ if (!args[0] || !args[1] || !args[2]) return; - if ( agg_cmp_type(thd, &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)) @@ -1943,7 +1998,7 @@ enum_field_types Item_func_ifnull::field_type() const Field *Item_func_ifnull::tmp_table_field(TABLE *table) { - return tmp_table_field_from_field_type(table); + return tmp_table_field_from_field_type(table, 0); } double @@ -2254,94 +2309,65 @@ Item_func_nullif::is_null() return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); } + /* - CASE expression Return the matching ITEM or NULL if all compares (including else) failed + + SYNOPSIS + find_item() + str Buffer string + + DESCRIPTION + Find and return matching items for CASE or ELSE item if all compares + are failed or NULL if ELSE item isn't defined. + + IMPLEMENTATION + In order to do correct comparisons of the CASE expression (the expression + between CASE and the first WHEN) with each WHEN expression several + comparators are used. One for each result type. CASE expression can be + evaluated up to # of different result types are used. To check whether + the CASE expression already was evaluated for a particular result type + a bit mapped variable value_added_map is used. Result types are mapped + to it according to their int values i.e. STRING_RESULT is mapped to bit + 0, REAL_RESULT to bit 1, so on. + + RETURN + NULL - Nothing found and there is no ELSE expression defined + item - Found item or ELSE item if defined and all comparisons are + failed */ Item *Item_func_case::find_item(String *str) { - String *first_expr_str, *tmp; - my_decimal *first_expr_dec, first_expr_dec_val; - longlong first_expr_int; - double first_expr_real; - char buff[MAX_FIELD_WIDTH]; - String buff_str(buff,sizeof(buff),default_charset()); - - /* These will be initialized later */ - LINT_INIT(first_expr_str); - LINT_INIT(first_expr_int); - LINT_INIT(first_expr_real); - LINT_INIT(first_expr_dec); + uint value_added_map= 0; - if (first_expr_num != -1) + if (first_expr_num == -1) { - switch (cmp_type) - { - case STRING_RESULT: - // We can't use 'str' here as this may be overwritten - if (!(first_expr_str= args[first_expr_num]->val_str(&buff_str))) - return else_expr_num != -1 ? args[else_expr_num] : 0; // Impossible - break; - case INT_RESULT: - 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; - break; - case REAL_RESULT: - first_expr_real= args[first_expr_num]->val_real(); - if (args[first_expr_num]->null_value) - return else_expr_num != -1 ? args[else_expr_num] : 0; - break; - case DECIMAL_RESULT: - first_expr_dec= args[first_expr_num]->val_decimal(&first_expr_dec_val); - if (args[first_expr_num]->null_value) - return else_expr_num != -1 ? args[else_expr_num] : 0; - break; - case ROW_RESULT: - default: - // This case should never be chosen - DBUG_ASSERT(0); - break; - } - } - - // Compare every WHEN argument with it and return the first match - for (uint i=0 ; i < ncases ; i+=2) - { - if (first_expr_num == -1) + for (uint i=0 ; i < ncases ; i+=2) { // No expression between CASE and the first WHEN if (args[i]->val_bool()) return args[i+1]; continue; } - switch (cmp_type) { - case STRING_RESULT: - if ((tmp=args[i]->val_str(str))) // If not null - if (sortcmp(tmp,first_expr_str,cmp_collation.collation)==0) - return args[i+1]; - break; - case INT_RESULT: - if (args[i]->val_int()==first_expr_int && !args[i]->null_value) - return args[i+1]; - break; - case REAL_RESULT: - if (args[i]->val_real() == first_expr_real && !args[i]->null_value) - return args[i+1]; - break; - case DECIMAL_RESULT: + } + else + { + /* Compare every WHEN argument with it and return the first match */ + for (uint i=0 ; i < ncases ; i+=2) { - my_decimal value; - if (my_decimal_cmp(args[i]->val_decimal(&value), first_expr_dec) == 0) - return args[i+1]; - break; - } - case ROW_RESULT: - default: - // This case should never be chosen - DBUG_ASSERT(0); - break; + cmp_type= item_cmp_type(left_result_type, args[i]->result_type()); + DBUG_ASSERT(cmp_type != ROW_RESULT); + DBUG_ASSERT(cmp_items[(uint)cmp_type]); + if (!(value_added_map & (1<<(uint)cmp_type))) + { + cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]); + if ((null_value=args[first_expr_num]->null_value)) + return else_expr_num != -1 ? args[else_expr_num] : 0; + value_added_map|= 1<<(uint)cmp_type; + } + if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value) + return args[i + 1]; } } // No, WHEN clauses all missed, return ELSE expression @@ -2431,7 +2457,7 @@ bool Item_func_case::fix_fields(THD *thd, Item **ref) Item_func_case::val_int() -> Item_func_case::find_item() */ #ifndef EMBEDDED_LIBRARY - char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(longlong)*2]; + uchar buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(longlong)*2]; #endif bool res= Item_func::fix_fields(thd, ref); /* @@ -2449,8 +2475,7 @@ void Item_func_case::fix_length_and_dec() { Item **agg; uint nagg; - THD *thd= current_thd; - + uint found_types= 0; if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1)))) return; @@ -2477,17 +2502,32 @@ void Item_func_case::fix_length_and_dec() */ if (first_expr_num != -1) { + uint i; agg[0]= args[first_expr_num]; + left_result_type= agg[0]->result_type(); + for (nagg= 0; nagg < ncases/2 ; nagg++) agg[nagg+1]= args[nagg*2]; nagg++; - if (agg_cmp_type(thd, &cmp_type, agg, nagg)) - return; - if ((cmp_type == STRING_RESULT) && - agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1)) + if (!(found_types= collect_cmp_types(agg, nagg))) return; + + 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) maybe_null=1; @@ -2757,7 +2797,7 @@ static int cmp_decimal(void *cmp_arg, my_decimal *a, my_decimal *b) int in_vector::find(Item *item) { - byte *result=get_value(item); + uchar *result=get_value(item); if (!result || !used_count) return 0; // Null value @@ -2812,9 +2852,9 @@ void in_string::set(uint pos,Item *item) } -byte *in_string::get_value(Item *item) +uchar *in_string::get_value(Item *item) { - return (byte*) item->val_str(&tmp); + return (uchar*) item->val_str(&tmp); } in_row::in_row(uint elements, Item * item) @@ -2836,12 +2876,12 @@ in_row::~in_row() delete [] (cmp_item_row*) base; } -byte *in_row::get_value(Item *item) +uchar *in_row::get_value(Item *item) { tmp.store_value(item); if (item->is_null()) return 0; - return (byte *)&tmp; + return (uchar *)&tmp; } void in_row::set(uint pos, Item *item) @@ -2864,13 +2904,13 @@ void in_longlong::set(uint pos,Item *item) buff->unsigned_flag= item->unsigned_flag; } -byte *in_longlong::get_value(Item *item) +uchar *in_longlong::get_value(Item *item) { tmp.val= item->val_int(); if (item->null_value) return 0; tmp.unsigned_flag= item->unsigned_flag; - return (byte*) &tmp; + return (uchar*) &tmp; } void in_datetime::set(uint pos,Item *item) @@ -2883,7 +2923,7 @@ void in_datetime::set(uint pos,Item *item) buff->unsigned_flag= 1L; } -byte *in_datetime::get_value(Item *item) +uchar *in_datetime::get_value(Item *item) { bool is_null; Item **tmp_item= lval_cache ? &lval_cache : &item; @@ -2891,7 +2931,7 @@ byte *in_datetime::get_value(Item *item) if (item->null_value) return 0; tmp.unsigned_flag= 1L; - return (byte*) &tmp; + return (uchar*) &tmp; } in_double::in_double(uint elements) @@ -2903,12 +2943,12 @@ void in_double::set(uint pos,Item *item) ((double*) base)[pos]= item->val_real(); } -byte *in_double::get_value(Item *item) +uchar *in_double::get_value(Item *item) { tmp= item->val_real(); if (item->null_value) return 0; /* purecov: inspected */ - return (byte*) &tmp; + return (uchar*) &tmp; } @@ -2930,12 +2970,12 @@ void in_decimal::set(uint pos, Item *item) } -byte *in_decimal::get_value(Item *item) +uchar *in_decimal::get_value(Item *item) { my_decimal *result= item->val_decimal(&val); if (item->null_value) return 0; - return (byte *)result; + return (uchar *)result; } @@ -3224,21 +3264,20 @@ static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y) void Item_func_in::fix_length_and_dec() { Item **arg, **arg_end; - uint const_itm= 1; + bool const_itm= 1; THD *thd= current_thd; bool datetime_found= FALSE; /* TRUE <=> arguments values will be compared as DATETIMEs. */ bool compare_as_datetime= FALSE; Item *date_arg= 0; - - if (agg_cmp_type(thd, &cmp_type, args, arg_count)) - return; - - if (cmp_type == STRING_RESULT && - agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1)) + uint found_types= 0; + uint type_cnt= 0, i; + Item_result cmp_type= STRING_RESULT; + left_result_type= args[0]->result_type(); + if (!(found_types= collect_cmp_types(args, arg_count))) return; - - for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++) + + for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++) { if (!arg[0]->const_item()) { @@ -3246,92 +3285,111 @@ void Item_func_in::fix_length_and_dec() break; } } - /* - When comparing rows create the row comparator object beforehand to ease - the DATETIME comparison detection procedure. - */ - if (cmp_type == ROW_RESULT) + for (i= 0; i <= (uint)DECIMAL_RESULT; i++) { - cmp_item_row *cmp= 0; - if (const_itm && !nulls_in_row()) - { - array= new in_row(arg_count-1, 0); - cmp= &((in_row*)array)->tmp; - } - else + if (found_types & 1 << i) { - if (!(cmp= new cmp_item_row)) - return; - in_item= cmp; + (type_cnt)++; + cmp_type= (Item_result) i; } - cmp->n= args[0]->cols(); - cmp->alloc_comparators(); } - /* All DATE/DATETIME fields/functions has the STRING result type. */ - if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT) - { - uint col, cols= args[0]->cols(); - for (col= 0; col < cols; col++) + if (type_cnt == 1) + { + if (cmp_type == STRING_RESULT && + agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1)) + return; + arg_types_compatible= TRUE; + } + if (type_cnt == 1) + { + /* + When comparing rows create the row comparator object beforehand to ease + the DATETIME comparison detection procedure. + */ + if (cmp_type == ROW_RESULT) { - bool skip_column= FALSE; - /* - Check that all items to be compared has the STRING result type and at - least one of them is a DATE/DATETIME item. - */ - for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++) + cmp_item_row *cmp= 0; + if (const_itm && !nulls_in_row()) { - Item *itm= ((cmp_type == STRING_RESULT) ? arg[0] : - arg[0]->element_index(col)); - if (itm->result_type() != STRING_RESULT) - { - skip_column= TRUE; - break; - } - else if (itm->is_datetime()) + array= new in_row(arg_count-1, 0); + cmp= &((in_row*)array)->tmp; + } + else + { + if (!(cmp= new cmp_item_row)) + return; + cmp_items[ROW_RESULT]= cmp; + } + cmp->n= args[0]->cols(); + cmp->alloc_comparators(); + } + /* All DATE/DATETIME fields/functions has the STRING result type. */ + if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT) + { + uint col, cols= args[0]->cols(); + + for (col= 0; col < cols; col++) + { + bool skip_column= FALSE; + /* + Check that all items to be compared has the STRING result type and at + least one of them is a DATE/DATETIME item. + */ + for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++) { - datetime_found= TRUE; - /* - Internally all DATE/DATETIME values are converted to the DATETIME - type. So try to find a DATETIME item to issue correct warnings. - */ - if (!date_arg) - date_arg= itm; - else if (itm->field_type() == MYSQL_TYPE_DATETIME) + Item *itm= ((cmp_type == STRING_RESULT) ? arg[0] : + arg[0]->element_index(col)); + if (itm->result_type() != STRING_RESULT) { - date_arg= itm; - /* All arguments are already checked to have the STRING result. */ - if (cmp_type == STRING_RESULT) - break; + skip_column= TRUE; + break; + } + else if (itm->is_datetime()) + { + datetime_found= TRUE; + /* + Internally all DATE/DATETIME values are converted to the DATETIME + type. So try to find a DATETIME item to issue correct warnings. + */ + if (!date_arg) + date_arg= itm; + else if (itm->field_type() == MYSQL_TYPE_DATETIME) + { + date_arg= itm; + /* All arguments are already checked to have the STRING result. */ + if (cmp_type == STRING_RESULT) + break; + } } } - } - if (skip_column) - continue; - if (datetime_found) - { - if (cmp_type == ROW_RESULT) + if (skip_column) + continue; + if (datetime_found) { - cmp_item **cmp= 0; - if (array) - cmp= ((in_row*)array)->tmp.comparators + col; + if (cmp_type == ROW_RESULT) + { + cmp_item **cmp= 0; + if (array) + cmp= ((in_row*)array)->tmp.comparators + col; + else + cmp= ((cmp_item_row*)cmp_items[ROW_RESULT])->comparators + col; + *cmp= new cmp_item_datetime(date_arg); + /* Reset variables for the next column. */ + date_arg= 0; + datetime_found= FALSE; + } else - cmp= ((cmp_item_row*)in_item)->comparators + col; - *cmp= new cmp_item_datetime(date_arg); - /* Reset variables for the next column. */ - date_arg= 0; - datetime_found= FALSE; + compare_as_datetime= TRUE; } - else - compare_as_datetime= TRUE; } } } /* - Row item with NULLs inside can return NULL or FALSE => + Row item with NULLs inside can return NULL or FALSE => they can't be processed as static */ - if (const_itm && !nulls_in_row()) + if (type_cnt == 1 && const_itm && !nulls_in_row()) { if (compare_as_datetime) array= new in_datetime(date_arg, arg_count - 1); @@ -3400,27 +3458,31 @@ void Item_func_in::fix_length_and_dec() else have_null= 1; } - if ((array->used_count=j)) + if ((array->used_count= j)) array->sort(); } } else { - if (in_item) + if (compare_as_datetime) + cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg); + else { - /* - The row comparator was created at the beginning but only DATETIME - items comparators were initialized. Call store_value() to setup - others. - */ - in_item->store_value(args[0]); + for (i= 0; i <= (uint) DECIMAL_RESULT; i++) + { + if (found_types & (1 << i) && !cmp_items[i]) + { + if ((Item_result)i == STRING_RESULT && + agg_arg_charsets(cmp_collation, args, arg_count, + MY_COLL_CMP_CONV, 1)) + return; + if (!cmp_items[i] && !(cmp_items[i]= + cmp_item::get_comparator((Item_result)i, + cmp_collation.collation))) + return; + } + } } - else if (compare_as_datetime) - in_item= new cmp_item_datetime(date_arg); - else - in_item= cmp_item::get_comparator(cmp_type, cmp_collation.collation); - if (cmp_type == STRING_RESULT) - in_item->cmp_charset= cmp_collation.collation; } max_length= 1; } @@ -3438,25 +3500,61 @@ void Item_func_in::print(String *str) } +/* + Evaluate the function and return its value. + + SYNOPSIS + val_int() + + DESCRIPTION + Evaluate the function and return its value. + + IMPLEMENTATION + If the array object is defined then the value of the function is + calculated by means of this array. + Otherwise several cmp_item objects are used in order to do correct + comparison of left expression and an expression from the values list. + One cmp_item object correspond to one used comparison type. Left + expression can be evaluated up to number of different used comparison + types. A bit mapped variable value_added_map is used to check whether + the left expression already was evaluated for a particular result type. + Result types are mapped to it according to their integer values i.e. + STRING_RESULT is mapped to bit 0, REAL_RESULT to bit 1, so on. + + RETURN + Value of the function +*/ + longlong Item_func_in::val_int() { + cmp_item *in_item; DBUG_ASSERT(fixed == 1); + uint value_added_map= 0; if (array) { int tmp=array->find(args[0]); null_value=args[0]->null_value || (!tmp && have_null); return (longlong) (!null_value && tmp != negated); } - in_item->store_value(args[0]); - if ((null_value=args[0]->null_value)) - return 0; - have_null= 0; - for (uint i=1 ; i < arg_count ; i++) + + for (uint i= 1 ; i < arg_count ; i++) { + Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type()); + in_item= cmp_items[(uint)cmp_type]; + DBUG_ASSERT(in_item); + if (!(value_added_map & (1 << (uint)cmp_type))) + { + in_item->store_value(args[0]); + if ((null_value=args[0]->null_value)) + return 0; + have_null= 0; + value_added_map|= 1 << (uint)cmp_type; + } if (!in_item->cmp(args[i]) && !args[i]->null_value) return (longlong) (!negated); have_null|= args[i]->null_value; } + null_value= have_null; return (longlong) (!null_value && negated); } @@ -3527,7 +3625,7 @@ Item_cond::fix_fields(THD *thd, Item **ref) List_iterator<Item> li(list); Item *item; #ifndef EMBEDDED_LIBRARY - char buff[sizeof(char*)]; // Max local vars in function + uchar buff[sizeof(char*)]; // Max local vars in function #endif not_null_tables_cache= used_tables_cache= 0; const_item_cache= 1; @@ -3594,14 +3692,14 @@ Item_cond::fix_fields(THD *thd, Item **ref) return FALSE; } -bool Item_cond::walk(Item_processor processor, byte *arg) +bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg) { List_iterator_fast<Item> li(list); Item *item; while ((item= li++)) - if (item->walk(processor, arg)) + if (item->walk(processor, walk_subquery, arg)) return 1; - return Item_func::walk(processor, arg); + return Item_func::walk(processor, walk_subquery, arg); } @@ -3626,7 +3724,7 @@ bool Item_cond::walk(Item_processor processor, byte *arg) Item returned as the result of transformation of the root node */ -Item *Item_cond::transform(Item_transformer transformer, byte *arg) +Item *Item_cond::transform(Item_transformer transformer, uchar *arg) { DBUG_ASSERT(!current_thd->is_stmt_prepare()); @@ -3677,8 +3775,8 @@ Item *Item_cond::transform(Item_transformer transformer, byte *arg) Item returned as the result of transformation of the root node */ -Item *Item_cond::compile(Item_analyzer analyzer, byte **arg_p, - Item_transformer transformer, byte *arg_t) +Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p, + Item_transformer transformer, uchar *arg_t) { if (!(this->*analyzer)(arg_p)) return 0; @@ -3691,7 +3789,7 @@ Item *Item_cond::compile(Item_analyzer analyzer, byte **arg_p, The same parameter value of arg_p must be passed to analyze any argument of the condition formula. */ - byte *arg_v= *arg_p; + uchar *arg_v= *arg_p; Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t); if (new_item && new_item != item) li.replace(new_item); @@ -3927,12 +4025,12 @@ longlong Item_is_not_null_test::val_int() if (!used_tables_cache && !with_subselect) { owner->was_null|= (!cached_value); - DBUG_PRINT("info", ("cached :%ld", (long) cached_value)); + DBUG_PRINT("info", ("cached: %ld", (long) cached_value)); DBUG_RETURN(cached_value); } if (args[0]->is_null()) { - DBUG_PRINT("info", ("null")) + DBUG_PRINT("info", ("null")); owner->was_null|= 1; DBUG_RETURN(0); } @@ -4925,17 +5023,19 @@ void Item_equal::fix_length_and_dec() item->collation.collation); } -bool Item_equal::walk(Item_processor processor, byte *arg) +bool Item_equal::walk(Item_processor processor, bool walk_subquery, uchar *arg) { List_iterator_fast<Item_field> it(fields); Item *item; while ((item= it++)) - if (item->walk(processor, arg)) + { + if (item->walk(processor, walk_subquery, arg)) return 1; - return Item_func::walk(processor, arg); + } + return Item_func::walk(processor, walk_subquery, arg); } -Item *Item_equal::transform(Item_transformer transformer, byte *arg) +Item *Item_equal::transform(Item_transformer transformer, uchar *arg) { DBUG_ASSERT(!current_thd->is_stmt_prepare()); |