summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-07-10 11:55:16 +0400
committerAlexander Barkov <bar@mariadb.com>2019-07-10 11:55:16 +0400
commit265a7d1613d29e2bdd4c91a5a75971b331519dbe (patch)
treeb053ea8bc389ff1bd7a6a8d9a750cdc71c0d8f43
parente37d7a37151f1aa53e102d24af5d234c2ccfa392 (diff)
downloadmariadb-git-265a7d1613d29e2bdd4c91a5a75971b331519dbe.tar.gz
MDEV-20009 Add CAST(expr AS pluggable_type)
-rw-r--r--mysql-test/main/gis-debug.result8
-rw-r--r--mysql-test/main/gis-debug.test9
-rw-r--r--mysql-test/main/gis.result35
-rw-r--r--mysql-test/main/gis.test40
-rw-r--r--mysql-test/suite/compat/oracle/r/gis-debug.result8
-rw-r--r--mysql-test/suite/compat/oracle/r/gis.result35
-rw-r--r--mysql-test/suite/compat/oracle/t/gis-debug.test8
-rw-r--r--mysql-test/suite/compat/oracle/t/gis.test40
-rw-r--r--sql/item_func.h5
-rw-r--r--sql/share/errmsg-utf8.txt2
-rw-r--r--sql/sql_lex.cc18
-rw-r--r--sql/sql_type.h1
-rw-r--r--sql/sql_type_geom.cc12
-rw-r--r--sql/sql_type_geom.h3
-rw-r--r--sql/sql_yacc.yy14
-rw-r--r--sql/sql_yacc_ora.yy14
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: