Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/bb-10.2-ext' into 10.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Barkov committed Apr 4, 2017
2 parents b7fb644 + 17309c4 commit d5c77fb
Show file tree
Hide file tree
Showing 7 changed files with 425 additions and 33 deletions.
59 changes: 59 additions & 0 deletions mysql-test/r/gis.result
Expand Up @@ -3778,5 +3778,64 @@ SELECT STDDEV(COALESCE(a)) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'std('
DROP TABLE t1;
#
# MDEV-12303 Add Type_handler::Item_xxx_fix_length_and_dec() for CAST classes
#
CREATE TABLE t1 (a GEOMETRY);
SELECT CAST(POINT(1,1) AS SIGNED) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_signed'
SELECT CAST(POINT(1,1) AS UNSIGNED) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_unsigned'
SELECT CAST(POINT(1,1) AS DOUBLE) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'double_typecast'
SELECT CAST(POINT(1,1) AS DECIMAL(10,1)) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'decimal_typecast'
SELECT CAST(POINT(1,1) AS CHAR) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_char'
SELECT CAST(POINT(1,1) AS TIME) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_time'
SELECT CAST(POINT(1,1) AS DATE) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_date'
SELECT CAST(POINT(1,1) AS DATETIME) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_datetime'
SELECT CAST(a AS SIGNED) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_signed'
SELECT CAST(a AS UNSIGNED) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_unsigned'
SELECT CAST(a AS DOUBLE) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'double_typecast'
SELECT CAST(a AS DECIMAL(10,1)) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'decimal_typecast'
SELECT CAST(a AS CHAR) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_char'
SELECT CAST(a AS TIME) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_time'
SELECT CAST(a AS DATE) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_date'
SELECT CAST(a AS DATETIME) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_datetime'
SELECT CAST(COALESCE(a) AS SIGNED) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_signed'
SELECT CAST(COALESCE(a) AS UNSIGNED) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_unsigned'
SELECT CAST(COALESCE(a) AS DOUBLE) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'double_typecast'
SELECT CAST(COALESCE(a) AS DECIMAL(10,1)) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'decimal_typecast'
SELECT CAST(COALESCE(a) AS CHAR) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_char'
SELECT CAST(COALESCE(a) AS TIME) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_time'
SELECT CAST(COALESCE(a) AS DATE) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_date'
SELECT CAST(COALESCE(a) AS DATETIME) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'cast_as_datetime'
SELECT LENGTH(CAST(POINT(1,1) AS BINARY)) FROM t1;
LENGTH(CAST(POINT(1,1) AS BINARY))
SELECT LENGTH(CAST(a AS BINARY)) FROM t1;
LENGTH(CAST(a AS BINARY))
SELECT LENGTH(CAST(COALESCE(a) AS BINARY)) FROM t1;
LENGTH(CAST(COALESCE(a) AS BINARY))
DROP TABLE t1;
#
# End of 10.3 tests
#
63 changes: 63 additions & 0 deletions mysql-test/t/gis.test
Expand Up @@ -1952,6 +1952,69 @@ SELECT STDDEV(COALESCE(a)) FROM t1;

DROP TABLE t1;

--echo #
--echo # MDEV-12303 Add Type_handler::Item_xxx_fix_length_and_dec() for CAST classes
--echo #

CREATE TABLE t1 (a GEOMETRY);

--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(POINT(1,1) AS SIGNED) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(POINT(1,1) AS UNSIGNED) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(POINT(1,1) AS DOUBLE) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(POINT(1,1) AS DECIMAL(10,1)) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(POINT(1,1) AS CHAR) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(POINT(1,1) AS TIME) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(POINT(1,1) AS DATE) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(POINT(1,1) AS DATETIME) FROM t1;

--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(a AS SIGNED) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(a AS UNSIGNED) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(a AS DOUBLE) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(a AS DECIMAL(10,1)) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(a AS CHAR) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(a AS TIME) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(a AS DATE) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(a AS DATETIME) FROM t1;

--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(COALESCE(a) AS SIGNED) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(COALESCE(a) AS UNSIGNED) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(COALESCE(a) AS DOUBLE) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(COALESCE(a) AS DECIMAL(10,1)) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(COALESCE(a) AS CHAR) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(COALESCE(a) AS TIME) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(COALESCE(a) AS DATE) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CAST(COALESCE(a) AS DATETIME) FROM t1;

# CAST from GEOMETRY to BINARY is OK
SELECT LENGTH(CAST(POINT(1,1) AS BINARY)) FROM t1;
SELECT LENGTH(CAST(a AS BINARY)) FROM t1;
SELECT LENGTH(CAST(COALESCE(a) AS BINARY)) FROM t1;

DROP TABLE t1;

