Commit 061a0f0b authored by Alexander Barkov's avatar Alexander Barkov

MDEV-20175 Move Type_handler_row from Type_collection_std to Type_collection_row

parent 5cc2096f
......@@ -189,7 +189,7 @@ SELECT a+1;
END;
$$
CALL p1();
ERROR 21000: Operand should contain 1 column(s)
ERROR HY000: Illegal parameter data types row and int for operation '+'
DROP PROCEDURE p1;
CREATE PROCEDURE p1()
BEGIN
......@@ -198,7 +198,7 @@ SELECT a+1;
END;
$$
CALL p1();
ERROR 21000: Operand should contain 1 column(s)
ERROR HY000: Illegal parameter data types row and int for operation '+'
DROP PROCEDURE p1;
#
# Comparing the entire ROW to a scalar value
......
......@@ -244,7 +244,7 @@ BEGIN
END;
$$
DELIMITER ;$$
--error ER_OPERAND_COLUMNS
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
......@@ -257,7 +257,7 @@ BEGIN
END;
$$
DELIMITER ;$$
--error ER_OPERAND_COLUMNS
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
......
#
# 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
#
--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 #
......@@ -209,7 +209,7 @@ SELECT a+1;
END;
$$
CALL p1();
ERROR 21000: Operand should contain 1 column(s)
ERROR HY000: Illegal parameter data types row and int for operation '+'
DROP PROCEDURE p1;
CREATE PROCEDURE p1()
AS
......@@ -219,7 +219,7 @@ SELECT a+1;
END;
$$
CALL p1();
ERROR 21000: Operand should contain 1 column(s)
ERROR HY000: Illegal parameter data types row and int for operation '+'
DROP PROCEDURE p1;
#
# Comparing the entire ROW to a scalar value
......
......@@ -263,7 +263,7 @@ BEGIN
END;
$$
DELIMITER ;$$
--error ER_OPERAND_COLUMNS
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
......@@ -277,7 +277,7 @@ BEGIN
END;
$$
DELIMITER ;$$
--error ER_OPERAND_COLUMNS
--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CALL p1();
DROP PROCEDURE p1;
......
......@@ -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
{
const Type_handler *handler= type_handler();
if (handler->is_traditional_type() && handler->is_scalar_type())
if (handler->is_traditional_scalar_type())
return false;
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0),
handler->name().ptr(), opname);
......
......@@ -936,7 +936,12 @@ class Item_func_num1: public Item_func_numhybrid
/* Base class for operations like '+', '-', '*' */
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) {}
virtual void result_precision()= 0;
......@@ -1798,6 +1803,10 @@ class Item_func_min_max :public Item_hybrid_func
String tmp_value;
int cmp_sign;
protected:
bool check_arguments() const
{
return false; // Checked by aggregate_for_min_max()
}
bool fix_attributes(Item **item, uint nitems);
public:
Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg):
......
......@@ -2001,7 +2001,7 @@ bool Item_date_add_interval::fix_length_and_dec()
{
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),
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;
if (!args[0]->type_handler()->is_traditional_type() ||
!args[1]->type_handler()->is_traditional_type())
if (!args[0]->type_handler()->is_traditional_scalar_type() ||
!args[1]->type_handler()->is_traditional_scalar_type())
{
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
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()
{
if (!args[0]->type_handler()->is_traditional_type() ||
!args[1]->type_handler()->is_traditional_type())
if (!args[0]->type_handler()->is_traditional_scalar_type() ||
!args[1]->type_handler()->is_traditional_scalar_type())
{
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
args[0]->type_handler()->name().ptr(),
......
......@@ -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()
......@@ -1752,15 +1804,12 @@ Type_handler_hybrid_field_type::aggregate_for_min_max(const char *funcname,
Item **items, uint nitems)
{
bool bit_and_non_bit_mixture_found= false;
uint32 max_display_length;
// LEAST/GREATEST require at least two arguments
DBUG_ASSERT(nitems > 1);
set_handler(items[0]->type_handler());
max_display_length= items[0]->max_display_length();
for (uint i= 1; i < nitems; i++)
{
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
bit_and_non_bit_mixture_found|= (m_type_handler == &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)
{
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));
}
return false;
}
......
......@@ -3314,7 +3314,7 @@ class Type_handler
*/
virtual enum_field_types traditional_merge_field_type() const
{
DBUG_ASSERT(is_traditional_type());
DBUG_ASSERT(is_traditional_scalar_type());
return field_type();
}
virtual enum_field_types type_code_for_protocol() const
......@@ -3413,13 +3413,10 @@ class 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.
*/
virtual bool is_traditional_type() const
{
return true;
}
bool is_traditional_scalar_type() const;
virtual bool is_scalar_type() const { return true; }
virtual bool can_return_int() const { return true; }
virtual bool can_return_decimal() const { return true; }
......@@ -3899,6 +3896,7 @@ class Type_handler_row: public Type_handler
DBUG_ASSERT(0);
return true;
}
const Type_collection *type_collection() const override;
bool is_scalar_type() const { return false; }
bool can_return_int() const { return false; }
bool can_return_decimal() const { return false; }
......
......@@ -136,7 +136,6 @@ class Type_handler_geometry: public Type_handler_string_result
bool can_return_text() const override { return false; }
bool can_return_date() 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_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;
......
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