MDEV-7113 difference between check_vcol_func_processor and check_partition_func_processor
MDEV-6789 segfault in Item_func_from_unixtime::get_date on updating table with virtual columns * prohibit VALUES in partitioning expression * prohibit user and system variables in virtual column expressions * fix Item_func_date_format to cache locale (for %M/%W to return the same as MONTHNAME/DAYNAME) * fix Item_func_from_unixtime to cache time_zone directly, not THD (and not to crash) * added tests for other incorrectly allowed (in vcols) functions to see that they don't crash
This commit is contained in:
parent
84f25c25f2
commit
5d0122bd77
@ -1754,3 +1754,8 @@ PARTITION pmax VALUES LESS THAN MAXVALUE);
|
|||||||
ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
|
ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
create table t1 (a int) partition by list (values(a) div 1) (partition p0 values in (0), partition p1 values in (1));
|
||||||
|
ERROR HY000: This partition function is not allowed
|
||||||
|
create table t1 (a int) partition by list (uuid_short()) (partition p0 values in (0), partition p1 values in (1));
|
||||||
|
ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ') (partition p0 values in (0), partition p1 values in (1))' at line 1
|
||||||
|
End of 5.5 tests
|
||||||
|
67
mysql-test/suite/vcol/r/not_supported.result
Normal file
67
mysql-test/suite/vcol/r/not_supported.result
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
set lc_time_names = 'es_MX';
|
||||||
|
set time_zone='+10:00';
|
||||||
|
set div_precision_increment=20;
|
||||||
|
create table t1 (a int, b int, v decimal(20,19) as (a/3));
|
||||||
|
create table t2 (a int, b int, v int as (a+@a));
|
||||||
|
ERROR HY000: Function or expression is not allowed for column 'v'
|
||||||
|
create table t3 (a int, b int, v int as (a+@@error_count));
|
||||||
|
ERROR HY000: Function or expression is not allowed for column 'v'
|
||||||
|
create table t4 (a int, b int, v int as (@a:=a));
|
||||||
|
ERROR HY000: Function or expression is not allowed for column 'v'
|
||||||
|
create table t5 (a int, b int, v varchar(100) as (monthname(a)));
|
||||||
|
create table t6 (a int, b int, v varchar(100) as (dayname(a)));
|
||||||
|
create table t7 (a int, b int, v varchar(100) as (date_format(a, '%W %a %M %b')));
|
||||||
|
create table t8 (a int, b int, v varchar(100) as (from_unixtime(a)));
|
||||||
|
insert t1 (a,b) values (1,2);
|
||||||
|
insert t5 (a,b) values (20141010,2);
|
||||||
|
insert t6 (a,b) values (20141010,2);
|
||||||
|
insert t7 (a,b) values (20141010,2);
|
||||||
|
insert t8 (a,b) values (1234567890,2);
|
||||||
|
select * from t1;
|
||||||
|
a b v
|
||||||
|
1 2 0.3333333333333333333
|
||||||
|
select * from t5;
|
||||||
|
a b v
|
||||||
|
20141010 2 octubre
|
||||||
|
select * from t6;
|
||||||
|
a b v
|
||||||
|
20141010 2 viernes
|
||||||
|
select * from t7;
|
||||||
|
a b v
|
||||||
|
20141010 2 viernes vie octubre oct
|
||||||
|
select * from t8;
|
||||||
|
a b v
|
||||||
|
1234567890 2 2009-02-14 09:31:30
|
||||||
|
set time_zone='+1:00';
|
||||||
|
select * from t1;
|
||||||
|
a b v
|
||||||
|
1 2 0.3333333333333333333
|
||||||
|
select * from t5;
|
||||||
|
a b v
|
||||||
|
20141010 2 octubre
|
||||||
|
select * from t6;
|
||||||
|
a b v
|
||||||
|
20141010 2 viernes
|
||||||
|
select * from t7;
|
||||||
|
a b v
|
||||||
|
20141010 2 viernes vie octubre oct
|
||||||
|
select * from t8;
|
||||||
|
a b v
|
||||||
|
1234567890 2 2009-02-14 09:31:30
|
||||||
|
flush tables;
|
||||||
|
select * from t1;
|
||||||
|
a b v
|
||||||
|
1 2 0.3333333330000000000
|
||||||
|
select * from t5;
|
||||||
|
a b v
|
||||||
|
20141010 2 October
|
||||||
|
select * from t6;
|
||||||
|
a b v
|
||||||
|
20141010 2 Friday
|
||||||
|
select * from t7;
|
||||||
|
a b v
|
||||||
|
20141010 2 Friday Fri October Oct
|
||||||
|
select * from t8;
|
||||||
|
a b v
|
||||||
|
1234567890 2 2009-02-14 00:31:30
|
||||||
|
drop table t1, t5, t6, t7, t8;
|
58
mysql-test/suite/vcol/t/not_supported.test
Normal file
58
mysql-test/suite/vcol/t/not_supported.test
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#
|
||||||
|
# MDEV-7113 difference between check_vcol_func_processor and check_partition_func_processor
|
||||||
|
#
|
||||||
|
|
||||||
|
# the following functions must not be supported in virtual columns.
|
||||||
|
# but for compatibility reasons it won't be done in a GA version,
|
||||||
|
# we'll only fix most critical issues (inconsistent results, crashes)
|
||||||
|
|
||||||
|
connect (con1, localhost, root);
|
||||||
|
|
||||||
|
set lc_time_names = 'es_MX';
|
||||||
|
set time_zone='+10:00';
|
||||||
|
set div_precision_increment=20;
|
||||||
|
|
||||||
|
create table t1 (a int, b int, v decimal(20,19) as (a/3));
|
||||||
|
--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
||||||
|
create table t2 (a int, b int, v int as (a+@a));
|
||||||
|
--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
||||||
|
create table t3 (a int, b int, v int as (a+@@error_count));
|
||||||
|
--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
||||||
|
create table t4 (a int, b int, v int as (@a:=a));
|
||||||
|
create table t5 (a int, b int, v varchar(100) as (monthname(a)));
|
||||||
|
create table t6 (a int, b int, v varchar(100) as (dayname(a)));
|
||||||
|
create table t7 (a int, b int, v varchar(100) as (date_format(a, '%W %a %M %b')));
|
||||||
|
create table t8 (a int, b int, v varchar(100) as (from_unixtime(a)));
|
||||||
|
|
||||||
|
insert t1 (a,b) values (1,2);
|
||||||
|
insert t5 (a,b) values (20141010,2);
|
||||||
|
insert t6 (a,b) values (20141010,2);
|
||||||
|
insert t7 (a,b) values (20141010,2);
|
||||||
|
insert t8 (a,b) values (1234567890,2);
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
select * from t5;
|
||||||
|
select * from t6;
|
||||||
|
select * from t7;
|
||||||
|
select * from t8;
|
||||||
|
|
||||||
|
disconnect con1;
|
||||||
|
connection default;
|
||||||
|
set time_zone='+1:00';
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
select * from t5;
|
||||||
|
select * from t6;
|
||||||
|
select * from t7;
|
||||||
|
select * from t8;
|
||||||
|
|
||||||
|
flush tables;
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
select * from t5;
|
||||||
|
select * from t6;
|
||||||
|
select * from t7;
|
||||||
|
select * from t8;
|
||||||
|
|
||||||
|
drop table t1, t5, t6, t7, t8;
|
||||||
|
|
@ -2005,3 +2005,14 @@ PARTITION pmax VALUES LESS THAN MAXVALUE);
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
|
||||||
|
#
|
||||||
|
# MDEV-7113 difference between check_vcol_func_processor and check_partition_func_processor
|
||||||
|
#
|
||||||
|
--error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
|
||||||
|
create table t1 (a int) partition by list (values(a) div 1) (partition p0 values in (0), partition p1 values in (1));
|
||||||
|
|
||||||
|
--error ER_PARSE_ERROR
|
||||||
|
create table t1 (a int) partition by list (uuid_short()) (partition p0 values in (0), partition p1 values in (1));
|
||||||
|
|
||||||
|
--echo End of 5.5 tests
|
||||||
|
@ -3939,6 +3939,7 @@ public:
|
|||||||
return arg->walk(processor, walk_subquery, args) ||
|
return arg->walk(processor, walk_subquery, args) ||
|
||||||
(this->*processor)(args);
|
(this->*processor)(args);
|
||||||
}
|
}
|
||||||
|
bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
|
||||||
bool check_vcol_func_processor(uchar *arg)
|
bool check_vcol_func_processor(uchar *arg)
|
||||||
{
|
{
|
||||||
return trace_unsupported_by_check_vcol_func_processor("values");
|
return trace_unsupported_by_check_vcol_func_processor("values");
|
||||||
|
@ -1696,6 +1696,7 @@ public:
|
|||||||
bool register_field_in_bitmap(uchar *arg);
|
bool register_field_in_bitmap(uchar *arg);
|
||||||
bool set_entry(THD *thd, bool create_if_not_exists);
|
bool set_entry(THD *thd, bool create_if_not_exists);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
bool check_vcol_func_processor(uchar *int_arg) {return TRUE;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1735,6 +1736,7 @@ public:
|
|||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
bool check_vcol_func_processor(uchar *int_arg) { return TRUE;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1817,6 +1819,7 @@ public:
|
|||||||
bool eq(const Item *item, bool binary_cmp) const;
|
bool eq(const Item *item, bool binary_cmp) const;
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
bool check_vcol_func_processor(uchar *int_arg) { return TRUE;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -2090,7 +2093,6 @@ public:
|
|||||||
longlong val_int();
|
longlong val_int();
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec()
|
||||||
{ max_length= 21; unsigned_flag=1; }
|
{ max_length= 21; unsigned_flag=1; }
|
||||||
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
|
|
||||||
bool check_vcol_func_processor(uchar *int_arg)
|
bool check_vcol_func_processor(uchar *int_arg)
|
||||||
{
|
{
|
||||||
return trace_unsupported_by_check_vcol_func_processor(func_name());
|
return trace_unsupported_by_check_vcol_func_processor(func_name());
|
||||||
|
@ -450,16 +450,14 @@ err:
|
|||||||
Create a formated date/time value in a string.
|
Create a formated date/time value in a string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
static bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
||||||
timestamp_type type, String *str)
|
timestamp_type type, MY_LOCALE *locale, String *str)
|
||||||
{
|
{
|
||||||
char intbuff[15];
|
char intbuff[15];
|
||||||
uint hours_i;
|
uint hours_i;
|
||||||
uint weekday;
|
uint weekday;
|
||||||
ulong length;
|
ulong length;
|
||||||
const char *ptr, *end;
|
const char *ptr, *end;
|
||||||
THD *thd= current_thd;
|
|
||||||
MY_LOCALE *locale= thd->variables.lc_time_names;
|
|
||||||
|
|
||||||
str->length(0);
|
str->length(0);
|
||||||
|
|
||||||
@ -1726,6 +1724,8 @@ overflow:
|
|||||||
void Item_func_date_format::fix_length_and_dec()
|
void Item_func_date_format::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
THD* thd= current_thd;
|
THD* thd= current_thd;
|
||||||
|
locale= thd->variables.lc_time_names;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Must use this_item() in case it's a local SP variable
|
Must use this_item() in case it's a local SP variable
|
||||||
(for ->max_length and ->str_value)
|
(for ->max_length and ->str_value)
|
||||||
@ -1889,7 +1889,7 @@ String *Item_func_date_format::val_str(String *str)
|
|||||||
if (!make_date_time(&date_time_format, &l_time,
|
if (!make_date_time(&date_time_format, &l_time,
|
||||||
is_time_format ? MYSQL_TIMESTAMP_TIME :
|
is_time_format ? MYSQL_TIMESTAMP_TIME :
|
||||||
MYSQL_TIMESTAMP_DATE,
|
MYSQL_TIMESTAMP_DATE,
|
||||||
str))
|
locale, str))
|
||||||
return str;
|
return str;
|
||||||
|
|
||||||
null_date:
|
null_date:
|
||||||
@ -1900,8 +1900,9 @@ null_date:
|
|||||||
|
|
||||||
void Item_func_from_unixtime::fix_length_and_dec()
|
void Item_func_from_unixtime::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
thd= current_thd;
|
THD *thd= current_thd;
|
||||||
thd->time_zone_used= 1;
|
thd->time_zone_used= 1;
|
||||||
|
tz= thd->variables.time_zone;
|
||||||
decimals= args[0]->decimals;
|
decimals= args[0]->decimals;
|
||||||
Item_temporal_func::fix_length_and_dec();
|
Item_temporal_func::fix_length_and_dec();
|
||||||
}
|
}
|
||||||
@ -1922,7 +1923,7 @@ bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime,
|
|||||||
if (args[0]->null_value || sign || sec > TIMESTAMP_MAX_VALUE)
|
if (args[0]->null_value || sign || sec > TIMESTAMP_MAX_VALUE)
|
||||||
return (null_value= 1);
|
return (null_value= 1);
|
||||||
|
|
||||||
thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)sec);
|
tz->gmt_sec_to_TIME(ltime, (my_time_t)sec);
|
||||||
|
|
||||||
ltime->second_part= sec_part;
|
ltime->second_part= sec_part;
|
||||||
|
|
||||||
|
@ -688,6 +688,7 @@ public:
|
|||||||
|
|
||||||
class Item_func_date_format :public Item_str_func
|
class Item_func_date_format :public Item_str_func
|
||||||
{
|
{
|
||||||
|
MY_LOCALE *locale;
|
||||||
int fixed_length;
|
int fixed_length;
|
||||||
const bool is_time_format;
|
const bool is_time_format;
|
||||||
String value;
|
String value;
|
||||||
@ -705,7 +706,7 @@ public:
|
|||||||
|
|
||||||
class Item_func_from_unixtime :public Item_temporal_func
|
class Item_func_from_unixtime :public Item_temporal_func
|
||||||
{
|
{
|
||||||
THD *thd;
|
Time_zone *tz;
|
||||||
public:
|
public:
|
||||||
Item_func_from_unixtime(Item *a) :Item_temporal_func(a) {}
|
Item_func_from_unixtime(Item *a) :Item_temporal_func(a) {}
|
||||||
const char *func_name() const { return "from_unixtime"; }
|
const char *func_name() const { return "from_unixtime"; }
|
||||||
@ -1046,10 +1047,4 @@ public:
|
|||||||
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Function prototypes */
|
|
||||||
|
|
||||||
bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
|
||||||
timestamp_type type, String *str);
|
|
||||||
|
|
||||||
#endif /* ITEM_TIMEFUNC_INCLUDED */
|
#endif /* ITEM_TIMEFUNC_INCLUDED */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user