diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-09-30 11:17:19 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-09-30 11:17:19 +0400 |
commit | aa582dedcbd22182e06355b94d1de4fc62f71910 (patch) | |
tree | 647fdbdaba6cc1baad1ea133fb7590cb30904d0d | |
parent | ca38b93e354baa5bbcaea00543dc1a99940072e4 (diff) | |
download | mariadb-git-aa582dedcbd22182e06355b94d1de4fc62f71910.tar.gz |
MDEV-13966 Parameter data type control for Item_temporal_func
-rw-r--r-- | mysql-test/r/func_time.result | 31 | ||||
-rw-r--r-- | mysql-test/r/gis.result | 31 | ||||
-rw-r--r-- | mysql-test/t/func_time.test | 41 | ||||
-rw-r--r-- | mysql-test/t/gis.test | 41 | ||||
-rw-r--r-- | sql/item.cc | 22 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 13 | ||||
-rw-r--r-- | sql/item_func.h | 1 | ||||
-rw-r--r-- | sql/item_timefunc.h | 22 | ||||
-rw-r--r-- | sql/sql_type.h | 6 |
10 files changed, 210 insertions, 0 deletions
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index fb0179026c9..9da6caef8e6 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -3294,3 +3294,34 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; SET sql_mode=DEFAULT; +# +# MDEV-13966 Parameter data type control for Item_temporal_func +# +SELECT FROM_DAYS(ROW(1,1)); +ERROR HY000: Illegal parameter data type row for operation 'from_days' +SELECT MAKEDATE(ROW(1,1),1); +ERROR HY000: Illegal parameter data type row for operation 'makedate' +SELECT MAKEDATE(1, ROW(1,1)); +ERROR HY000: Illegal parameter data type row for operation 'makedate' +SELECT LAST_DAY(ROW(1,1)); +ERROR HY000: Illegal parameter data type row for operation 'last_day' +SELECT SEC_TO_TIME(ROW(1,1)); +ERROR HY000: Illegal parameter data type row for operation 'sec_to_time' +SELECT TIMEDIFF(ROW(1,1),1); +ERROR HY000: Illegal parameter data type row for operation 'timediff' +SELECT TIMEDIFF(1, ROW(1,1)); +ERROR HY000: Illegal parameter data type row for operation 'timediff' +SELECT MAKETIME(ROW(1,1),1,1); +ERROR HY000: Illegal parameter data type row for operation 'maketime' +SELECT MAKETIME(1, ROW(1,1), 1); +ERROR HY000: Illegal parameter data type row for operation 'maketime' +SELECT MAKETIME(1, 1, ROW(1,1)); +ERROR HY000: Illegal parameter data type row for operation 'maketime' +SELECT FROM_UNIXTIME(ROW(1,1)); +ERROR HY000: Illegal parameter data type row for operation 'from_unixtime' +SELECT CONVERT_TZ(ROW(1,1),1,1); +ERROR HY000: Illegal parameter data type row for operation 'convert_tz' +SELECT CONVERT_TZ(1, ROW(1,1), 1); +ERROR HY000: Illegal parameter data type row for operation 'convert_tz' +SELECT CONVERT_TZ(1, 1, ROW(1,1)); +ERROR HY000: Illegal parameter data type row for operation 'convert_tz' diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index ebcdb13a407..ecc29bbb659 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -4786,5 +4786,36 @@ 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' # +# MDEV-13966 Parameter data type control for Item_temporal_func +# +SELECT FROM_DAYS(POINT(1,1)); +ERROR HY000: Illegal parameter data type geometry for operation 'from_days' +SELECT MAKEDATE(POINT(1,1),1); +ERROR HY000: Illegal parameter data type geometry for operation 'makedate' +SELECT MAKEDATE(1, POINT(1,1)); +ERROR HY000: Illegal parameter data type geometry for operation 'makedate' +SELECT LAST_DAY(POINT(1,1)); +ERROR HY000: Illegal parameter data type geometry for operation 'last_day' +SELECT SEC_TO_TIME(POINT(1,1)); +ERROR HY000: Illegal parameter data type geometry for operation 'sec_to_time' +SELECT TIMEDIFF(POINT(1,1),1); +ERROR HY000: Illegal parameter data type geometry for operation 'timediff' +SELECT TIMEDIFF(1, POINT(1,1)); +ERROR HY000: Illegal parameter data type geometry for operation 'timediff' +SELECT MAKETIME(POINT(1,1),1,1); +ERROR HY000: Illegal parameter data type geometry for operation 'maketime' +SELECT MAKETIME(1, POINT(1,1), 1); +ERROR HY000: Illegal parameter data type geometry for operation 'maketime' +SELECT MAKETIME(1, 1, POINT(1,1)); +ERROR HY000: Illegal parameter data type geometry for operation 'maketime' +SELECT FROM_UNIXTIME(POINT(1,1)); +ERROR HY000: Illegal parameter data type geometry for operation 'from_unixtime' +SELECT CONVERT_TZ(POINT(1,1),1,1); +ERROR HY000: Illegal parameter data type geometry for operation 'convert_tz' +SELECT CONVERT_TZ(1, POINT(1,1), 1); +ERROR HY000: Illegal parameter data type geometry for operation 'convert_tz' +SELECT CONVERT_TZ(1, 1, POINT(1,1)); +ERROR HY000: Illegal parameter data type geometry for operation 'convert_tz' +# # End of 10.3 tests # diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index a3f542aaf57..3c154a8f67e 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -1880,3 +1880,44 @@ CREATE TABLE t1 AS SELECT TO_SECONDS('9999-12-31 23:59:59'); SHOW CREATE TABLE t1; DROP TABLE t1; SET sql_mode=DEFAULT; + + +--echo # +--echo # MDEV-13966 Parameter data type control for Item_temporal_func +--echo # + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT FROM_DAYS(ROW(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MAKEDATE(ROW(1,1),1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MAKEDATE(1, ROW(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT LAST_DAY(ROW(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT SEC_TO_TIME(ROW(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT TIMEDIFF(ROW(1,1),1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT TIMEDIFF(1, ROW(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MAKETIME(ROW(1,1),1,1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MAKETIME(1, ROW(1,1), 1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MAKETIME(1, 1, ROW(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT FROM_UNIXTIME(ROW(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT CONVERT_TZ(ROW(1,1),1,1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT CONVERT_TZ(1, ROW(1,1), 1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT CONVERT_TZ(1, 1, ROW(1,1)); diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 79310ccf692..b746ec2abfc 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -2837,5 +2837,46 @@ SELECT LAST_INSERT_ID(POINT(1,1)); --echo # +--echo # MDEV-13966 Parameter data type control for Item_temporal_func +--echo # + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT FROM_DAYS(POINT(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MAKEDATE(POINT(1,1),1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MAKEDATE(1, POINT(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT LAST_DAY(POINT(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT SEC_TO_TIME(POINT(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT TIMEDIFF(POINT(1,1),1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT TIMEDIFF(1, POINT(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MAKETIME(POINT(1,1),1,1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MAKETIME(1, POINT(1,1), 1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MAKETIME(1, 1, POINT(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT FROM_UNIXTIME(POINT(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT CONVERT_TZ(POINT(1,1),1,1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT CONVERT_TZ(1, POINT(1,1), 1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT CONVERT_TZ(1, 1, POINT(1,1)); + + +--echo # --echo # End of 10.3 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 840ab12a7ce..c62ca8029d3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1069,6 +1069,17 @@ bool Item::check_type_can_return_int(const char *opname) const } +bool Item::check_type_can_return_decimal(const char *opname) const +{ + const Type_handler *handler= type_handler(); + if (handler->can_return_decimal()) + 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_real(const char *opname) const { const Type_handler *handler= type_handler(); @@ -1091,6 +1102,17 @@ bool Item::check_type_can_return_date(const char *opname) const } +bool Item::check_type_can_return_time(const char *opname) const +{ + const Type_handler *handler= type_handler(); + if (handler->can_return_time()) + 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(); diff --git a/sql/item.h b/sql/item.h index 6d918999e73..7662d358b42 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1710,9 +1710,11 @@ public: bool check_type_or_binary(const char *opname, const Type_handler *handler) const; 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_decimal(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; + bool check_type_can_return_time(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 5157c01348e..7db5e3bccc7 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -244,6 +244,19 @@ bool Item_func::check_argument_types_can_return_date(uint start, } +bool Item_func::check_argument_types_can_return_time(uint start, + uint end) const +{ + for (uint i= start; i < end ; i++) + { + DBUG_ASSERT(i < arg_count); + if (args[i]->check_type_can_return_time(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 6d59cae616e..c061c713de5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -50,6 +50,7 @@ protected: 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; + bool check_argument_types_can_return_time(uint start, uint end) const; public: table_map not_null_tables_cache; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index cd67e900efe..6bbc37a78e2 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -782,6 +782,8 @@ public: class Item_func_from_days :public Item_datefunc { + bool check_arguments() const + { return args[0]->check_type_can_return_int(func_name()); } public: Item_func_from_days(THD *thd, Item *a): Item_datefunc(thd, a) {} const char *func_name() const { return "from_days"; } @@ -838,6 +840,8 @@ public: class Item_func_from_unixtime :public Item_datetimefunc { + bool check_arguments() const + { return args[0]->check_type_can_return_decimal(func_name()); } Time_zone *tz; public: Item_func_from_unixtime(THD *thd, Item *a): Item_datetimefunc(thd, a) {} @@ -865,6 +869,11 @@ class Time_zone; */ class Item_func_convert_tz :public Item_datetimefunc { + bool check_arguments() const + { + return args[0]->check_type_can_return_date(func_name()) || + check_argument_types_can_return_str_ascii(1, arg_count); + } /* If time zone parameters are constants we are caching objects that represent them (we use separate from_tz_cached/to_tz_cached members @@ -891,6 +900,8 @@ class Item_func_convert_tz :public Item_datetimefunc class Item_func_sec_to_time :public Item_timefunc { + bool check_arguments() const + { return args[0]->check_type_can_return_decimal(func_name()); } public: Item_func_sec_to_time(THD *thd, Item *item): Item_timefunc(thd, item) {} bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); @@ -1130,6 +1141,8 @@ public: class Item_func_makedate :public Item_datefunc { + bool check_arguments() const + { return check_argument_types_can_return_int(0, arg_count); } public: Item_func_makedate(THD *thd, Item *a, Item *b): Item_datefunc(thd, a, b) {} @@ -1159,6 +1172,8 @@ public: class Item_func_timediff :public Item_timefunc { + bool check_arguments() const + { return check_argument_types_can_return_time(0, arg_count); } public: Item_func_timediff(THD *thd, Item *a, Item *b): Item_timefunc(thd, a, b) {} const char *func_name() const { return "timediff"; } @@ -1175,6 +1190,11 @@ public: class Item_func_maketime :public Item_timefunc { + bool check_arguments() const + { + return check_argument_types_can_return_int(0, 2) || + args[2]->check_type_can_return_decimal(func_name()); + } public: Item_func_maketime(THD *thd, Item *a, Item *b, Item *c): Item_timefunc(thd, a, b, c) @@ -1283,6 +1303,8 @@ public: class Item_func_last_day :public Item_datefunc { + bool check_arguments() const + { return args[0]->check_type_can_return_date(func_name()); } public: Item_func_last_day(THD *thd, Item *a): Item_datefunc(thd, a) {} const char *func_name() const { return "last_day"; } diff --git a/sql/sql_type.h b/sql/sql_type.h index 63351cb26c3..f570e91f882 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -704,9 +704,11 @@ public: } virtual bool is_scalar_type() const { return true; } virtual bool can_return_int() const { return true; } + virtual bool can_return_decimal() 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 can_return_time() 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; @@ -1003,9 +1005,11 @@ public: const Name name() const { return m_name_row; } bool is_scalar_type() const { return false; } bool can_return_int() const { return false; } + bool can_return_decimal() 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 can_return_time() const { return false; } enum_field_types field_type() const { DBUG_ASSERT(0); @@ -2677,9 +2681,11 @@ public: TABLE *table) const; bool can_return_int() const { return false; } + bool can_return_decimal() 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 can_return_time() const { return false; } bool is_traditional_type() const { return false; |