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 /sql | |
parent | ca38b93e354baa5bbcaea00543dc1a99940072e4 (diff) | |
download | mariadb-git-aa582dedcbd22182e06355b94d1de4fc62f71910.tar.gz |
MDEV-13966 Parameter data type control for Item_temporal_func
Diffstat (limited to 'sql')
-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 |
6 files changed, 66 insertions, 0 deletions
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; |