diff options
author | evgen@moonbone.local <> | 2005-08-05 00:34:42 +0400 |
---|---|---|
committer | evgen@moonbone.local <> | 2005-08-05 00:34:42 +0400 |
commit | 1894cff045ad75ca9b354840f1e9625ab653573c (patch) | |
tree | ea443ade0b265ff4d840c6bc185eb459f3a51c95 /sql | |
parent | 069fb89bb969108fd0d834301ce0e5eaf0bd6aaa (diff) | |
parent | fa0ea36507e886f270ce11ffea67af031febb88d (diff) | |
download | mariadb-git-1894cff045ad75ca9b354840f1e9625ab653573c.tar.gz |
Manual merge of #11335 bugfix
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_sum.cc | 16 | ||||
-rw-r--r-- | sql/sql_select.cc | 24 | ||||
-rw-r--r-- | sql/sql_union.cc | 8 |
3 files changed, 46 insertions, 2 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index b669a8c426d..bbcea4705fa 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -321,6 +321,22 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table, field->flags&= ~NOT_NULL_FLAG; return field; } + /* + DATE/TIME fields have STRING_RESULT result types. + In order to preserve field type, it's needed to handle DATE/TIME + fields creations separately. + */ + switch (args[0]->field_type()) { + case MYSQL_TYPE_DATE: + return new Field_date(maybe_null, name, table, collation.collation); + case MYSQL_TYPE_TIME: + return new Field_time(maybe_null, name, table, collation.collation); + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_DATETIME: + return new Field_datetime(maybe_null, name, table, collation.collation); + default: + break; + } return Item_sum::create_tmp_field(group, table, convert_blob_length); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c09a35c1fc0..33476979c7e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7944,7 +7944,15 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, item->name, table, item->unsigned_flag); break; case STRING_RESULT: - if (item->max_length > 255 && convert_blob_length) + enum enum_field_types type; + /* + DATE/TIME fields have STRING_RESULT result type. To preserve + type they needed to be handled separately. + */ + if ((type= item->field_type()) == MYSQL_TYPE_DATETIME || + type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE) + new_field= item->tmp_table_field_from_field_type(table); + else if (item->max_length > 255 && convert_blob_length) new_field= new Field_varstring(convert_blob_length, maybe_null, item->name, table, item->collation.collation); @@ -8055,6 +8063,20 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::DEFAULT_VALUE_ITEM: { Item_field *field= (Item_field*) item; + /* + If item have to be able to store NULLs but underlaid field can't do it, + create_tmp_field_from_field() can't be used for tmp field creation. + */ + if (field->maybe_null && !field->field->maybe_null()) + { + Field *res= create_tmp_field_from_item(thd, item, table, NULL, + modify_item, convert_blob_length); + *from_field= field->field; + if (res && modify_item) + ((Item_field*)item)->result_field= res; + return res; + } + if (table_cant_handle_bit_fields && field->field->type() == FIELD_TYPE_BIT) return create_tmp_field_from_item(thd, item, table, copy_func, diff --git a/sql/sql_union.cc b/sql/sql_union.cc index f2b637dc5f4..c414f5e9e72 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -235,7 +235,13 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, if ((res= (res || thd_arg->is_fatal_error))) goto err; - if (sl == first_select) + /* + Use items list of underlaid select for derived tables to preserve + information about fields lengths and exact types + */ + if (!is_union) + types= first_select_in_union()->item_list; + else if (sl == first_select) { /* We need to create an empty table object. It is used |