diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-07-10 11:55:16 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-07-10 11:55:16 +0400 |
commit | 265a7d1613d29e2bdd4c91a5a75971b331519dbe (patch) | |
tree | b053ea8bc389ff1bd7a6a8d9a750cdc71c0d8f43 | |
parent | e37d7a37151f1aa53e102d24af5d234c2ccfa392 (diff) | |
download | mariadb-git-265a7d1613d29e2bdd4c91a5a75971b331519dbe.tar.gz |
MDEV-20009 Add CAST(expr AS pluggable_type)
-rw-r--r-- | mysql-test/main/gis-debug.result | 8 | ||||
-rw-r--r-- | mysql-test/main/gis-debug.test | 9 | ||||
-rw-r--r-- | mysql-test/main/gis.result | 35 | ||||
-rw-r--r-- | mysql-test/main/gis.test | 40 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/r/gis-debug.result | 8 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/r/gis.result | 35 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/t/gis-debug.test | 8 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/t/gis.test | 40 | ||||
-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 |
16 files changed, 246 insertions, 6 deletions
diff --git a/mysql-test/main/gis-debug.result b/mysql-test/main/gis-debug.result index 8935c256068..f490a720ecf 100644 --- a/mysql-test/main/gis-debug.result +++ b/mysql-test/main/gis-debug.result @@ -502,5 +502,13 @@ SELECT WITHIN(POINT(1,1),POINT(1,1)); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(POINT(1,1),POINT(1,1))' at line 1 SET SESSION debug_dbug="-d,make_item_func_call_native_simulate_not_found"; # +# MDEV-20009 Add CAST(expr AS pluggable_type) +# +SET SESSION debug_dbug="+d,emulate_geometry_create_typecast_item"; +SELECT AsText(CAST('POINT(0 0)' AS GEOMETRY)); +AsText(CAST('POINT(0 0)' AS GEOMETRY)) +POINT(0 0) +SET SESSION debug_dbug="-d,emulate_geometry_create_typecast_item"; +# # End of 10.5 tests # diff --git a/mysql-test/main/gis-debug.test b/mysql-test/main/gis-debug.test index 47eda47c7ff..dd1cbd0b932 100644 --- a/mysql-test/main/gis-debug.test +++ b/mysql-test/main/gis-debug.test @@ -171,5 +171,14 @@ SELECT WITHIN(POINT(1,1),POINT(1,1)); SET SESSION debug_dbug="-d,make_item_func_call_native_simulate_not_found"; --echo # +--echo # MDEV-20009 Add CAST(expr AS pluggable_type) +--echo # + +SET SESSION debug_dbug="+d,emulate_geometry_create_typecast_item"; +SELECT AsText(CAST('POINT(0 0)' AS GEOMETRY)); +SET SESSION debug_dbug="-d,emulate_geometry_create_typecast_item"; + + +--echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/gis.result b/mysql-test/main/gis.result index 2ba2a9d71c5..c01eda308ba 100644 --- a/mysql-test/main/gis.result +++ b/mysql-test/main/gis.result @@ -5056,5 +5056,40 @@ ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(PO SELECT WITHIN(POINT(1,1), POINT(1,1), POINT(1,1)); ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(POINT(1,1), POINT(1,1), POINT(1,1))' # +# MDEV-20009 Add CAST(expr AS pluggable_type) +# +SELECT CAST(1 AS GEOMETRY); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometry)' +SELECT CAST(1 AS GEOMETRYCOLLECTION); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometrycollection)' +SELECT CAST(1 AS POINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS point)' +SELECT CAST(1 AS LINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS linestring)' +SELECT CAST(1 AS POLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS polygon)' +SELECT CAST(1 AS MULTIPOINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipoint)' +SELECT CAST(1 AS MULTILINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS multilinestring)' +SELECT CAST(1 AS MULTIPOLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipolygon)' +SELECT CONVERT(1, GEOMETRY); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometry)' +SELECT CONVERT(1, GEOMETRYCOLLECTION); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometrycollection)' +SELECT CONVERT(1, POINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS point)' +SELECT CONVERT(1, LINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS linestring)' +SELECT CONVERT(1, POLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS polygon)' +SELECT CONVERT(1, MULTIPOINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipoint)' +SELECT CONVERT(1, MULTILINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS multilinestring)' +SELECT CONVERT(1, MULTIPOLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipolygon)' +# # End of 10.5 tests # diff --git a/mysql-test/main/gis.test b/mysql-test/main/gis.test index a48fd8cf019..48f2803b27d 100644 --- a/mysql-test/main/gis.test +++ b/mysql-test/main/gis.test @@ -3141,5 +3141,45 @@ SELECT WITHIN(POINT(1,1)); SELECT WITHIN(POINT(1,1), POINT(1,1), POINT(1,1)); --echo # +--echo # MDEV-20009 Add CAST(expr AS pluggable_type) +--echo # + +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS GEOMETRY); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS GEOMETRYCOLLECTION); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS POINT); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS LINESTRING); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS POLYGON); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS MULTIPOINT); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS MULTILINESTRING); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS MULTIPOLYGON); + + +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, GEOMETRY); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, GEOMETRYCOLLECTION); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, POINT); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, LINESTRING); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, POLYGON); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, MULTIPOINT); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, MULTILINESTRING); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, MULTIPOLYGON); + + +--echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/suite/compat/oracle/r/gis-debug.result b/mysql-test/suite/compat/oracle/r/gis-debug.result index cf686ba4d34..9ab74e6e579 100644 --- a/mysql-test/suite/compat/oracle/r/gis-debug.result +++ b/mysql-test/suite/compat/oracle/r/gis-debug.result @@ -12,5 +12,13 @@ SELECT WITHIN(POINT(1,1),POINT(1,1)); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(POINT(1,1),POINT(1,1))' at line 1 SET SESSION debug_dbug="-d,make_item_func_call_native_simulate_not_found"; # +# MDEV-20009 Add CAST(expr AS pluggable_type) +# +SET SESSION debug_dbug="+d,emulate_geometry_create_typecast_item"; +SELECT AsText(CAST('POINT(0 0)' AS GEOMETRY)); +AsText(CAST('POINT(0 0)' AS GEOMETRY)) +POINT(0 0) +SET SESSION debug_dbug="-d,emulate_geometry_create_typecast_item"; +# # End of 10.5 tests # diff --git a/mysql-test/suite/compat/oracle/r/gis.result b/mysql-test/suite/compat/oracle/r/gis.result index f8d5ff994cd..113cb0ea402 100644 --- a/mysql-test/suite/compat/oracle/r/gis.result +++ b/mysql-test/suite/compat/oracle/r/gis.result @@ -30,5 +30,40 @@ ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(PO SELECT WITHIN(POINT(1,1), POINT(1,1), POINT(1,1)); ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(POINT(1,1), POINT(1,1), POINT(1,1))' # +# MDEV-20009 Add CAST(expr AS pluggable_type) +# +SELECT CAST(1 AS GEOMETRY); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometry)' +SELECT CAST(1 AS GEOMETRYCOLLECTION); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometrycollection)' +SELECT CAST(1 AS POINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS point)' +SELECT CAST(1 AS LINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS linestring)' +SELECT CAST(1 AS POLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS polygon)' +SELECT CAST(1 AS MULTIPOINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipoint)' +SELECT CAST(1 AS MULTILINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS multilinestring)' +SELECT CAST(1 AS MULTIPOLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipolygon)' +SELECT CONVERT(1, GEOMETRY); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometry)' +SELECT CONVERT(1, GEOMETRYCOLLECTION); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometrycollection)' +SELECT CONVERT(1, POINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS point)' +SELECT CONVERT(1, LINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS linestring)' +SELECT CONVERT(1, POLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS polygon)' +SELECT CONVERT(1, MULTIPOINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipoint)' +SELECT CONVERT(1, MULTILINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS multilinestring)' +SELECT CONVERT(1, MULTIPOLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipolygon)' +# # End of 10.5 tests # diff --git a/mysql-test/suite/compat/oracle/t/gis-debug.test b/mysql-test/suite/compat/oracle/t/gis-debug.test index ba01449b2cf..6053e546211 100644 --- a/mysql-test/suite/compat/oracle/t/gis-debug.test +++ b/mysql-test/suite/compat/oracle/t/gis-debug.test @@ -19,5 +19,13 @@ SELECT WITHIN(POINT(1,1),POINT(1,1)); SET SESSION debug_dbug="-d,make_item_func_call_native_simulate_not_found"; --echo # +--echo # MDEV-20009 Add CAST(expr AS pluggable_type) +--echo # + +SET SESSION debug_dbug="+d,emulate_geometry_create_typecast_item"; +SELECT AsText(CAST('POINT(0 0)' AS GEOMETRY)); +SET SESSION debug_dbug="-d,emulate_geometry_create_typecast_item"; + +--echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/suite/compat/oracle/t/gis.test b/mysql-test/suite/compat/oracle/t/gis.test index 74d0f7f6ee5..cb1b869035a 100644 --- a/mysql-test/suite/compat/oracle/t/gis.test +++ b/mysql-test/suite/compat/oracle/t/gis.test @@ -32,5 +32,45 @@ SELECT WITHIN(POINT(1,1)); SELECT WITHIN(POINT(1,1), POINT(1,1), POINT(1,1)); --echo # +--echo # MDEV-20009 Add CAST(expr AS pluggable_type) +--echo # + +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS GEOMETRY); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS GEOMETRYCOLLECTION); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS POINT); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS LINESTRING); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS POLYGON); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS MULTIPOINT); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS MULTILINESTRING); +--error ER_UNKNOWN_OPERATOR +SELECT CAST(1 AS MULTIPOLYGON); + + +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, GEOMETRY); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, GEOMETRYCOLLECTION); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, POINT); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, LINESTRING); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, POLYGON); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, MULTIPOINT); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, MULTILINESTRING); +--error ER_UNKNOWN_OPERATOR +SELECT CONVERT(1, MULTIPOLYGON); + + +--echo # --echo # End of 10.5 tests --echo # 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: |