--echo #
--echo # End of 10.3 tests
Expand Down
22 changes: 19 additions & 3 deletions sql/item_func.h
Expand Up @@ -758,7 +758,7 @@ class Item_func_signed :public Item_int_func
null_value= args[0]->null_value;
return value;
}
void fix_length_and_dec()
void fix_length_and_dec_generic()
{
uint32 char_length= MY_MIN(args[0]->max_char_length(),
MY_INT64_NUM_DECIMAL_DIGITS);
Expand All @@ -770,6 +770,10 @@ class Item_func_signed :public Item_int_func
set_if_bigger(char_length, 1U + (unsigned_flag ? 0 : 1));
fix_char_length(char_length);
}
void fix_length_and_dec()
{
args[0]->type_handler()->Item_func_signed_fix_length_and_dec(this);
}
virtual void print(String *str, enum_query_type query_type);
uint decimal_precision() const { return args[0]->decimal_precision(); }
bool need_parentheses_in_default() { return true; }
Expand All @@ -792,6 +796,10 @@ class Item_func_unsigned :public Item_func_signed
null_value= args[0]->null_value;
return value;
}
void fix_length_and_dec()
{
args[0]->type_handler()->Item_func_unsigned_fix_length_and_dec(this);
}
virtual void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_unsigned>(thd, mem_root, this); }
Expand All @@ -815,7 +823,11 @@ class Item_decimal_typecast :public Item_func
my_decimal *val_decimal(my_decimal*);
enum Item_result result_type () const { return DECIMAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
void fix_length_and_dec() {}
void fix_length_and_dec_generic() {}
void fix_length_and_dec()
{
args[0]->type_handler()->Item_decimal_typecast_fix_length_and_dec(this);
}
const char *func_name() const { return "decimal_typecast"; }
virtual void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
Expand All @@ -835,7 +847,11 @@ class Item_double_typecast :public Item_real_func
}
double val_real();
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
void fix_length_and_dec() { maybe_null= 1; }
void fix_length_and_dec_generic() { maybe_null= 1; }
void fix_length_and_dec()
{
args[0]->type_handler()->Item_double_typecast_fix_length_and_dec(this);
}
const char *func_name() const { return "double_typecast"; }
virtual void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
Expand Down
24 changes: 17 additions & 7 deletions sql/item_timefunc.cc
Expand Up @@ -2502,7 +2502,23 @@ String *Item_char_typecast::val_str(String *str)
}


void Item_char_typecast::fix_length_and_dec()
void Item_char_typecast::fix_length_and_dec_numeric()
{
fix_length_and_dec_internal(from_cs= cast_cs->mbminlen == 1 ?
cast_cs :
&my_charset_latin1);
}


void Item_char_typecast::fix_length_and_dec_str()
{
fix_length_and_dec_internal(from_cs= args[0]->dynamic_result() ?
0 :
args[0]->collation.collation);
}


void Item_char_typecast::fix_length_and_dec_internal(CHARSET_INFO *from_cs)
{
uint32 char_length;
/*
Expand Down Expand Up @@ -2532,12 +2548,6 @@ void Item_char_typecast::fix_length_and_dec()
Note (TODO): we could use repertoire technique here.
*/
from_cs= ((args[0]->result_type() == INT_RESULT ||
args[0]->result_type() == DECIMAL_RESULT ||
args[0]->result_type() == REAL_RESULT) ?
(cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) :
args[0]->dynamic_result() ? 0 :
args[0]->collation.collation);
charset_conversion= !from_cs || (cast_cs->mbmaxlen > 1) ||
(!my_charset_same(from_cs, cast_cs) &&
from_cs != &my_charset_bin &&
Expand Down
23 changes: 21 additions & 2 deletions sql/item_timefunc.h
Expand Up @@ -1037,14 +1037,21 @@ class Item_char_typecast :public Item_str_func
String *copy(String *src, CHARSET_INFO *cs);
uint adjusted_length_with_warn(uint length);
void check_truncation_with_warn(String *src, uint dstlen);
void fix_length_and_dec_internal(CHARSET_INFO *fromcs);
public:
Item_char_typecast(THD *thd, Item *a, uint length_arg, CHARSET_INFO *cs_arg):
Item_str_func(thd, a), cast_length(length_arg), cast_cs(cs_arg) {}
enum Functype functype() const { return CHAR_TYPECAST_FUNC; }
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "cast_as_char"; }
CHARSET_INFO *cast_charset() const { return cast_cs; }
String *val_str(String *a);
void fix_length_and_dec();
void fix_length_and_dec_numeric();
void fix_length_and_dec_str();
void fix_length_and_dec()
{
args[0]->type_handler()->Item_char_typecast_fix_length_and_dec(this);
}
void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
Expand All @@ -1058,7 +1065,7 @@ class Item_temporal_typecast: public Item_temporal_func
Item_temporal_typecast(THD *thd, Item *a): Item_temporal_func(thd, a) {}
virtual const char *cast_type() const = 0;
void print(String *str, enum_query_type query_type);
void fix_length_and_dec()
void fix_length_and_dec_generic()
{
if (decimals == NOT_FIXED_DEC)
decimals= args[0]->temporal_precision(field_type());
Expand All @@ -1074,6 +1081,10 @@ class Item_date_typecast :public Item_temporal_typecast
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
const char *cast_type() const { return "date"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
void fix_length_and_dec()
{
args[0]->type_handler()->Item_date_typecast_fix_length_and_dec(this);
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_date_typecast>(thd, mem_root, this); }
};
Expand All @@ -1088,6 +1099,10 @@ class Item_time_typecast :public Item_temporal_typecast
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
const char *cast_type() const { return "time"; }
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
void fix_length_and_dec()
{
args[0]->type_handler()->Item_time_typecast_fix_length_and_dec(this);
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_time_typecast>(thd, mem_root, this); }
};
Expand All @@ -1102,6 +1117,10 @@ class Item_datetime_typecast :public Item_temporal_typecast
const char *cast_type() const { return "datetime"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
void fix_length_and_dec()
{
args[0]->type_handler()->Item_datetime_typecast_fix_length_and_dec(this);
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_datetime_typecast>(thd, mem_root, this); }
};
Expand Down

0 comments on commit d5c77fb

Please sign in to comment.