From 0b52b28b91eac1018d865f2f918b83c416565f2f Mon Sep 17 00:00:00 2001 From: Jacob Mathew Date: Tue, 18 Apr 2017 17:36:05 -0700 Subject: [PATCH] MDEV-10355 Weird error message upon CREATE TABLE with DEFAULT Fixed handling of default values with cached temporal functions so that the CREATE TABLE statement now succeeds. Fixed virtual column session cleanup. Fixed the error message. Added quoting of date/time values in cases when this was omitted. Added a test case in default.test. Updated test result files. --- mysql-test/r/default.result | 15 +++++++++ mysql-test/r/derived_cond_pushdown.result | 28 ++++++++--------- mysql-test/r/explain_json.result | 6 ++-- mysql-test/r/range.result | 18 +++++------ mysql-test/r/range_mrr_icp.result | 18 +++++------ mysql-test/r/type_time.result | 16 +++++----- mysql-test/t/default.test | 14 +++++++++ sql/item.cc | 38 +++++++++++++++-------- sql/item.h | 29 +++++++++++++++++ sql/table.cc | 7 +++-- 10 files changed, 130 insertions(+), 59 deletions(-) diff --git a/mysql-test/r/default.result b/mysql-test/r/default.result index 4a3f25cb8f4..2780ed3b168 100644 --- a/mysql-test/r/default.result +++ b/mysql-test/r/default.result @@ -1941,6 +1941,21 @@ SELECT * FROM t1; a b c 2003-02-01 2003-05-01 12:05:55 128885 DROP TABLE t1; +CREATE OR REPLACE TABLE t1 ( col INT DEFAULT ( 1 LIKE ( NOW() BETWEEN '2000-01-01' AND '2012-12-12' ) ) ); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `col` int(11) DEFAULT (1 like (current_timestamp() between '2000-01-01' and '2012-12-12')) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SET timestamp = UNIX_TIMESTAMP( '2004-04-04' ); +INSERT INTO t1 VALUES( DEFAULT ); +SET timestamp = DEFAULT; +INSERT INTO t1 VALUES( DEFAULT ); +SELECT * FROM t1; +col +1 +0 +DROP TABLE t1; # # Hybrid type functions # diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result index 021633200e1..d51b01b6690 100644 --- a/mysql-test/r/derived_cond_pushdown.result +++ b/mysql-test/r/derived_cond_pushdown.result @@ -7118,7 +7118,7 @@ EXPLAIN { "query_block": { "select_id": 1, - "const_condition": "0 or (2,(subquery#3))", + "const_condition": "2 < 2 or (2,(subquery#3))", "table": { "table_name": "t1", "access_type": "system", @@ -7202,7 +7202,7 @@ EXPLAIN { "query_block": { "select_id": 1, - "const_condition": "0 or (2,(subquery#3))", + "const_condition": "2 < 2 or (2,(subquery#3))", "table": { "table_name": "t1", "access_type": "system", @@ -7668,7 +7668,7 @@ EXPLAIN "access_type": "ALL", "rows": 2, "filtered": 100, - "attached_condition": "v1.b = 2", + "attached_condition": "v1.b = count(t2.c)", "materialized": { "query_block": { "select_id": 3, @@ -7725,7 +7725,7 @@ EXPLAIN "access_type": "ALL", "rows": 2, "filtered": 100, - "attached_condition": "v1.f = 2", + "attached_condition": "v1.f = count(t.pk)", "materialized": { "query_block": { "select_id": 3, @@ -7745,7 +7745,7 @@ EXPLAIN "access_type": "ALL", "rows": 2, "filtered": 100, - "attached_condition": "v2.pk > 2" + "attached_condition": "v2.pk > count(t.pk)" }, "buffer_type": "flat", "buffer_size": "256Kb", @@ -7804,7 +7804,7 @@ EXPLAIN "access_type": "ALL", "rows": 3, "filtered": 100, - "attached_condition": "sq.i = 3", + "attached_condition": "sq.i = min(t2.j)", "materialized": { "query_block": { "select_id": 2, @@ -7861,7 +7861,7 @@ EXPLAIN "access_type": "ALL", "rows": 3, "filtered": 100, - "attached_condition": "sq.i = 2.7100000381469727", + "attached_condition": "sq.i = min(t2.j)", "materialized": { "query_block": { "select_id": 2, @@ -7913,7 +7913,7 @@ EXPLAIN "access_type": "ALL", "rows": 3, "filtered": 100, - "attached_condition": "sq.i = 3.21", + "attached_condition": "sq.i = min(t2.j)", "materialized": { "query_block": { "select_id": 2, @@ -7965,7 +7965,7 @@ EXPLAIN "access_type": "ALL", "rows": 3, "filtered": 100, - "attached_condition": "sq.i = 'aa'", + "attached_condition": "sq.i = min(t2.j)", "materialized": { "query_block": { "select_id": 2, @@ -8019,7 +8019,7 @@ EXPLAIN "access_type": "ALL", "rows": 3, "filtered": 100, - "attached_condition": "sq.i = 2007-05-28 00:00:00", + "attached_condition": "sq.i = min(t2.j)", "materialized": { "query_block": { "select_id": 2, @@ -8071,7 +8071,7 @@ EXPLAIN "access_type": "ALL", "rows": 3, "filtered": 100, - "attached_condition": "sq.i = 2007-05-28", + "attached_condition": "sq.i = min(t2.j)", "materialized": { "query_block": { "select_id": 2, @@ -8123,7 +8123,7 @@ EXPLAIN "access_type": "ALL", "rows": 3, "filtered": 100, - "attached_condition": "sq.i = 10:00:02", + "attached_condition": "sq.i = min(t2.j)", "materialized": { "query_block": { "select_id": 2, @@ -8214,7 +8214,7 @@ EXPLAIN "access_type": "ALL", "rows": 2, "filtered": 100, - "attached_condition": "v1.c = NULL", + "attached_condition": "v1.c = min(t2.c)", "materialized": { "query_block": { "select_id": 3, @@ -8317,7 +8317,7 @@ EXPLAIN "access_type": "ALL", "rows": 2, "filtered": 100, - "attached_condition": "((1,(subquery#2))) or v1.c = 'foo'", + "attached_condition": "(1,(subquery#2)) or v1.c = 'foo'", "materialized": { "query_block": { "select_id": 3, diff --git a/mysql-test/r/explain_json.result b/mysql-test/r/explain_json.result index 1af67cf6a4e..f416e5c2554 100644 --- a/mysql-test/r/explain_json.result +++ b/mysql-test/r/explain_json.result @@ -811,7 +811,7 @@ EXPLAIN "ref": ["func"], "rows": 2, "filtered": 100, - "attached_condition": "trigcond((outer_t1.a) = t1.a or t1.a is null)", + "attached_condition": "trigcond(outer_t1.a = t1.a or t1.a is null)", "using_index": true } }, @@ -825,7 +825,7 @@ EXPLAIN "buffer_type": "flat", "buffer_size": "256Kb", "join_type": "BNL", - "attached_condition": "t2.b <> outer_t1.a and trigcond((outer_t1.a) = t1.a or t1.a is null)" + "attached_condition": "t2.b <> outer_t1.a and trigcond(outer_t1.a = t1.a or t1.a is null)" } } } @@ -1106,7 +1106,7 @@ EXPLAIN "access_type": "ALL", "rows": 2, "filtered": 100, - "attached_condition": "(case when convert(t1.a using utf8) = (_utf8'a' collate utf8_bin) then NULL else t1.a end)" + "attached_condition": "(case when convert(t1.a using utf8) = _utf8'a' collate utf8_bin then NULL else t1.a end)" } } } diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 28f5cf635d0..3c57ab980c3 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -2371,7 +2371,7 @@ EXPLAIN "used_key_parts": ["a", "b"], "rows": 7, "filtered": 100, - "attached_condition": "(t1.a,t1.b) in (((2,3)),((3,3)),((8,8)),((7,7)))" + "attached_condition": "(t1.a,t1.b) in ((2,3),(3,3),(8,8),(7,7))" } } } @@ -2431,7 +2431,7 @@ EXPLAIN "used_key_parts": ["a"], "rows": 5, "filtered": 100, - "attached_condition": "(t1.a,t1.b + t1.a) in (((4,9)),((8,8)),((7,7)))" + "attached_condition": "(t1.a,t1.b + t1.a) in ((4,9),(8,8),(7,7))" } } } @@ -2498,7 +2498,7 @@ EXPLAIN "rows": 3, "filtered": 100, "index_condition": "t2.d is not null", - "attached_condition": "(t2.d,t2.e) in (((3,3)),((7,7)),((2,2)))" + "attached_condition": "(t2.d,t2.e) in ((3,3),(7,7),(2,2))" }, "table": { "table_name": "t1", @@ -2581,7 +2581,7 @@ EXPLAIN "ref": ["test.t1.a"], "rows": 12, "filtered": 100, - "attached_condition": "(t1.a,t2.e) in (((3,3)),((7,7)),((8,8))) and length(t2.f) = 1" + "attached_condition": "(t1.a,t2.e) in ((3,3),(7,7),(8,8)) and length(t2.f) = 1" } } } @@ -2666,7 +2666,7 @@ EXPLAIN "used_key_parts": ["e"], "rows": 6, "filtered": 100, - "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and length(t2.f) = 1 and t2.d is not null" + "attached_condition": "(t2.d,t2.e) in ((4,4),(7,7),(8,8)) and length(t2.f) = 1 and t2.d is not null" }, "table": { "table_name": "t1", @@ -2716,7 +2716,7 @@ EXPLAIN "rows": 5, "filtered": 100, "index_condition": "t2.d is not null", - "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and length(t2.f) = 1" + "attached_condition": "(t2.d,t2.e) in ((4,4),(7,7),(8,8)) and length(t2.f) = 1" }, "table": { "table_name": "t1", @@ -2830,7 +2830,7 @@ EXPLAIN "ref": ["test.t1.a"], "rows": 3, "filtered": 100, - "attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),((7,7)),((8,8))) and length(t2.f) = 1" + "attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),(7,7),(8,8)) and length(t2.f) = 1" } } } @@ -2870,7 +2870,7 @@ EXPLAIN "rows": 13, "filtered": 100, "index_condition": "t1.a is not null", - "attached_condition": "(t1.a,2) in (((2,2)),((7,7)),((8,8))) and length(t1.c) = 1" + "attached_condition": "(t1.a,2) in ((2,2),(7,7),(8,8)) and length(t1.c) = 1" }, "table": { "table_name": "t2", @@ -2958,7 +2958,7 @@ EXPLAIN "rows": 13, "filtered": 100, "index_condition": "t1.a is not null", - "attached_condition": "(t1.a,1 + 1) in (((2,2)),((7,7)),((8,8))) and length(t1.c) = 1" + "attached_condition": "(t1.a,1 + 1) in ((2,2),(7,7),(8,8)) and length(t1.c) = 1" }, "table": { "table_name": "t2", diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result index f2860aaab76..445f0877586 100644 --- a/mysql-test/r/range_mrr_icp.result +++ b/mysql-test/r/range_mrr_icp.result @@ -2373,7 +2373,7 @@ EXPLAIN "used_key_parts": ["a", "b"], "rows": 7, "filtered": 100, - "attached_condition": "(t1.a,t1.b) in (((2,3)),((3,3)),((8,8)),((7,7)))", + "attached_condition": "(t1.a,t1.b) in ((2,3),(3,3),(8,8),(7,7))", "mrr_type": "Rowid-ordered scan" } } @@ -2434,7 +2434,7 @@ EXPLAIN "used_key_parts": ["a"], "rows": 5, "filtered": 100, - "attached_condition": "(t1.a,t1.b + t1.a) in (((4,9)),((8,8)),((7,7)))", + "attached_condition": "(t1.a,t1.b + t1.a) in ((4,9),(8,8),(7,7))", "mrr_type": "Rowid-ordered scan" } } @@ -2503,7 +2503,7 @@ EXPLAIN "rows": 3, "filtered": 100, "index_condition": "t2.d is not null", - "attached_condition": "(t2.d,t2.e) in (((3,3)),((7,7)),((2,2)))", + "attached_condition": "(t2.d,t2.e) in ((3,3),(7,7),(2,2))", "mrr_type": "Rowid-ordered scan" }, "table": { @@ -2588,7 +2588,7 @@ EXPLAIN "ref": ["test.t1.a"], "rows": 12, "filtered": 100, - "attached_condition": "(t1.a,t2.e) in (((3,3)),((7,7)),((8,8))) and length(t2.f) = 1" + "attached_condition": "(t1.a,t2.e) in ((3,3),(7,7),(8,8)) and length(t2.f) = 1" } } } @@ -2673,7 +2673,7 @@ EXPLAIN "used_key_parts": ["e"], "rows": 6, "filtered": 100, - "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and length(t2.f) = 1 and t2.d is not null", + "attached_condition": "(t2.d,t2.e) in ((4,4),(7,7),(8,8)) and length(t2.f) = 1 and t2.d is not null", "mrr_type": "Rowid-ordered scan" }, "table": { @@ -2724,7 +2724,7 @@ EXPLAIN "rows": 5, "filtered": 100, "index_condition": "t2.d is not null", - "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and length(t2.f) = 1", + "attached_condition": "(t2.d,t2.e) in ((4,4),(7,7),(8,8)) and length(t2.f) = 1", "mrr_type": "Rowid-ordered scan" }, "table": { @@ -2840,7 +2840,7 @@ EXPLAIN "ref": ["test.t1.a"], "rows": 3, "filtered": 100, - "attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),((7,7)),((8,8))) and length(t2.f) = 1" + "attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),(7,7),(8,8)) and length(t2.f) = 1" } } } @@ -2880,7 +2880,7 @@ EXPLAIN "rows": 13, "filtered": 100, "index_condition": "t1.a is not null", - "attached_condition": "(t1.a,2) in (((2,2)),((7,7)),((8,8))) and length(t1.c) = 1", + "attached_condition": "(t1.a,2) in ((2,2),(7,7),(8,8)) and length(t1.c) = 1", "mrr_type": "Rowid-ordered scan" }, "table": { @@ -2969,7 +2969,7 @@ EXPLAIN "rows": 13, "filtered": 100, "index_condition": "t1.a is not null", - "attached_condition": "(t1.a,1 + 1) in (((2,2)),((7,7)),((8,8))) and length(t1.c) = 1", + "attached_condition": "(t1.a,1 + 1) in ((2,2),(7,7),(8,8)) and length(t1.c) = 1", "mrr_type": "Rowid-ordered scan" }, "table": { diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index a827fb19943..2aabd98229d 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -989,7 +989,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=TIME('00:00:00') AND COALESCE(a)=DATE('2015-0 id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 00:00:00 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '00:00:00' # TIME cast + DATE literal SELECT * FROM t1 WHERE COALESCE(a)=TIME('00:00:00') AND COALESCE(a)=DATE'2015-09-11'; a @@ -999,7 +999,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=TIME('00:00:00') AND COALESCE(a)=DATE'2015-09 id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 00:00:00 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '00:00:00' # TIME literal + DATE cast SELECT * FROM t1 WHERE COALESCE(a)=TIME'00:00:00' AND COALESCE(a)=DATE('2015-09-11'); a @@ -1029,7 +1029,7 @@ SELECT * FROM t1 WHERE COALESCE(a)='00:00:00' AND COALESCE(a)=DATE('2015-09-11') id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '00:00:00' and coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '00:00:00' and coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00' # TIME-alike string literal + DATE literal SELECT * FROM t1 WHERE COALESCE(a)='00:00:00' AND COALESCE(a)=DATE'2015-09-11'; a @@ -1049,7 +1049,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=0 AND COALESCE(a)=DATE('2015-09-11'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 0 and coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 0 and coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00' # TIME-alike integer literal + DATE literal SELECT * FROM t1 WHERE COALESCE(a)=0 AND COALESCE(a)=DATE'2015-09-11'; a @@ -1069,7 +1069,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)=TIME('00:0 id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00' # DATE cast + TIME literal SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)=TIME'00:00:00'; a @@ -1079,7 +1079,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)=TIME'00:00 id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00' # DATE cast + TIME-alike string literal SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)='00:00:00'; a @@ -1089,7 +1089,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)='00:00:00' id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00 and coalesce(`test`.`t1`.`a`) = '00:00:00' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00' and coalesce(`test`.`t1`.`a`) = '00:00:00' # DATE cast + TIME-alike integer literal SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)=0; a @@ -1099,7 +1099,7 @@ SELECT * FROM t1 WHERE COALESCE(a)=DATE('2015-09-11') AND COALESCE(a)=0; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = 2015-09-11 00:00:00 and coalesce(`test`.`t1`.`a`) = 0 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where coalesce(`test`.`t1`.`a`) = '2015-09-11 00:00:00' and coalesce(`test`.`t1`.`a`) = 0 # DATE literal + TIME cast SELECT * FROM t1 WHERE COALESCE(a)=DATE'2015-09-11' AND COALESCE(a)=TIME('00:00:00'); a diff --git a/mysql-test/t/default.test b/mysql-test/t/default.test index 85f99806fc9..84ef620de04 100644 --- a/mysql-test/t/default.test +++ b/mysql-test/t/default.test @@ -1289,6 +1289,20 @@ INSERT INTO t1 (a,b) VALUES ('2003-02-01','2003-05-01 12:05:55'); SELECT * FROM t1; DROP TABLE t1; +# +# MDEV-10355 Weird error message upon CREATE TABLE with DEFAULT +# +# Column default value expression that includes a temporal function +# +CREATE OR REPLACE TABLE t1 ( col INT DEFAULT ( 1 LIKE ( NOW() BETWEEN '2000-01-01' AND '2012-12-12' ) ) ); +SHOW CREATE TABLE t1; +SET timestamp = UNIX_TIMESTAMP( '2004-04-04' ); +INSERT INTO t1 VALUES( DEFAULT ); +SET timestamp = DEFAULT; +INSERT INTO t1 VALUES( DEFAULT ); +SELECT * FROM t1; +DROP TABLE t1; + --echo # --echo # Hybrid type functions diff --git a/sql/item.cc b/sql/item.cc index 446176ff398..5d6c4bb67a6 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -616,8 +616,9 @@ void Item::print_value(String *str) str->append("NULL"); else { - switch (result_type()) { + switch (cmp_type()) { case STRING_RESULT: + case TIME_RESULT: append_unescaped(str, ptr->ptr(), ptr->length()); break; case DECIMAL_RESULT: @@ -626,7 +627,6 @@ void Item::print_value(String *str) str->append(*ptr); break; case ROW_RESULT: - case TIME_RESULT: DBUG_ASSERT(0); } } @@ -4110,7 +4110,7 @@ Item_param::eq(const Item *item, bool binary_cmp) const void Item_param::print(String *str, enum_query_type query_type) { - if (state == NO_VALUE || query_type & QT_NO_DATA_EXPANSION) + if (state == NO_VALUE) { str->append('?'); } @@ -9417,17 +9417,28 @@ void Item_cache::store(Item *item) void Item_cache::print(String *str, enum_query_type query_type) { - if (value_cached) + if (example && // There is a cached item + (query_type & QT_ITEM_CACHE_WRAPPER_SKIP_DETAILS)) // Caller is show-create-table { - print_value(str); - return; - } - str->append(STRING_WITH_LEN("(")); - if (example) + // Instead of "cache" or the cached value, print the cached item name example->print(str, query_type); + } else - Item::print(str, query_type); - str->append(')'); + { + if (value_cached && !(query_type & QT_NO_DATA_EXPANSION)) + { + print_value(str); + return; + } + if (!(query_type & QT_ITEM_CACHE_WRAPPER_SKIP_DETAILS)) + str->append(STRING_WITH_LEN("(")); + if (example) + example->print(str, query_type); + else + Item::print(str, query_type); + if (!(query_type & QT_ITEM_CACHE_WRAPPER_SKIP_DETAILS)) + str->append(')'); + } } /** @@ -9653,7 +9664,7 @@ int Item_cache_temporal::save_in_field(Field *field, bool no_conversions) void Item_cache_temporal::store_packed(longlong val_arg, Item *example_arg) { - /* An explicit values is given, save it. */ + /* An explicit value is given, save it. */ store(example_arg); value_cached= true; value= val_arg; @@ -10659,6 +10670,7 @@ void Virtual_column_info::print(String *str) QT_ITEM_IDENT_SKIP_DB_NAMES | QT_ITEM_IDENT_SKIP_TABLE_NAMES | QT_ITEM_CACHE_WRAPPER_SKIP_DETAILS | - QT_TO_SYSTEM_CHARSET), + QT_TO_SYSTEM_CHARSET | + QT_NO_DATA_EXPANSION), LOWEST_PRECEDENCE); } diff --git a/sql/item.h b/sql/item.h index 078641c490c..a0137144140 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1551,6 +1551,7 @@ public: /*========= Item processors, to be used with Item::walk() ========*/ virtual bool remove_dependence_processor(void *arg) { return 0; } virtual bool cleanup_processor(void *arg); + virtual bool cleanup_excluding_fields_processor(void *arg) { return cleanup_processor(arg); } virtual bool cleanup_excluding_const_fields_processor(void *arg) { return cleanup_processor(arg); } virtual bool collect_item_field_processor(void *arg) { return 0; } virtual bool collect_outer_ref_processor(void *arg) {return 0; } @@ -2634,6 +2635,8 @@ public: virtual void print(String *str, enum_query_type query_type); bool exclusive_dependence_on_table_processor(void *map); bool exclusive_dependence_on_grouping_fields_processor(void *arg); + bool cleanup_excluding_fields_processor(void *arg) + { return field ? 0 : cleanup_processor(arg); } bool cleanup_excluding_const_fields_processor(void *arg) { return field && const_item() ? 0 : cleanup_processor(arg); } @@ -4324,6 +4327,14 @@ public: { return depended_from != NULL; } bool exclusive_dependence_on_grouping_fields_processor(void *arg) { return depended_from != NULL; } + bool cleanup_excluding_fields_processor(void *arg) + { + Item *item= real_item(); + if (item && item->type() == FIELD_ITEM && + ((Item_field *)item)->field) + return 0; + return cleanup_processor(arg); + } bool cleanup_excluding_const_fields_processor(void *arg) { Item *item= real_item(); @@ -5460,8 +5471,26 @@ public: } bool check_vcol_func_processor(void *arg) { + if (example) + { + Item::vcol_func_processor_result *res= (Item::vcol_func_processor_result*)arg; + example->check_vcol_func_processor(arg); + if (res->errors & VCOL_NOT_STRICTLY_DETERMINISTIC) + res->errors|= VCOL_SESSION_FUNC; + return false; + } return mark_unsupported_function("cache", arg, VCOL_IMPOSSIBLE); } + bool cleanup_excluding_fields_processor(void* arg) + { + cleanup(); + return 0; + } + void cleanup() + { + clear(); + Item_basic_constant::cleanup(); + } /** Check if saved item has a non-NULL value. Will cache value of saved item if not already done. diff --git a/sql/table.cc b/sql/table.cc index 380da5fcd7b..398383efccd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2725,7 +2725,7 @@ bool fix_session_vcol_expr(THD *thd, Virtual_column_info *vcol) if (!(vcol->flags & (VCOL_TIME_FUNC|VCOL_SESSION_FUNC))) DBUG_RETURN(0); - vcol->expr->cleanup(); + vcol->expr->walk(&Item::cleanup_excluding_fields_processor, 0, 0); DBUG_ASSERT(!vcol->expr->fixed); DBUG_RETURN(fix_vcol_expr(thd, vcol)); } @@ -2809,9 +2809,10 @@ static bool fix_and_check_vcol_expr(THD *thd, TABLE *table, int error= func_expr->walk(&Item::check_vcol_func_processor, 0, &res); if (error || (res.errors & VCOL_IMPOSSIBLE)) - { // this can only happen if the frm was corrupted + { + // this can only happen if the frm was corrupted my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), res.name, - "???", "?????"); + vcol->get_vcol_type_name(), vcol->name.str); DBUG_RETURN(1); } else if (res.errors & VCOL_AUTO_INC)