Commit ca38b93e authored by Alexander Barkov's avatar Alexander Barkov

MDEV-13965 Parameter data type control for Item_longlong_func

parent dc41bc14
#
# 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
#
...@@ -4755,5 +4755,36 @@ ERROR HY000: Illegal parameter data type row for operation 'radians' ...@@ -4755,5 +4755,36 @@ ERROR HY000: Illegal parameter data type row for operation 'radians'
SELECT DEGREES(ROW(1,1)); SELECT DEGREES(ROW(1,1));
ERROR HY000: Illegal parameter data type row for operation 'degrees' 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 # End of 10.3 tests
# #
...@@ -45,4 +45,17 @@ master_pos_wait('master-bin.000001',1000000,1,"my_slave") ...@@ -45,4 +45,17 @@ master_pos_wait('master-bin.000001',1000000,1,"my_slave")
STOP SLAVE 'my_slave'; STOP SLAVE 'my_slave';
RESET SLAVE 'my_slave' ALL; RESET SLAVE 'my_slave' ALL;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root'; 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 include/rpl_end.inc
...@@ -56,5 +56,23 @@ eval change master to master_port=$MASTER_MYPORT, master_host='127.0.0.1', maste ...@@ -56,5 +56,23 @@ eval change master to master_port=$MASTER_MYPORT, master_host='127.0.0.1', maste
# End of 10.0 tests # 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 --let $rpl_only_running_threads= 1
--source include/rpl_end.inc --source include/rpl_end.inc
--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 #
...@@ -2794,6 +2794,48 @@ SELECT RADIANS(ROW(1,1)); ...@@ -2794,6 +2794,48 @@ SELECT RADIANS(ROW(1,1));
SELECT DEGREES(ROW(1,1)); 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 #
--echo # End of 10.3 tests --echo # End of 10.3 tests
--echo # --echo #
...@@ -1080,6 +1080,28 @@ bool Item::check_type_can_return_real(const char *opname) const ...@@ -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 bool Item::check_type_scalar(const char *opname) const
{ {
const Type_handler *handler= type_handler(); const Type_handler *handler= type_handler();
......
...@@ -1711,6 +1711,8 @@ class Item: public Value_source, ...@@ -1711,6 +1711,8 @@ class Item: public Value_source,
bool check_type_general_purpose_string(const char *opname) 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_int(const char *opname) const;
bool check_type_can_return_real(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 // It is not row => null inside is impossible
virtual bool null_inside() { return 0; } virtual bool null_inside() { return 0; }
// used in row subselects to get value of elements // used in row subselects to get value of elements
......
...@@ -218,6 +218,32 @@ bool Item_func::check_argument_types_can_return_real(uint start, ...@@ -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 bool Item_func::check_argument_types_scalar(uint start, uint end) const
{ {
for (uint i= start; i < end; i++) for (uint i= start; i < end; i++)
......
...@@ -48,6 +48,8 @@ class Item_func :public Item_func_or_sum ...@@ -48,6 +48,8 @@ class Item_func :public Item_func_or_sum
uint start, uint end) const; uint start, uint end) const;
bool check_argument_types_can_return_int(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_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: public:
table_map not_null_tables_cache; table_map not_null_tables_cache;
...@@ -1742,6 +1744,8 @@ class Item_func_find_in_set :public Item_long_func ...@@ -1742,6 +1744,8 @@ class Item_func_find_in_set :public Item_long_func
class Item_func_bit: public Item_longlong_func class Item_func_bit: public Item_longlong_func
{ {
bool check_arguments() const
{ return check_argument_types_can_return_int(0, arg_count); }
public: public:
Item_func_bit(THD *thd, Item *a, Item *b): Item_longlong_func(thd, a, b) {} 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) {} Item_func_bit(THD *thd, Item *a): Item_longlong_func(thd, a) {}
...@@ -1828,6 +1832,8 @@ class Item_func_bit_neg :public Item_func_bit ...@@ -1828,6 +1832,8 @@ class Item_func_bit_neg :public Item_func_bit
class Item_func_last_insert_id :public Item_longlong_func 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: public:
Item_func_last_insert_id(THD *thd): Item_longlong_func(thd) {} 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) {} Item_func_last_insert_id(THD *thd, Item *a): Item_longlong_func(thd, a) {}
...@@ -2199,6 +2205,14 @@ class Item_func_release_lock :public Item_long_func ...@@ -2199,6 +2205,14 @@ class Item_func_release_lock :public Item_long_func
class Item_master_pos_wait :public Item_longlong_func 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; String value;
public: public:
Item_master_pos_wait(THD *thd, Item *a, Item *b) Item_master_pos_wait(THD *thd, Item *a, Item *b)
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
class Item_func_inet_aton : public Item_longlong_func 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: public:
Item_func_inet_aton(THD *thd, Item *a): Item_longlong_func(thd, a) {} Item_func_inet_aton(THD *thd, Item *a): Item_longlong_func(thd, a) {}
longlong val_int(); longlong val_int();
......
...@@ -91,6 +91,8 @@ class Item_func_to_days :public Item_long_func ...@@ -91,6 +91,8 @@ class Item_func_to_days :public Item_long_func
class Item_func_to_seconds :public Item_longlong_func class Item_func_to_seconds :public Item_longlong_func
{ {
bool check_arguments() const
{ return check_argument_types_can_return_date(0, arg_count); }
public: public:
Item_func_to_seconds(THD *thd, Item *a): Item_longlong_func(thd, a) {} Item_func_to_seconds(THD *thd, Item *a): Item_longlong_func(thd, a) {}
longlong val_int(); longlong val_int();
...@@ -1214,6 +1216,8 @@ class Item_func_microsecond :public Item_long_func ...@@ -1214,6 +1216,8 @@ class Item_func_microsecond :public Item_long_func
class Item_func_timestamp_diff :public Item_longlong_func 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; const interval_type int_type;
public: public:
Item_func_timestamp_diff(THD *thd, Item *a, Item *b, interval_type type_arg): Item_func_timestamp_diff(THD *thd, Item *a, Item *b, interval_type type_arg):
......
...@@ -705,6 +705,8 @@ class Type_handler ...@@ -705,6 +705,8 @@ class Type_handler
virtual bool is_scalar_type() const { return true; } virtual bool is_scalar_type() const { return true; }
virtual bool can_return_int() const { return true; } virtual bool can_return_int() const { return true; }
virtual bool can_return_real() 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 bool is_general_purpose_string_type() const { return false; }
virtual uint Item_time_precision(Item *item) const; virtual uint Item_time_precision(Item *item) const;
virtual uint Item_datetime_precision(Item *item) const; virtual uint Item_datetime_precision(Item *item) const;
...@@ -1002,6 +1004,8 @@ class Type_handler_row: public Type_handler ...@@ -1002,6 +1004,8 @@ class Type_handler_row: public Type_handler
bool is_scalar_type() const { return false; } bool is_scalar_type() const { return false; }
bool can_return_int() const { return false; } bool can_return_int() const { return false; }
bool can_return_real() 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 enum_field_types field_type() const
{ {
DBUG_ASSERT(0); DBUG_ASSERT(0);
...@@ -2674,6 +2678,8 @@ class Type_handler_geometry: public Type_handler_string_result ...@@ -2674,6 +2678,8 @@ class Type_handler_geometry: public Type_handler_string_result
bool can_return_int() const { return false; } bool can_return_int() const { return false; }
bool can_return_real() 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 bool is_traditional_type() const
{ {
return false; return false;
......
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