diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_func.h | 5 | ||||
-rw-r--r-- | sql/share/errmsg-utf8.txt | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 18 | ||||
-rw-r--r-- | sql/sql_type.h | 1 | ||||
-rw-r--r-- | sql/sql_type_geom.cc | 12 | ||||
-rw-r--r-- | sql/sql_type_geom.h | 3 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 14 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 14 |
8 files changed, 63 insertions, 6 deletions
diff --git a/sql/item_func.h b/sql/item_func.h index f47cd080f57..d1be46e41a7 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -3103,12 +3103,15 @@ public: set(handler, 0, 0); } const Type_handler *type_handler() const { return m_type_handler; } - Item *create_typecast_item(THD *thd, Item *item, CHARSET_INFO *cs= NULL) + Item *create_typecast_item(THD *thd, Item *item, + CHARSET_INFO *cs= NULL) const { return m_type_handler-> create_typecast_item(thd, item, Type_cast_attributes(length(), dec(), cs)); } + Item *create_typecast_item_or_error(THD *thd, Item *item, + CHARSET_INFO *cs= NULL) const; }; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 73877425360..0f68c726747 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7935,3 +7935,5 @@ ER_TOO_LONG_DATABASE_COMMENT eng "Comment for database '%-.64s' is too long (max = %u)" ER_UNKNOWN_DATA_TYPE eng "Unknown data type: '%-.64s'" +ER_UNKNOWN_OPERATOR + eng "Operator does not exists: '%-.128s'" diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5fc52d83a48..feda4cd23fb 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -10464,3 +10464,21 @@ Spvar_definition *LEX::row_field_name(THD *thd, const Lex_ident_sys_st &name) init_last_field(res, &name, thd->variables.collation_database); return res; } + + +Item * +Lex_cast_type_st::create_typecast_item_or_error(THD *thd, Item *item, + CHARSET_INFO *cs) const +{ + Item *tmp= create_typecast_item(thd, item, cs); + if (!tmp) + { + Name name= m_type_handler->name(); + char buf[128]; + size_t length= my_snprintf(buf, sizeof(buf), "CAST(expr AS %.*s)", + (int) name.length(), name.ptr()); + my_error(ER_UNKNOWN_OPERATOR, MYF(0), + ErrConvString(buf, length, system_charset_info).ptr()); + } + return tmp; +} diff --git a/sql/sql_type.h b/sql/sql_type.h index 73e6ab5924f..4ea3f860614 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -3723,7 +3723,6 @@ public: virtual Item *create_typecast_item(THD *thd, Item *item, const Type_cast_attributes &attr) const { - DBUG_ASSERT(0); return NULL; } virtual Item_copy *create_item_copy(THD *thd, Item *item) const; diff --git a/sql/sql_type_geom.cc b/sql/sql_type_geom.cc index 94ec69ae62c..4b8d8ab97be 100644 --- a/sql/sql_type_geom.cc +++ b/sql/sql_type_geom.cc @@ -318,6 +318,18 @@ bool Type_handler_geometry::Key_part_spec_init_spatial(Key_part_spec *part, } +Item * +Type_handler_geometry::create_typecast_item(THD *thd, Item *item, + const Type_cast_attributes &attr) + const +{ + DBUG_EXECUTE_IF("emulate_geometry_create_typecast_item", + return new (thd->mem_root) Item_func_geometry_from_text(thd, item); + ); + + return NULL; +} + bool Type_handler_point::Key_part_spec_init_primary(Key_part_spec *part, const Column_definition &def, const handler *file) const diff --git a/sql/sql_type_geom.h b/sql/sql_type_geom.h index 487bdaa53be..c27811cedf1 100644 --- a/sql/sql_type_geom.h +++ b/sql/sql_type_geom.h @@ -50,6 +50,9 @@ public: const Type_collection *type_collection() const override; const Type_handler *type_handler_for_comparison() const override; virtual geometry_types geometry_type() const { return GEOM_GEOMETRY; } + virtual Item *create_typecast_item(THD *thd, Item *item, + const Type_cast_attributes &attr) + const override; const Type_handler *type_handler_frm_unpack(const uchar *buffer) const override; bool is_binary_compatible_geom_super_type_for(const Type_handler_geometry *th) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 45cd5724c55..f490760a2ad 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -10277,7 +10277,8 @@ column_default_non_parenthesized_expr: } | CAST_SYM '(' expr AS cast_type ')' { - if (unlikely(!($$= $5.create_typecast_item(thd, $3, Lex->charset)))) + if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3, + Lex->charset)))) MYSQL_YYABORT; } | CASE_SYM when_list_opt_else END @@ -10293,7 +10294,8 @@ column_default_non_parenthesized_expr: } | CONVERT_SYM '(' expr ',' cast_type ')' { - if (unlikely(!($$= $5.create_typecast_item(thd, $3, Lex->charset)))) + if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3, + Lex->charset)))) MYSQL_YYABORT; } | CONVERT_SYM '(' expr USING charset_name ')' @@ -11700,6 +11702,14 @@ cast_type: } | cast_type_numeric { $$= $1; Lex->charset= NULL; } | cast_type_temporal { $$= $1; Lex->charset= NULL; } + | IDENT_sys + { + const Type_handler *h; + if (!(h= Type_handler::handler_by_name_or_error($1))) + MYSQL_YYABORT; + $$.set(h); + Lex->charset= NULL; + } ; cast_type_numeric: diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index f0ae0353d2b..52c223f891f 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -10377,7 +10377,8 @@ column_default_non_parenthesized_expr: } | CAST_SYM '(' expr AS cast_type ')' { - if (unlikely(!($$= $5.create_typecast_item(thd, $3, Lex->charset)))) + if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3, + Lex->charset)))) MYSQL_YYABORT; } | CASE_SYM when_list_opt_else END @@ -10393,7 +10394,8 @@ column_default_non_parenthesized_expr: } | CONVERT_SYM '(' expr ',' cast_type ')' { - if (unlikely(!($$= $5.create_typecast_item(thd, $3, Lex->charset)))) + if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3, + Lex->charset)))) MYSQL_YYABORT; } | CONVERT_SYM '(' expr USING charset_name ')' @@ -11800,6 +11802,14 @@ cast_type: } | cast_type_numeric { $$= $1; Lex->charset= NULL; } | cast_type_temporal { $$= $1; Lex->charset= NULL; } + | IDENT_sys + { + const Type_handler *h; + if (!(h= Type_handler::handler_by_name_or_error($1))) + MYSQL_YYABORT; + $$.set(h); + Lex->charset= NULL; + } ; cast_type_numeric: |