Commit 265a7d16 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-20009 Add CAST(expr AS pluggable_type)

parent e37d7a37
......@@ -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
#
......@@ -170,6 +170,15 @@ SELECT CONTAINS(POINT(1,1),POINT(1,1));
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 #
......@@ -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
#
......@@ -3140,6 +3140,46 @@ SELECT WITHIN(POINT(1,1));
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
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 #
......@@ -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
#
......@@ -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
#
......@@ -18,6 +18,14 @@ SELECT CONTAINS(POINT(1,1),POINT(1,1));
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 #
......@@ -31,6 +31,46 @@ SELECT WITHIN(POINT(1,1));
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
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 #
......@@ -3103,12 +3103,15 @@ struct Lex_cast_type_st: public Lex_length_and_dec_st
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;
};
......
......@@ -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'"
......@@ -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;
}
......@@ -3723,7 +3723,6 @@ class Type_handler
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;
......
......@@ -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
......
......@@ -50,6 +50,9 @@ class Type_handler_geometry: public Type_handler_string_result
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)
......
......@@ -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:
......
......@@ -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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment