MDEV-20175 Move Type_handler_row from Type_collection_std to Type_collection_row

This commit is contained in:
Alexander Barkov 2019-07-25 04:38:05 +04:00
parent 5cc2096f93
commit 061a0f0b8d
12 changed files with 198 additions and 25 deletions

View File

@ -189,7 +189,7 @@ SELECT a+1;
END; END;
$$ $$
CALL p1(); CALL p1();
ERROR 21000: Operand should contain 1 column(s) ERROR HY000: Illegal parameter data types row and int for operation '+'
DROP PROCEDURE p1; DROP PROCEDURE p1;
CREATE PROCEDURE p1() CREATE PROCEDURE p1()
BEGIN BEGIN
@ -198,7 +198,7 @@ SELECT a+1;
END; END;
$$ $$
CALL p1(); CALL p1();
ERROR 21000: Operand should contain 1 column(s) ERROR HY000: Illegal parameter data types row and int for operation '+'
DROP PROCEDURE p1; DROP PROCEDURE p1;
# #
# Comparing the entire ROW to a scalar value # Comparing the entire ROW to a scalar value

View File

@ -244,7 +244,7 @@ BEGIN
END; END;
$$ $$
DELIMITER ;$$ DELIMITER ;$$
--error ER_OPERAND_COLUMNS --error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1(); CALL p1();
DROP PROCEDURE p1; DROP PROCEDURE p1;
@ -257,7 +257,7 @@ BEGIN
END; END;
$$ $$
DELIMITER ;$$ DELIMITER ;$$
--error ER_OPERAND_COLUMNS --error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1(); CALL p1();
DROP PROCEDURE p1; DROP PROCEDURE p1;

View File

@ -0,0 +1,51 @@
#
# Start of 10.5 tests
#
#
# MDEV-20175 Move Type_handler_row from Type_collection_std to Type_collection_row
#
SELECT LEAST(ROW(1,1), ROW(1,1));
ERROR HY000: Illegal parameter data types row and row for operation 'least'
SELECT GREATEST(ROW(1,1), ROW(1,1));
ERROR HY000: Illegal parameter data types row and row for operation 'greatest'
SELECT LEAST(ROW(1,1), 1);
ERROR HY000: Illegal parameter data types row and int for operation 'least'
SELECT GREATEST(ROW(1,1), 1);
ERROR HY000: Illegal parameter data types row and int for operation 'greatest'
SELECT LEAST(1, ROW(1,1));
ERROR HY000: Illegal parameter data types int and row for operation 'least'
SELECT GREATEST(1, ROW(1,1));
ERROR HY000: Illegal parameter data types int and row for operation 'greatest'
SELECT ROW(1,1) + ROW(1,1);
ERROR HY000: Illegal parameter data types row and row for operation '+'
SELECT 1 + ROW(1,1);
ERROR HY000: Illegal parameter data types int and row for operation '+'
SELECT ROW(1,1) + 1;
ERROR HY000: Illegal parameter data types row and int for operation '+'
SELECT ROW(1,1) - ROW(1,1);
ERROR HY000: Illegal parameter data types row and row for operation '-'
SELECT 1 - ROW(1,1);
ERROR HY000: Illegal parameter data types int and row for operation '-'
SELECT ROW(1,1) - 1;
ERROR HY000: Illegal parameter data types row and int for operation '-'
SELECT ROW(1,1) * ROW(1,1);
ERROR HY000: Illegal parameter data types row and row for operation '*'
SELECT 1 * ROW(1,1);
ERROR HY000: Illegal parameter data types int and row for operation '*'
SELECT ROW(1,1) * 1;
ERROR HY000: Illegal parameter data types row and int for operation '*'
SELECT ROW(1,1) / ROW(1,1);
ERROR HY000: Illegal parameter data types row and row for operation '/'
SELECT 1 / ROW(1,1);
ERROR HY000: Illegal parameter data types int and row for operation '/'
SELECT ROW(1,1) / 1;
ERROR HY000: Illegal parameter data types row and int for operation '/'
SELECT ROW(1,1) % ROW(1,1);
ERROR HY000: Illegal parameter data types row and row for operation 'MOD'
SELECT 1 % ROW(1,1);
ERROR HY000: Illegal parameter data types int and row for operation 'MOD'
SELECT ROW(1,1) % 1;
ERROR HY000: Illegal parameter data types row and int for operation 'MOD'
#
# End of 10.5 tests
#

View File

