diff options
author | unknown <evgen@sunlight.local> | 2007-09-24 17:23:40 +0400 |
---|---|---|
committer | unknown <evgen@sunlight.local> | 2007-09-24 17:23:40 +0400 |
commit | e4cbbcf8a970b854bfbc34f77571afdb0b247814 (patch) | |
tree | dff8e299e24252baed98de65a5a6435bbbfcf1c4 /sql | |
parent | c2c760bdb60eaa22165b518c209381010d489604 (diff) | |
parent | 17df0d648ca86d7074805228ba50d0f137b486d4 (diff) | |
download | mariadb-git-e4cbbcf8a970b854bfbc34f77571afdb0b247814.tar.gz |
Merge sunlight.local:/local_work/27216-bug-5.0-opt-mysql
into sunlight.local:/local_work/merge-5.1-opt-mysql
libmysql/libmysql.c:
Auto merged
mysql-test/r/date_formats.result:
Auto merged
mysql-test/r/insert_select.result:
Auto merged
mysql-test/t/insert_select.test:
Auto merged
sql/item_func.cc:
Auto merged
sql/item_func.h:
Auto merged
sql/item_timefunc.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/protocol.cc:
Auto merged
sql/sql_class.h:
Auto merged
mysql-test/r/type_datetime.result:
Manually merged
mysql-test/t/type_datetime.test:
Manually merged
sql/item_cmpfunc.cc:
Manually merged
sql/item_cmpfunc.h:
Manually merged
sql/sql_insert.cc:
Manually merged
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_cmpfunc.cc | 39 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 7 | ||||
-rw-r--r-- | sql/item_func.cc | 1 | ||||
-rw-r--r-- | sql/item_func.h | 4 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 2 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/protocol.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 17 |
9 files changed, 63 insertions, 11 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8f5ff050dd6..690661bc513 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -146,6 +146,35 @@ static int agg_cmp_type(Item_result *type, Item **items, uint nitems) } +/** + @brief Aggregates field types from the array of items. + + @param[in] items array of items to aggregate the type from + @paran[in] nitems number of items in the array + + @details This function aggregates field types from the array of items. + Found type is supposed to be used later as the result field type + of a multi-argument function. + Aggregation itself is performed by the Field::field_type_merge() + function. + + @note The term "aggregation" is used here in the sense of inferring the + result type of a function from its argument types. + + @return aggregated field type. +*/ + +enum_field_types agg_field_type(Item **items, uint nitems) +{ + uint i; + if (!nitems || items[0]->result_type() == ROW_RESULT ) + return (enum_field_types)-1; + enum_field_types res= items[0]->field_type(); + for (i= 1 ; i < nitems ; i++) + res= Field::field_type_merge(res, items[i]->field_type()); + return res; +} + /* Collects different types for comparison of first item with each other items @@ -2065,9 +2094,7 @@ Item_func_ifnull::fix_length_and_dec() default: DBUG_ASSERT(0); } - cached_field_type= args[0]->field_type(); - if (cached_field_type != args[1]->field_type()) - cached_field_type= Item_func::field_type(); + cached_field_type= agg_field_type(args, 2); } @@ -2215,11 +2242,13 @@ Item_func_if::fix_length_and_dec() { cached_result_type= arg2_type; collation.set(args[2]->collation.collation); + cached_field_type= args[2]->field_type(); } else if (null2) { cached_result_type= arg1_type; collation.set(args[1]->collation.collation); + cached_field_type= args[1]->field_type(); } else { @@ -2233,6 +2262,7 @@ Item_func_if::fix_length_and_dec() { collation.set(&my_charset_bin); // Number } + cached_field_type= agg_field_type(args + 1, 2); } if ((cached_result_type == DECIMAL_RESULT ) @@ -2582,7 +2612,7 @@ void Item_func_case::fix_length_and_dec() agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1)) return; - + cached_field_type= agg_field_type(agg, nagg); /* Aggregate first expression and all THEN expression types and collations when string comparison @@ -2751,6 +2781,7 @@ my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value) void Item_func_coalesce::fix_length_and_dec() { + cached_field_type= agg_field_type(args, arg_count); agg_result_type(&hybrid_type, args, arg_count); switch (hybrid_type) { case STRING_RESULT: diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 40d0c2dfe91..1a64f9c4211 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -640,6 +640,7 @@ public: class Item_func_coalesce :public Item_func_numhybrid { protected: + enum_field_types cached_field_type; Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {} public: Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {} @@ -652,13 +653,13 @@ public: enum Item_result result_type () const { return hybrid_type; } const char *func_name() const { return "coalesce"; } table_map not_null_tables() const { return 0; } + enum_field_types field_type() const { return cached_field_type; } }; class Item_func_ifnull :public Item_func_coalesce { protected: - enum_field_types cached_field_type; bool field_type_defined; public: Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {} @@ -677,6 +678,7 @@ public: class Item_func_if :public Item_func { enum Item_result cached_result_type; + enum_field_types cached_field_type; public: Item_func_if(Item *a,Item *b,Item *c) :Item_func(a,b,c), cached_result_type(INT_RESULT) @@ -686,6 +688,7 @@ public: String *val_str(String *str); my_decimal *val_decimal(my_decimal *); enum Item_result result_type () const { return cached_result_type; } + enum_field_types field_type() const { return cached_field_type; } bool fix_fields(THD *, Item **); void fix_length_and_dec(); uint decimal_precision() const; @@ -713,6 +716,7 @@ public: bool is_null(); }; + /* Functions to handle the optimized IN */ @@ -1442,6 +1446,7 @@ public: Item *transform(Item_transformer transformer, uchar *arg); void traverse_cond(Cond_traverser, void *arg, traverse_order order); void neg_arguments(THD *thd); + enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } bool subst_argument_checker(uchar **arg) { return TRUE; } Item *compile(Item_analyzer analyzer, uchar **arg_p, Item_transformer transformer, uchar *arg_t); diff --git a/sql/item_func.cc b/sql/item_func.cc index efc42c1b73f..6b1c0e340a5 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2238,6 +2238,7 @@ void Item_func_min_max::fix_length_and_dec() else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT)) max_length= my_decimal_precision_to_length(max_int_part+decimals, decimals, unsigned_flag); + cached_field_type= agg_field_type(args, arg_count); } diff --git a/sql/item_func.h b/sql/item_func.h index ea22e35773d..602c1c86f01 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -699,7 +699,8 @@ class Item_func_min_max :public Item_func /* An item used for issuing warnings while string to DATETIME conversion. */ Item *datetime_item; THD *thd; - +protected: + enum_field_types cached_field_type; public: Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list), cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg), compare_as_dates(FALSE), @@ -712,6 +713,7 @@ public: enum Item_result result_type () const { return cmp_type; } bool result_as_longlong() { return compare_as_dates; }; uint cmp_datetimes(ulonglong *value); + enum_field_types field_type() const { return cached_field_type; } }; class Item_func_min :public Item_func_min_max diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 300d0788f55..59e1777f542 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -3239,7 +3239,7 @@ void Item_func_str_to_date::fix_length_and_dec() String format_str(format_buff, sizeof(format_buff), &my_charset_bin), *format; maybe_null= 1; decimals=0; - cached_field_type= MYSQL_TYPE_STRING; + cached_field_type= MYSQL_TYPE_DATETIME; max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; cached_timestamp_type= MYSQL_TIMESTAMP_NONE; format= args[1]->val_str(&format_str); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 47a42354423..3aaee71bd42 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1673,6 +1673,7 @@ void flush_thread_cache(); /* item_func.cc */ extern bool check_reserved_words(LEX_STRING *name); +extern enum_field_types agg_field_type(Item **items, uint nitems); /* strfunc.cc */ ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs, diff --git a/sql/protocol.cc b/sql/protocol.cc index 2ed241c4c98..839109ef964 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -827,6 +827,7 @@ bool Protocol_text::store(const char *from, size_t length, field_types[field_pos] == MYSQL_TYPE_DECIMAL || field_types[field_pos] == MYSQL_TYPE_BIT || field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL || + field_types[field_pos] == MYSQL_TYPE_NEWDATE || (field_types[field_pos] >= MYSQL_TYPE_ENUM && field_types[field_pos] <= MYSQL_TYPE_GEOMETRY)); field_pos++; diff --git a/sql/sql_class.h b/sql/sql_class.h index 7875870bd1a..95338d7f151 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2107,7 +2107,7 @@ class select_insert :public select_result_interceptor { ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not COPY_INFO info; bool insert_into_view; - + bool is_bulk_insert_mode; select_insert(TABLE_LIST *table_list_par, TABLE *table_par, List<Item> *fields_par, List<Item> *update_fields, List<Item> *update_values, diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index ebbf4cafb19..4bac5f9c9da 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2778,7 +2778,8 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par, bool ignore_check_option_errors) :table_list(table_list_par), table(table_par), fields(fields_par), autoinc_value_of_last_inserted_row(0), - insert_into_view(table_list_par && table_list_par->view != 0) + insert_into_view(table_list_par && table_list_par->view != 0), + is_bulk_insert_mode(FALSE) { bzero((char*) &info,sizeof(info)); info.handle_duplicates= duplic; @@ -2964,8 +2965,11 @@ int select_insert::prepare2(void) { DBUG_ENTER("select_insert::prepare2"); if (thd->lex->current_select->options & OPTION_BUFFER_RESULT && - !thd->prelocked_mode) + !thd->prelocked_mode && !is_bulk_insert_mode) + { table->file->ha_start_bulk_insert((ha_rows) 0); + is_bulk_insert_mode= TRUE; + } DBUG_RETURN(0); } @@ -3084,6 +3088,7 @@ bool select_insert::send_eof() trans_table, table->file->table_type())); error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert():0; + is_bulk_insert_mode= FALSE; table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); @@ -3307,7 +3312,10 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, Create_field *cr_field; Field *field, *def_field; if (item->type() == Item::FUNC_ITEM) - field= item->tmp_table_field(&tmp_table); + if (item->result_type() != STRING_RESULT) + field= item->tmp_table_field(&tmp_table); + else + field= item->tmp_table_field_from_field_type(&tmp_table); else field= create_tmp_field(thd, &tmp_table, item, item->type(), (Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0, @@ -3518,7 +3526,10 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) if (info.handle_duplicates == DUP_UPDATE) table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE); if (!thd->prelocked_mode) + { table->file->ha_start_bulk_insert((ha_rows) 0); + is_bulk_insert_mode= TRUE; + } thd->abort_on_warning= (!info.ignore && (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | |