summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorevgen@moonbone.local <>2005-08-05 00:34:42 +0400
committerevgen@moonbone.local <>2005-08-05 00:34:42 +0400
commit1894cff045ad75ca9b354840f1e9625ab653573c (patch)
treeea443ade0b265ff4d840c6bc185eb459f3a51c95 /sql
parent069fb89bb969108fd0d834301ce0e5eaf0bd6aaa (diff)
parentfa0ea36507e886f270ce11ffea67af031febb88d (diff)
downloadmariadb-git-1894cff045ad75ca9b354840f1e9625ab653573c.tar.gz
Manual merge of #11335 bugfix
Diffstat (limited to 'sql')
-rw-r--r--sql/item_sum.cc16
-rw-r--r--sql/sql_select.cc24
-rw-r--r--sql/sql_union.cc8
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