diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 190df1b9f5aaa..a03e8468ac38b 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -4354,24 +4354,7 @@ bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg) uint valpos= i * 2 + 1; DYNAMIC_COLUMN_TYPE type= defs[i].type; if (type == DYN_COL_NULL) - switch (args[valpos]->field_type()) - { - case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_GEOMETRY: - type= DYN_COL_STRING; - break; - default: - break; - } - + type= args[valpos]->type_handler()->dyncol_type(args[valpos]); if (type == DYN_COL_STRING && args[valpos]->type() == Item::FUNC_ITEM && ((Item_func *)args[valpos])->functype() == DYNCOL_FUNC) @@ -4388,63 +4371,7 @@ bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg) uint valpos= i * 2 + 1; DYNAMIC_COLUMN_TYPE type= defs[i].type; if (type == DYN_COL_NULL) // auto detect - { - /* - We don't have a default here to ensure we get a warning if - one adds a new not handled MYSQL_TYPE_... - */ - switch (args[valpos]->field_type()) { - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_NEWDECIMAL: - type= DYN_COL_DECIMAL; - break; - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_LONGLONG: - case MYSQL_TYPE_INT24: - case MYSQL_TYPE_YEAR: - case MYSQL_TYPE_BIT: - type= args[valpos]->unsigned_flag ? DYN_COL_UINT : DYN_COL_INT; - break; - case MYSQL_TYPE_FLOAT: - case MYSQL_TYPE_DOUBLE: - type= DYN_COL_DOUBLE; - break; - case MYSQL_TYPE_NULL: - type= DYN_COL_NULL; - break; - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_TIMESTAMP2: - case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_DATETIME2: - type= DYN_COL_DATETIME; - break; - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_NEWDATE: - type= DYN_COL_DATE; - break; - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_TIME2: - type= DYN_COL_TIME; - break; - case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_GEOMETRY: - type= DYN_COL_STRING; - break; - case MYSQL_TYPE_VARCHAR_COMPRESSED: - case MYSQL_TYPE_BLOB_COMPRESSED: - DBUG_ASSERT(0); - } - } + type= args[valpos]->type_handler()->dyncol_type(args[valpos]); if (type == DYN_COL_STRING && args[valpos]->type() == Item::FUNC_ITEM && ((Item_func *)args[valpos])->functype() == DYNCOL_FUNC) diff --git a/sql/sql_type.h b/sql/sql_type.h index 2a96e7ca6544c..fe39006138221 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -27,6 +27,9 @@ #include "sql_time.h" #include "sql_type_real.h" #include "compat56.h" +C_MODE_START +#include +C_MODE_END class Field; class Column_definition; @@ -3239,6 +3242,8 @@ class Type_handler virtual protocol_send_type_t protocol_send_type() const= 0; virtual Item_result result_type() const= 0; virtual Item_result cmp_type() const= 0; + virtual enum_dynamic_column_type + dyncol_type(const Type_all_attributes *attr) const= 0; virtual enum_mysql_timestamp_type mysql_timestamp_type() const { return MYSQL_TIMESTAMP_ERROR; @@ -3796,6 +3801,11 @@ class Type_handler_row: public Type_handler { return ROW_RESULT; } + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + DBUG_ASSERT(0); + return DYN_COL_NULL; + } const Type_handler *type_handler_for_comparison() const; int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const { @@ -4148,6 +4158,10 @@ class Type_handler_real_result: public Type_handler_numeric public: Item_result result_type() const { return REAL_RESULT; } Item_result cmp_type() const { return REAL_RESULT; } + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + return DYN_COL_DOUBLE; + } virtual ~Type_handler_real_result() {} const Type_handler *type_handler_for_comparison() const; void Column_definition_reuse_fix_attributes(THD *thd, @@ -4233,6 +4247,10 @@ class Type_handler_decimal_result: public Type_handler_numeric } Item_result result_type() const { return DECIMAL_RESULT; } Item_result cmp_type() const { return DECIMAL_RESULT; } + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + return DYN_COL_DECIMAL; + } virtual ~Type_handler_decimal_result() {}; const Type_handler *type_handler_for_comparison() const; int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const @@ -4463,6 +4481,10 @@ class Type_handler_int_result: public Type_handler_numeric public: Item_result result_type() const { return INT_RESULT; } Item_result cmp_type() const { return INT_RESULT; } + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + return attr->unsigned_flag ? DYN_COL_UINT : DYN_COL_INT; + } bool is_order_clause_position_type() const { return true; } bool is_limit_clause_valid_type() const { return true; } virtual ~Type_handler_int_result() {} @@ -4632,6 +4654,10 @@ class Type_handler_string_result: public Type_handler } Item_result result_type() const { return STRING_RESULT; } Item_result cmp_type() const { return STRING_RESULT; } + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + return DYN_COL_STRING; + } CHARSET_INFO *charset_for_protocol(const Item *item) const; virtual ~Type_handler_string_result() {} const Type_handler *type_handler_for_comparison() const; @@ -5260,6 +5286,10 @@ class Type_handler_time_common: public Type_handler_temporal_result const Name name() const { return m_name_time; } const Name &default_value() const; enum_field_types field_type() const { return MYSQL_TYPE_TIME; } + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + return DYN_COL_TIME; + } protocol_send_type_t protocol_send_type() const { return PROTOCOL_SEND_TIME; @@ -5426,6 +5456,10 @@ class Type_handler_date_common: public Type_handler_temporal_with_date const Name &default_value() const; const Type_handler *type_handler_for_comparison() const; enum_field_types field_type() const { return MYSQL_TYPE_DATE; } + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + return DYN_COL_DATE; + } protocol_send_type_t protocol_send_type() const { return PROTOCOL_SEND_DATE; @@ -5526,6 +5560,10 @@ class Type_handler_datetime_common: public Type_handler_temporal_with_date const Name &default_value() const; const Type_handler *type_handler_for_comparison() const; enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + return DYN_COL_DATETIME; + } protocol_send_type_t protocol_send_type() const { return PROTOCOL_SEND_DATETIME; @@ -5646,6 +5684,10 @@ class Type_handler_timestamp_common: public Type_handler_temporal_with_date const Type_handler *type_handler_for_comparison() const; const Type_handler *type_handler_for_native_format() const; enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; } + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + return DYN_COL_DATETIME; + } protocol_send_type_t protocol_send_type() const { return PROTOCOL_SEND_DATETIME; @@ -5843,6 +5885,10 @@ class Type_handler_null: public Type_handler_general_purpose_string virtual ~Type_handler_null() {} const Name name() const { return m_name_null; } enum_field_types field_type() const { return MYSQL_TYPE_NULL; } + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + return DYN_COL_NULL; + } const Type_handler *type_handler_for_comparison() const; const Type_handler *type_handler_for_tmp_table(const Item *item) const; const Type_handler *type_handler_for_union(const Item *) const; @@ -6021,6 +6067,11 @@ class Type_handler_varchar_compressed: public Type_handler_varchar public: Field *make_conversion_table_field(TABLE *, uint metadata, const Field *target) const; + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + DBUG_ASSERT(0); + return DYN_COL_STRING; + } }; @@ -6148,6 +6199,11 @@ class Type_handler_blob_compressed: public Type_handler_blob public: Field *make_conversion_table_field(TABLE *, uint metadata, const Field *target) const; + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) const + { + DBUG_ASSERT(0); + return DYN_COL_STRING; + } };