summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2017-09-29 22:44:07 +0400
committerAlexander Barkov <bar@mariadb.org>2017-09-29 22:44:07 +0400
commitca38b93e354baa5bbcaea00543dc1a99940072e4 (patch)
treee63f26bf9fcdd6da150dca779f2e109c90611728
parentdc41bc14e05dc7b8fa55e7f47e7930f3d28e27f8 (diff)
downloadmariadb-git-ca38b93e354baa5bbcaea00543dc1a99940072e4.tar.gz
MDEV-13965 Parameter data type control for Item_longlong_func
-rw-r--r--mysql-test/r/func_int.result37
-rw-r--r--mysql-test/r/gis.result31
-rw-r--r--mysql-test/suite/rpl/r/rpl_master_pos_wait.result13
-rw-r--r--mysql-test/suite/rpl/t/rpl_master_pos_wait.test18
-rw-r--r--mysql-test/t/func_int.test49
-rw-r--r--mysql-test/t/gis.test42
-rw-r--r--sql/item.cc22
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_func.cc26
-rw-r--r--sql/item_func.h14
-rw-r--r--sql/item_inetfunc.h2
-rw-r--r--sql/item_timefunc.h4
-rw-r--r--sql/sql_type.h6
13 files changed, 266 insertions, 0 deletions
diff --git a/mysql-test/r/func_int.result b/mysql-test/r/func_int.result
new file mode 100644
index 00000000000..1d4620ff6ac
--- /dev/null
+++ b/mysql-test/r/func_int.result
@@ -0,0 +1,37 @@
+#
+# Start of 10.3 tests
+#
+#
+# MDEV-13965 Parameter data type control for Item_longlong_func
+#
+SELECT ROW(1,1) | 1;
+ERROR HY000: Illegal parameter data type row for operation '|'
+SELECT 1 | ROW(1,1);
+ERROR HY000: Illegal parameter data type row for operation '|'
+SELECT ROW(1,1) & 1;
+ERROR HY000: Illegal parameter data type row for operation '&'
+SELECT 1 & ROW(1,1);
+ERROR HY000: Illegal parameter data type row for operation '&'
+SELECT ROW(1,1) << 1;
+ERROR HY000: Illegal parameter data type row for operation '<<'
+SELECT 1 << ROW(1,1);
+ERROR HY000: Illegal parameter data type row for operation '<<'
+SELECT ROW(1,1) >> 1;
+ERROR HY000: Illegal parameter data type row for operation '>>'
+SELECT 1 >> ROW(1,1);
+ERROR HY000: Illegal parameter data type row for operation '>>'
+SELECT ~ROW(1,1);
+ERROR HY000: Illegal parameter data type row for operation '~'
+SELECT TO_SECONDS(ROW(1,1));
+ERROR HY000: Illegal parameter data type row for operation 'to_seconds'
+SELECT TIMESTAMPDIFF(SECOND,ROW(1,1), 1);
+ERROR HY000: Illegal parameter data type row for operation 'timestampdiff'
+SELECT TIMESTAMPDIFF(SECOND,1, ROW(1,1));
+ERROR HY000: Illegal parameter data type row for operation 'timestampdiff'
+SELECT INET_ATON(ROW(1,1));
+ERROR HY000: Illegal parameter data type row for operation 'inet_aton'
+SELECT LAST_INSERT_ID(ROW(1,1));
+ERROR HY000: Illegal parameter data type row for operation 'last_insert_id'
+#
+# End of 10.3 tests
+#
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 35654cb4ede..ebcdb13a407 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -4755,5 +4755,36 @@ ERROR HY000: Illegal parameter data type row for operation 'radians'
SELECT DEGREES(ROW(1,1));
ERROR HY000: Illegal parameter data type row for operation 'degrees'
#
+# MDEV-13965 Parameter data type control for Item_longlong_func
+#
+SELECT POINT(1,1) | 1;
+ERROR HY000: Illegal parameter data type geometry for operation '|'
+SELECT 1 | POINT(1,1);
+ERROR HY000: Illegal parameter data type geometry for operation '|'
+SELECT POINT(1,1) & 1;
+ERROR HY000: Illegal parameter data type geometry for operation '&'
+SELECT 1 & POINT(1,1);
+ERROR HY000: Illegal parameter data type geometry for operation '&'
+SELECT POINT(1,1) << 1;
+ERROR HY000: Illegal parameter data type geometry for operation '<<'
+SELECT 1 << POINT(1,1);
+ERROR HY000: Illegal parameter data type geometry for operation '<<'
+SELECT POINT(1,1) >> 1;
+ERROR HY000: Illegal parameter data type geometry for operation '>>'
+SELECT 1 >> POINT(1,1);
+ERROR HY000: Illegal parameter data type geometry for operation '>>'
+SELECT ~POINT(1,1);
+ERROR HY000: Illegal parameter data type geometry for operation '~'
+SELECT TO_SECONDS(POINT(1,1));
+ERROR HY000: Illegal parameter data type geometry for operation 'to_seconds'
+SELECT TIMESTAMPDIFF(SECOND,POINT(1,1), 1);
+ERROR HY000: Illegal parameter data type geometry for operation 'timestampdiff'
+SELECT TIMESTAMPDIFF(SECOND,1, POINT(1,1));
+ERROR HY000: Illegal parameter data type geometry for operation 'timestampdiff'
+SELECT INET_ATON(POINT(1,1));
+ERROR HY000: Illegal parameter data type geometry for operation 'inet_aton'
+SELECT LAST_INSERT_ID(POINT(1,1));
+ERROR HY000: Illegal parameter data type geometry for operation 'last_insert_id'
+#
# End of 10.3 tests
#
diff --git a/mysql-test/suite/rpl/r/rpl_master_pos_wait.result b/mysql-test/suite/rpl/r/rpl_master_pos_wait.result
index 18298986069..04f55fc1263 100644
--- a/mysql-test/suite/rpl/r/rpl_master_pos_wait.result
+++ b/mysql-test/suite/rpl/r/rpl_master_pos_wait.result
@@ -45,4 +45,17 @@ master_pos_wait('master-bin.000001',1000000,1,"my_slave")
STOP SLAVE 'my_slave';
RESET SLAVE 'my_slave' ALL;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
+#
+# Start of 10.3 tests
+#
+#
+# MDEV-13965 Parameter data type control for Item_longlong_func
+#
+SELECT MASTER_POS_WAIT('x',1,ROW(1,1));
+ERROR HY000: Illegal parameter data type row for operation 'master_pos_wait'
+SELECT MASTER_POS_WAIT('x',1,1,ROW(1,1));
+ERROR HY000: Illegal parameter data type row for operation 'master_pos_wait'
+#
+# End of 10.3 tests
+#
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_master_pos_wait.test b/mysql-test/suite/rpl/t/rpl_master_pos_wait.test
index a3f3ff56464..d8c8162ed9f 100644
--- a/mysql-test/suite/rpl/t/rpl_master_pos_wait.test
+++ b/mysql-test/suite/rpl/t/rpl_master_pos_wait.test
@@ -56,5 +56,23 @@ eval change master to master_port=$MASTER_MYPORT, master_host='127.0.0.1', maste
# End of 10.0 tests
+--echo #
+--echo # Start of 10.3 tests
+--echo #
+
+--echo #
+--echo # MDEV-13965 Parameter data type control for Item_longlong_func
+--echo #
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT MASTER_POS_WAIT('x',1,ROW(1,1));
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT MASTER_POS_WAIT('x',1,1,ROW(1,1));
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
+
+
--let $rpl_only_running_threads= 1
--source include/rpl_end.inc
diff --git a/mysql-test/t/func_int.test b/mysql-test/t/func_int.test
new file mode 100644
index 00000000000..dac3d936f53
--- /dev/null
+++ b/mysql-test/t/func_int.test
@@ -0,0 +1,49 @@
+--echo #
+--echo # Start of 10.3 tests
+--echo #
+
+
+--echo #
+--echo # MDEV-13965 Parameter data type control for Item_longlong_func
+--echo #
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT ROW(1,1) | 1;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT 1 | ROW(1,1);
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT ROW(1,1) & 1;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT 1 & ROW(1,1);
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT ROW(1,1) << 1;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT 1 << ROW(1,1);
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT ROW(1,1) >> 1;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT 1 >> ROW(1,1);
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT ~ROW(1,1);
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT TO_SECONDS(ROW(1,1));
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT TIMESTAMPDIFF(SECOND,ROW(1,1), 1);
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT TIMESTAMPDIFF(SECOND,1, ROW(1,1));
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT INET_ATON(ROW(1,1));
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT LAST_INSERT_ID(ROW(1,1));
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index a3498da8ee2..79310ccf692 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -2795,5 +2795,47 @@ SELECT DEGREES(ROW(1,1));
--echo #
+--echo # MDEV-13965 Parameter data type control for Item_longlong_func
+--echo #
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT POINT(1,1) | 1;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT 1 | POINT(1,1);
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT POINT(1,1) & 1;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT 1 & POINT(1,1);
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT POINT(1,1) << 1;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT 1 << POINT(1,1);
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT POINT(1,1) >> 1;
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT 1 >> POINT(1,1);
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT ~POINT(1,1);
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT TO_SECONDS(POINT(1,1));
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT TIMESTAMPDIFF(SECOND,POINT(1,1), 1);
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT TIMESTAMPDIFF(SECOND,1, POINT(1,1));
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT INET_ATON(POINT(1,1));
+
+--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
+SELECT LAST_INSERT_ID(POINT(1,1));
+
+
+--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/sql/item.cc b/sql/item.cc
index ce9f258612e..840ab12a7ce 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1080,6 +1080,28 @@ bool Item::check_type_can_return_real(const char *opname) const
}
+bool Item::check_type_can_return_date(const char *opname) const
+{
+ const Type_handler *handler= type_handler();
+ if (handler->can_return_date())
+ return false;
+ my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0),
+ handler->name().ptr(), opname);
+ return true;
+}
+
+
+bool Item::check_type_can_return_str_ascii(const char *opname) const
+{
+ const Type_handler *handler= type_handler();
+ if (handler->can_return_str_ascii())
+ return false;
+ my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0),
+ handler->name().ptr(), opname);
+ return true;
+}
+
+
bool Item::check_type_scalar(const char *opname) const
{
const Type_handler *handler= type_handler();
diff --git a/sql/item.h b/sql/item.h
index 13f6f2019e4..6d918999e73 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1711,6 +1711,8 @@ public:
bool check_type_general_purpose_string(const char *opname) const;
bool check_type_can_return_int(const char *opname) const;
bool check_type_can_return_real(const char *opname) const;
+ bool check_type_can_return_str_ascii(const char *opname) const;
+ bool check_type_can_return_date(const char *opname) const;
// It is not row => null inside is impossible
virtual bool null_inside() { return 0; }
// used in row subselects to get value of elements
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 869b5311445..5157c01348e 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -218,6 +218,32 @@ bool Item_func::check_argument_types_can_return_real(uint start,
}
+bool Item_func::check_argument_types_can_return_str_ascii(uint start,
+ uint end) const
+{
+ for (uint i= start; i < end ; i++)
+ {
+ DBUG_ASSERT(i < arg_count);
+ if (args[i]->check_type_can_return_str_ascii(func_name()))
+ return true;
+ }
+ return false;
+}
+
+
+bool Item_func::check_argument_types_can_return_date(uint start,
+ uint end) const
+{
+ for (uint i= start; i < end ; i++)
+ {
+ DBUG_ASSERT(i < arg_count);
+ if (args[i]->check_type_can_return_date(func_name()))
+ return true;
+ }
+ return false;
+}
+
+
bool Item_func::check_argument_types_scalar(uint start, uint end) const
{
for (uint i= start; i < end; i++)
diff --git a/sql/item_func.h b/sql/item_func.h
index f7a80d85467..6d59cae616e 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -48,6 +48,8 @@ protected:
uint start, uint end) const;
bool check_argument_types_can_return_int(uint start, uint end) const;
bool check_argument_types_can_return_real(uint start, uint end) const;
+ bool check_argument_types_can_return_str_ascii(uint start, uint end) const;
+ bool check_argument_types_can_return_date(uint start, uint end) const;
public:
table_map not_null_tables_cache;
@@ -1742,6 +1744,8 @@ public:
class Item_func_bit: public Item_longlong_func
{
+ bool check_arguments() const
+ { return check_argument_types_can_return_int(0, arg_count); }
public:
Item_func_bit(THD *thd, Item *a, Item *b): Item_longlong_func(thd, a, b) {}
Item_func_bit(THD *thd, Item *a): Item_longlong_func(thd, a) {}
@@ -1828,6 +1832,8 @@ public:
class Item_func_last_insert_id :public Item_longlong_func
{
+ bool check_arguments() const
+ { return check_argument_types_can_return_int(0, arg_count); }
public:
Item_func_last_insert_id(THD *thd): Item_longlong_func(thd) {}
Item_func_last_insert_id(THD *thd, Item *a): Item_longlong_func(thd, a) {}
@@ -2199,6 +2205,14 @@ public:
class Item_master_pos_wait :public Item_longlong_func
{
+ bool check_arguments() const
+ {
+ return
+ args[0]->check_type_general_purpose_string(func_name()) ||
+ args[1]->check_type_can_return_int(func_name()) ||
+ (arg_count > 2 && args[2]->check_type_can_return_int(func_name())) ||
+ (arg_count > 3 && args[3]->check_type_general_purpose_string(func_name()));
+ }
String value;
public:
Item_master_pos_wait(THD *thd, Item *a, Item *b)
diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h
index 33586c29175..5d24835a625 100644
--- a/sql/item_inetfunc.h
+++ b/sql/item_inetfunc.h
@@ -26,6 +26,8 @@
class Item_func_inet_aton : public Item_longlong_func
{
+ bool check_arguments() const
+ { return check_argument_types_can_return_str_ascii(0, arg_count); }
public:
Item_func_inet_aton(THD *thd, Item *a): Item_longlong_func(thd, a) {}
longlong val_int();
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 20ecb4774b3..cd67e900efe 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -91,6 +91,8 @@ public:
class Item_func_to_seconds :public Item_longlong_func
{
+ bool check_arguments() const
+ { return check_argument_types_can_return_date(0, arg_count); }
public:
Item_func_to_seconds(THD *thd, Item *a): Item_longlong_func(thd, a) {}
longlong val_int();
@@ -1214,6 +1216,8 @@ public:
class Item_func_timestamp_diff :public Item_longlong_func
{
+ bool check_arguments() const
+ { return check_argument_types_can_return_date(0, arg_count); }
const interval_type int_type;
public:
Item_func_timestamp_diff(THD *thd, Item *a, Item *b, interval_type type_arg):
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 57737662c48..63351cb26c3 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -705,6 +705,8 @@ public:
virtual bool is_scalar_type() const { return true; }
virtual bool can_return_int() const { return true; }
virtual bool can_return_real() const { return true; }
+ virtual bool can_return_str_ascii() const { return true; }
+ virtual bool can_return_date() const { return true; }
virtual bool is_general_purpose_string_type() const { return false; }
virtual uint Item_time_precision(Item *item) const;
virtual uint Item_datetime_precision(Item *item) const;
@@ -1002,6 +1004,8 @@ public:
bool is_scalar_type() const { return false; }
bool can_return_int() const { return false; }
bool can_return_real() const { return false; }
+ bool can_return_str_ascii() const { return false; }
+ bool can_return_date() const { return false; }
enum_field_types field_type() const
{
DBUG_ASSERT(0);
@@ -2674,6 +2678,8 @@ public:
bool can_return_int() const { return false; }
bool can_return_real() const { return false; }
+ bool can_return_str_ascii() const { return false; }
+ bool can_return_date() const { return false; }
bool is_traditional_type() const
{
return false;