@ -0,0 +1,62 @@
--echo #
--echo # Start of 10.5 tests
--echo #
--echo #
--echo # MDEV-20175 Move Type_handler_row from Type_collection_std to Type_collection_row
--echo #
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT LEAST(ROW(1,1), ROW(1,1));
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT GREATEST(ROW(1,1), ROW(1,1));
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT LEAST(ROW(1,1), 1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT GREATEST(ROW(1,1), 1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT LEAST(1, ROW(1,1));
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT GREATEST(1, ROW(1,1));
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT ROW(1,1) + ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT 1 + ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT ROW(1,1) + 1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT ROW(1,1) - ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT 1 - ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT ROW(1,1) - 1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT ROW(1,1) * ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT 1 * ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT ROW(1,1) * 1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT ROW(1,1) / ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT 1 / ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT ROW(1,1) / 1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT ROW(1,1) % ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT 1 % ROW(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT ROW(1,1) % 1;
--echo #
--echo # End of 10.5 tests
--echo #

View File

@ -209,7 +209,7 @@ SELECT a+1;
END; END;
$$ $$
CALL p1(); CALL p1();
ERROR 21000: Operand should contain 1 column(s) ERROR HY000: Illegal parameter data types row and int for operation '+'
DROP PROCEDURE p1; DROP PROCEDURE p1;
CREATE PROCEDURE p1() CREATE PROCEDURE p1()
AS AS
@ -219,7 +219,7 @@ SELECT a+1;
END; END;
$$ $$
CALL p1(); CALL p1();
ERROR 21000: Operand should contain 1 column(s) ERROR HY000: Illegal parameter data types row and int for operation '+'
DROP PROCEDURE p1; DROP PROCEDURE p1;
# #
# Comparing the entire ROW to a scalar value # Comparing the entire ROW to a scalar value

View File

@ -263,7 +263,7 @@ BEGIN
END; END;
$$ $$
DELIMITER ;$$ DELIMITER ;$$
--error ER_OPERAND_COLUMNS --error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1(); CALL p1();
DROP PROCEDURE p1; DROP PROCEDURE p1;
@ -277,7 +277,7 @@ BEGIN
END; END;
$$ $$
DELIMITER ;$$ DELIMITER ;$$
--error ER_OPERAND_COLUMNS --error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1(); CALL p1();
DROP PROCEDURE p1; DROP PROCEDURE p1;

View File

@ -978,7 +978,7 @@ bool Item::check_type_general_purpose_string(const char *opname) const
bool Item::check_type_traditional_scalar(const char *opname) const bool Item::check_type_traditional_scalar(const char *opname) const
{ {
const Type_handler *handler= type_handler(); const Type_handler *handler= type_handler();
if (handler->is_traditional_type() && handler->is_scalar_type()) if (handler->is_traditional_scalar_type())
return false; return false;
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0), my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0),
handler->name().ptr(), opname); handler->name().ptr(), opname);

View File

@ -936,7 +936,12 @@ public:
/* Base class for operations like '+', '-', '*' */ /* Base class for operations like '+', '-', '*' */
class Item_num_op :public Item_func_numhybrid class Item_num_op :public Item_func_numhybrid
{ {
public: protected:
bool check_arguments() const
{
return false; // Checked by aggregate_for_num_op()
}
public:
Item_num_op(THD *thd, Item *a, Item *b): Item_func_numhybrid(thd, a, b) {} Item_num_op(THD *thd, Item *a, Item *b): Item_func_numhybrid(thd, a, b) {}
virtual void result_precision()= 0; virtual void result_precision()= 0;
@ -1798,6 +1803,10 @@ class Item_func_min_max :public Item_hybrid_func
String tmp_value; String tmp_value;
int cmp_sign; int cmp_sign;
protected: protected:
bool check_arguments() const
{
return false; // Checked by aggregate_for_min_max()
}
bool fix_attributes(Item **item, uint nitems); bool fix_attributes(Item **item, uint nitems);
public: public:
Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg): Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg):

View File

@ -2001,7 +2001,7 @@ bool Item_date_add_interval::fix_length_and_dec()
{ {
enum_field_types arg0_field_type; enum_field_types arg0_field_type;
if (!args[0]->type_handler()->is_traditional_type()) if (!args[0]->type_handler()->is_traditional_scalar_type())
{ {
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
args[0]->type_handler()->name().ptr(), args[0]->type_handler()->name().ptr(),
@ -2505,8 +2505,8 @@ bool Item_func_add_time::fix_length_and_dec()
{ {
enum_field_types arg0_field_type; enum_field_types arg0_field_type;
if (!args[0]->type_handler()->is_traditional_type() || if (!args[0]->type_handler()->is_traditional_scalar_type() ||
!args[1]->type_handler()->is_traditional_type()) !args[1]->type_handler()->is_traditional_scalar_type())
{ {
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
args[0]->type_handler()->name().ptr(), args[0]->type_handler()->name().ptr(),
@ -2916,8 +2916,8 @@ get_date_time_result_type(const char *format, uint length)
bool Item_func_str_to_date::fix_length_and_dec() bool Item_func_str_to_date::fix_length_and_dec()
{ {
if (!args[0]->type_handler()->is_traditional_type() || if (!args[0]->type_handler()->is_traditional_scalar_type() ||
!args[1]->type_handler()->is_traditional_type()) !args[1]->type_handler()->is_traditional_scalar_type())
{ {
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
args[0]->type_handler()->name().ptr(), args[0]->type_handler()->name().ptr(),

View File

@ -109,6 +109,58 @@ const Type_collection *Type_handler::type_collection() const
} }
bool Type_handler::is_traditional_scalar_type() const
{
return type_collection() == &type_collection_std;
}
class Type_collection_row: public Type_collection
{
public:
bool init(Type_handler_data *data) override
{
return false;
}
const Type_handler *handler_by_name(const LEX_CSTRING &name) const override
{
return NULL;
}
const Type_handler *aggregate_for_result(const Type_handler *a,
const Type_handler *b)
const override
{
return NULL;
}
const Type_handler *aggregate_for_comparison(const Type_handler *a,
const Type_handler *b)
const override
{
DBUG_ASSERT(a == &type_handler_row);
DBUG_ASSERT(b == &type_handler_row);
return &type_handler_row;
}
const Type_handler *aggregate_for_min_max(const Type_handler *a,
const Type_handler *b)
const override
{
return NULL;
}
const Type_handler *aggregate_for_num_op(const Type_handler *a,
const Type_handler *b)
const override
{
return NULL;
}
};
static Type_collection_row type_collection_row;
const Type_collection *Type_handler_row::type_collection() const
{
return &type_collection_row;
}
bool Type_handler_data::init() bool Type_handler_data::init()
@ -1752,15 +1804,12 @@ Type_handler_hybrid_field_type::aggregate_for_min_max(const char *funcname,
Item **items, uint nitems) Item **items, uint nitems)
{ {
bool bit_and_non_bit_mixture_found= false; bool bit_and_non_bit_mixture_found= false;
uint32 max_display_length;
// LEAST/GREATEST require at least two arguments // LEAST/GREATEST require at least two arguments
DBUG_ASSERT(nitems > 1); DBUG_ASSERT(nitems > 1);
set_handler(items[0]->type_handler()); set_handler(items[0]->type_handler());
max_display_length= items[0]->max_display_length();
for (uint i= 1; i < nitems; i++) for (uint i= 1; i < nitems; i++)
{ {
const Type_handler *cur= items[i]->type_handler(); const Type_handler *cur= items[i]->type_handler();
set_if_bigger(max_display_length, items[i]->max_display_length());
// Check if BIT + non-BIT, or non-BIT + BIT // Check if BIT + non-BIT, or non-BIT + BIT
bit_and_non_bit_mixture_found|= (m_type_handler == &type_handler_bit) != bit_and_non_bit_mixture_found|= (m_type_handler == &type_handler_bit) !=
(cur == &type_handler_bit); (cur == &type_handler_bit);
@ -1772,7 +1821,12 @@ Type_handler_hybrid_field_type::aggregate_for_min_max(const char *funcname,
} }
} }
if (bit_and_non_bit_mixture_found && type_handler() == &type_handler_longlong) if (bit_and_non_bit_mixture_found && type_handler() == &type_handler_longlong)
{
uint32 max_display_length= items[0]->max_display_length();
for (uint i= 1; i < nitems; i++)
set_if_bigger(max_display_length, items[i]->max_display_length());
set_handler(Type_handler::bit_and_int_mixture_handler(max_display_length)); set_handler(Type_handler::bit_and_int_mixture_handler(max_display_length));
}
return false; return false;
} }

View File

@ -3314,7 +3314,7 @@ public:
*/ */
virtual enum_field_types traditional_merge_field_type() const virtual enum_field_types traditional_merge_field_type() const
{ {
DBUG_ASSERT(is_traditional_type()); DBUG_ASSERT(is_traditional_scalar_type());
return field_type(); return field_type();
} }
virtual enum_field_types type_code_for_protocol() const virtual enum_field_types type_code_for_protocol() const
@ -3413,13 +3413,10 @@ public:
} }
virtual ~Type_handler() {} virtual ~Type_handler() {}
/** /**
Determines MariaDB traditional data types that always present Determines MariaDB traditional scalar data types that always present
in the server. in the server.
*/ */
virtual bool is_traditional_type() const bool is_traditional_scalar_type() const;
{
return true;
}
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_decimal() const { return true; } virtual bool can_return_decimal() const { return true; }
@ -3899,6 +3896,7 @@ public:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return true; return true;
} }
const Type_collection *type_collection() const override;
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_decimal() const { return false; } bool can_return_decimal() const { return false; }

View File

@ -136,7 +136,6 @@ public:
bool can_return_text() const override { return false; } bool can_return_text() const override { return false; }
bool can_return_date() const override { return false; } bool can_return_date() const override { return false; }
bool can_return_time() const override { return false; } bool can_return_time() const override { return false; }
bool is_traditional_type() const override { return false; }
bool Item_func_round_fix_length_and_dec(Item_func_round *) const override; bool Item_func_round_fix_length_and_dec(Item_func_round *) const override;
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const override; bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const override;
bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const override; bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const override;