Skip to content

Commit

Permalink
session-state dependent functions in DEFAULT/CHECK/vcols
Browse files Browse the repository at this point in the history
* revert part of the db7edfe that moved calculations from
  fix_fields to val_str for Item_func_sysconst and descendants
* mark session state dependent functions in check_vcol_func_processor()
* re-run fix_fields for all such functions for every statement
* fix CURRENT_USER/CURRENT_ROLE not to use Name_resolution_context
  (that is allocated on the stack in unpack_vcol_info_from_frm())

Note that NOW(), CURDATE(), etc use lazy initialization and do *not*
force fix_fields to be re-run. The rule is:
* lazy initialization is *not* allowed, if it changes metadata (so,
   e.g. DAYNAME() cannot use it)
* lazy initialization is *preferrable* if it has side effects (e.g.
  NOW() sets thd->time_zone_used=1, so it's better to do it when
  the value of NOW is actually needed, not when NOW is simply prepared)
  • Loading branch information
vuvova committed Aug 27, 2016
1 parent eb9bce5 commit 73a220a
Show file tree
Hide file tree
Showing 20 changed files with 422 additions and 222 deletions.
33 changes: 0 additions & 33 deletions mysql-test/r/default.result
Original file line number Diff line number Diff line change
Expand Up @@ -1084,33 +1084,6 @@ a b
20010101102030 2001
DROP TABLE t1;
#
# Miscelaneous SQL standard <default option> variants
#
CREATE TABLE t1 (a VARCHAR(30) DEFAULT CURRENT_USER);
ERROR HY000: Function or expression 'current_user()' cannot be used in the DEFAULT clause of `a`
CREATE TABLE t1 (a VARCHAR(30) DEFAULT CURRENT_ROLE);
ERROR HY000: Function or expression 'current_role()' cannot be used in the DEFAULT clause of `a`
#
# Other Item_func_sysconst derived functions
#
CREATE TABLE t1 (a VARCHAR(30) DEFAULT DATABASE());
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(30) DEFAULT DATABASE()
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ();
USE INFORMATION_SCHEMA;
INSERT INTO test.t1 VALUES ();
USE test;
INSERT INTO t1 VALUES ();
SELECT * FROM t1;
a
test
information_schema
test
DROP TABLE t1;
#
# Check DEFAULT() function
#
CREATE TABLE `t1` (`a` int(11) DEFAULT (3+3),`b` int(11) DEFAULT '1000');
Expand Down Expand Up @@ -1400,8 +1373,6 @@ SELECT * FROM t1;
a b c
01,5,2013 %d,%m,%Y 2013-05-01
DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(30), b VARCHAR(30) DEFAULT DATE_FORMAT(a,'%W %M %Y'));
ERROR HY000: Function or expression 'date_format()' cannot be used in the DEFAULT clause of `b`
# Item_datefunc
SET time_zone='-10:00';
SET timestamp=UNIX_TIMESTAMP('2001-01-01 23:59:59');
Expand Down Expand Up @@ -1835,10 +1806,6 @@ SELECT * FROM t1;
a b
2008-04-01 2
DROP TABLE t1;
CREATE TABLE t1 (a DATE, b VARCHAR(30) DEFAULT DAYNAME(a));
ERROR HY000: Function or expression 'dayname()' cannot be used in the DEFAULT clause of `b`
CREATE TABLE t1 (a DATE, b VARCHAR(30) DEFAULT MONTHNAME(a));
ERROR HY000: Function or expression 'monthname()' cannot be used in the DEFAULT clause of `b`
CREATE TABLE t1 (a DATE, b INT DEFAULT EXTRACT(YEAR FROM a));
SHOW CREATE TABLE t1;
Table Create Table
Expand Down
94 changes: 94 additions & 0 deletions mysql-test/r/default_session.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
create database mysqltest1;
create user ''@localhost;
create user foo@localhost;
create role bar;
grant select on *.* to ''@localhost;
grant select,insert on *.* to foo@localhost;
grant select,insert on *.* to bar;
grant bar to ''@localhost;
create table t1 (n varchar(100),
u varchar(100) default user(),
cu varchar(100) default current_user(),
cr varchar(100) default current_role(),
d varchar(100) default database());
create definer=foo@localhost view mysqltest1.v1 as select * from t1;
create definer=bar view v2 as select * from t1;
create view v3 as select * from v2;
create definer=foo@localhost view mysqltest1.v4 as select default(n),default(u),default(cu),default(cr), default(d) from t1;
create definer=bar view v5 as select default(n),default(u),default(cu),default(cr), default(d) from t1;
create view v6 as select * from v5;
insert t1 (n) values ('t1');
insert mysqltest1.v1 (n) values ('v1');
insert v2 (n) values ('v2');
insert v3 (n) values ('v3');
select default(n),default(u),default(cu),default(cr), default(d) from t1 limit 1;
default(n) default(u) default(cu) default(cr) default(d)
NULL root@localhost root@localhost NULL test
select * from mysqltest1.v4 limit 1;
default(n) default(u) default(cu) default(cr) default(d)
NULL root@localhost foo@localhost NULL test
select * from v5 limit 1;
default(n) default(u) default(cu) default(cr) default(d)
NULL root@localhost @ bar test
select * from v6 limit 1;
default(n) default(u) default(cu) default(cr) default(d)
NULL root@localhost @ bar test
connect conn,localhost,conn,,mysqltest1;
set role bar;
insert test.t1 (n) values ('t1');
insert v1 (n) values ('v1');
insert test.v2 (n) values ('v2');
insert test.v3 (n) values ('v3');
select default(n),default(u),default(cu),default(cr), default(d) from test.t1 limit 1;
default(n) default(u) default(cu) default(cr) default(d)
NULL conn@localhost @localhost bar mysqltest1
select * from v4 limit 1;
default(n) default(u) default(cu) default(cr) default(d)
NULL conn@localhost foo@localhost NULL mysqltest1
select * from test.v5 limit 1;
default(n) default(u) default(cu) default(cr) default(d)
NULL conn@localhost @ bar mysqltest1
select * from test.v6 limit 1;
default(n) default(u) default(cu) default(cr) default(d)
NULL conn@localhost @ bar mysqltest1
connection default;
disconnect conn;
select * from t1;
n u cu cr d
t1 root@localhost root@localhost NULL test
v1 root@localhost foo@localhost NULL test
v2 root@localhost @ bar test
v3 root@localhost @ bar test
t1 conn@localhost @localhost bar mysqltest1
v1 conn@localhost foo@localhost NULL mysqltest1
v2 conn@localhost @ bar mysqltest1
v3 conn@localhost @ bar mysqltest1
drop database mysqltest1;
drop view v2, v3, v5, v6;
drop table t1;
drop user ''@localhost;
drop user foo@localhost;
drop role bar;
create table t1 (a date,
mn varchar(100) default monthname(a),
dn varchar(100) default dayname(a),
df varchar(100) default date_format(a, "%a, %b"));
insert t1 (a) values ('2010-12-2');
set lc_time_names=de_DE;
insert t1 (a) values ('2010-12-2');
set lc_time_names=default;
select * from t1;
a mn dn df
2010-12-02 December Thursday Thu, Dec
2010-12-02 Dezember Donnerstag Do, Dez
drop table t1;
create table t1 (a varchar(100) default @@sql_mode);
insert t1 () values ();
set sql_mode=ansi;
insert t1 () values ();
set sql_mode=default;
select * from t1;
a
NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI
drop table t1;
6 changes: 0 additions & 6 deletions mysql-test/suite/vcol/r/not_supported.result
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ create table t4 (a int, b int, v int as (@a:=a));
ERROR HY000: Function or expression '@a' cannot be used in the GENERATED ALWAYS AS clause of `v`
create table t4 (a int, b int, v int as (@a:=a) PERSISTENT);
ERROR HY000: Function or expression '@a' cannot be used in the GENERATED ALWAYS AS clause of `v`
create table t5 (a int, b int, v varchar(100) as (monthname(a)));
ERROR HY000: Function or expression 'monthname()' cannot be used in the GENERATED ALWAYS AS clause of `v`
create table t6 (a int, b int, v varchar(100) as (dayname(a)));
ERROR HY000: Function or expression 'dayname()' cannot be used in the GENERATED ALWAYS AS clause of `v`
create table t7 (a int, b int, v varchar(100) as (date_format(a, '%W %a %M %b')));
ERROR HY000: Function or expression 'date_format()' cannot be used in the GENERATED ALWAYS AS clause of `v`
create table t8 (a int, b int, v varchar(100) as (from_unixtime(a)));
insert t1 (a,b) values (1,2);
insert t8 (a,b) values (1234567890,2);
Expand Down
19 changes: 0 additions & 19 deletions mysql-test/suite/vcol/r/vcol_blocked_sql_funcs.result
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,6 @@ create or replace table t1 (a varchar(64), b varchar(64) as (collation(a)) PERSI
create or replace table t1 (a int as (connection_id()));
create or replace table t1 (a int as (connection_id()) PERSISTENT);
ERROR HY000: Function or expression 'connection_id()' cannot be used in the GENERATED ALWAYS AS clause of `a`
# CURRENT_USER(), CURRENT_USER
create or replace table t1 (a varchar(32) as (current_user()));
ERROR HY000: Function or expression 'current_user()' cannot be used in the GENERATED ALWAYS AS clause of `a`
create or replace table t1 (a varchar(32) as (current_user()) PERSISTENT);
ERROR HY000: Function or expression 'current_user()' cannot be used in the GENERATED ALWAYS AS clause of `a`
create or replace table t1 (a varchar(32) as (current_user) PERSISTENT);
ERROR HY000: Function or expression 'current_user()' cannot be used in the GENERATED ALWAYS AS clause of `a`
# DATABASE()
create or replace table t1 (a varchar(32) as (database()));
create or replace table t1 (a varchar(1024), b varchar(1024) as (database()) PERSISTENT);
Expand Down Expand Up @@ -141,9 +134,6 @@ create or replace table t1 (a varchar(1024), b varchar(1024) as (version()) PERS
ERROR HY000: Function or expression 'version()' cannot be used in the GENERATED ALWAYS AS clause of `b`
# ENCRYPT()
create or replace table t1 (a varchar(1024), b varchar(1024) as (encrypt(a)) PERSISTENT);
# DATE_FORMAT()
create or replace table t1 (a datetime, b varchar(64) as (date_format(a,'%W %M %D'));
ERROR HY000: Function or expression 'date_format()' cannot be used in the GENERATED ALWAYS AS clause of `b`
# Stored procedures
create procedure p1()
begin
Expand Down Expand Up @@ -217,15 +207,6 @@ ERROR HY000: Function or expression 'var_samp()' cannot be used in the GENERATED
# VARIANCE()
create or replace table t1 (a int, b int as (variance(a)));
ERROR HY000: Function or expression 'variance()' cannot be used in the GENERATED ALWAYS AS clause of `b`
# DAYNAME()
create or replace table t1 (a int, b varchar(10) as (dayname(a)));
ERROR HY000: Function or expression 'dayname()' cannot be used in the GENERATED ALWAYS AS clause of `b`
create or replace table t1 (a int, b varchar(10) as (monthname(a)));
ERROR HY000: Function or expression 'monthname()' cannot be used in the GENERATED ALWAYS AS clause of `b`
create or replace table t1 (a int, b varchar(10) as (date_format("1963-01-01","%d.%m.%Y")));
ERROR HY000: Function or expression 'date_format()' cannot be used in the GENERATED ALWAYS AS clause of `b`
create or replace table t1 (a int, b varchar(10) as (time_format(now(),"%d.%m.%Y")));
ERROR HY000: Function or expression 'time_format()' cannot be used in the GENERATED ALWAYS AS clause of `b`
#
# XML FUNCTIONS
#
Expand Down
75 changes: 75 additions & 0 deletions mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result
Original file line number Diff line number Diff line change
Expand Up @@ -2831,3 +2831,78 @@ a b
a 30
drop table t1;
set sql_warnings = 0;
# MONTHNAME()
set sql_warnings = 1;
create table t1 (a date, b varchar(100) as (monthname(a)));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` varchar(100) AS (monthname(a)) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('2010-10-10',default);
select * from t1;
a b
2010-10-10 October
drop table t1;
set sql_warnings = 0;
# DAYNAME()
set sql_warnings = 1;
create table t1 (a date, b varchar(100) as (dayname(a)));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` varchar(100) AS (dayname(a)) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('2011-11-11',default);
select * from t1;
a b
2011-11-11 Friday
drop table t1;
set sql_warnings = 0;
# DATE_FORMAT()
set sql_warnings = 1;
create table t1 (a date, b varchar(100) as (date_format(a, '%W %a %M %b')));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` varchar(100) AS (date_format(a, '%W %a %M %b')) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('2012-12-12',default);
select * from t1;
a b
2012-12-12 Wednesday Wed December Dec
drop table t1;
set sql_warnings = 0;
# CURRENT_USER()
set sql_warnings = 1;
create table t1 (a char, b varchar(32) as (current_user()));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` char(1) DEFAULT NULL,
`b` varchar(32) AS (current_user()) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('a', default);
select * from t1;
a b
a root@localhost
drop table t1;
set sql_warnings = 0;
# TIME_FORMAT()
set sql_warnings = 1;
create table t1 (a datetime, b varchar(10) as (time_format(a,"%d.%m.%Y")));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` datetime DEFAULT NULL,
`b` varchar(10) AS (time_format(a,"%d.%m.%Y")) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('2001-01-01 02:02:02',default);
select * from t1;
a b
2001-01-01 02:02:02 01.01.2001
drop table t1;
set sql_warnings = 0;
6 changes: 0 additions & 6 deletions mysql-test/suite/vcol/t/not_supported.test
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ create table t3 (a int, b int, v int as (a+@@error_count) PERSISTENT);
create table t4 (a int, b int, v int as (@a:=a));
--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t4 (a int, b int, v int as (@a:=a) PERSISTENT);
--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t5 (a int, b int, v varchar(100) as (monthname(a)));
--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create table t6 (a int, b int, v varchar(100) as (dayname(a)));
--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
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);
Expand Down
25 changes: 0 additions & 25 deletions mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_main.inc
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,6 @@ create or replace table t1 (a int as (connection_id()));
-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t1 (a int as (connection_id()) PERSISTENT);

--echo # CURRENT_USER(), CURRENT_USER
-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t1 (a varchar(32) as (current_user()));
-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t1 (a varchar(32) as (current_user()) PERSISTENT);
-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t1 (a varchar(32) as (current_user) PERSISTENT);

--echo # DATABASE()
create or replace table t1 (a varchar(32) as (database()));
-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
Expand Down Expand Up @@ -204,10 +196,6 @@ create or replace table t1 (a varchar(1024), b varchar(1024) as (version()) PERS
--echo # ENCRYPT()
create or replace table t1 (a varchar(1024), b varchar(1024) as (encrypt(a)) PERSISTENT);

--echo # DATE_FORMAT()
-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t1 (a datetime, b varchar(64) as (date_format(a,'%W %M %D'));

--echo # Stored procedures

delimiter //;
Expand Down Expand Up @@ -308,19 +296,6 @@ create or replace table t1 (a int, b int as (var_samp(a)));
-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t1 (a int, b int as (variance(a)));

--echo # DAYNAME()
-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t1 (a int, b varchar(10) as (dayname(a)));

-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t1 (a int, b varchar(10) as (monthname(a)));

-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t1 (a int, b varchar(10) as (date_format("1963-01-01","%d.%m.%Y")));

-- error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
create or replace table t1 (a int, b varchar(10) as (time_format(now(),"%d.%m.%Y")));

--echo #
--echo # XML FUNCTIONS
--echo #
Expand Down
30 changes: 30 additions & 0 deletions mysql-test/suite/vcol/t/vcol_supported_sql_funcs_main.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1179,3 +1179,33 @@ let $values1 = 'a',default;
let $rows = 1;
--source suite/vcol/inc/vcol_supported_sql_funcs.inc

--echo # MONTHNAME()
let $cols = a date, b varchar(100) as (monthname(a));
let $values1 = '2010-10-10',default;
let $rows = 1;
--source suite/vcol/inc/vcol_supported_sql_funcs.inc

--echo # DAYNAME()
let $cols = a date, b varchar(100) as (dayname(a));
let $values1 = '2011-11-11',default;
let $rows = 1;
--source suite/vcol/inc/vcol_supported_sql_funcs.inc

--echo # DATE_FORMAT()
let $cols = a date, b varchar(100) as (date_format(a, '%W %a %M %b'));
let $values1 = '2012-12-12',default;
let $rows = 1;
--source suite/vcol/inc/vcol_supported_sql_funcs.inc

--echo # CURRENT_USER()
let $cols = a char, b varchar(32) as (current_user());
let $values1 = 'a', default;
let $rows = 1;
--source suite/vcol/inc/vcol_supported_sql_funcs.inc

--echo # TIME_FORMAT()
let $cols = a datetime, b varchar(10) as (time_format(a,"%d.%m.%Y"));
let $values1 = '2001-01-01 02:02:02',default;
let $rows = 1;
--source suite/vcol/inc/vcol_supported_sql_funcs.inc

Loading

0 comments on commit 73a220a

Please sign in to comment.