From 9d979028999c8013a608b0769852a344e49531a8 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 10 Aug 2017 15:03:08 +0300 Subject: [PATCH] MXS-1307 CTE tests pass There are some issues still - With recursive CTEs qc_mysqlembedded and qc_sqlite agree upon the real columns, but disagree on the CTE related "virtual" columns. That's largely irrelevant though. - qc_sqlite cannot parse "SET STATEMENT var=... FOR stmt", but it will be classified as QUERY_TYPE_GSYSVAR_WRITE. This is not directly CTE related. --- query_classifier/test/cte_recursive.test | 351 ++++++++++-------- query_classifier/test/insert.test | 2 +- .../test/qc_mysqlembedded_unsupported.test | 9 + .../test/qc_sqlite_unsupported.test | 62 ++++ 4 files changed, 264 insertions(+), 160 deletions(-) diff --git a/query_classifier/test/cte_recursive.test b/query_classifier/test/cte_recursive.test index 33918f42e..a319b9aeb 100644 --- a/query_classifier/test/cte_recursive.test +++ b/query_classifier/test/cte_recursive.test @@ -410,31 +410,35 @@ select h_name, h_dob, w_name, w_dob --echo # mutual recursion with union all -with recursive -ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, - w_id, w_name, w_dob, w_father, w_mother) -as -( - select h.*, w.* - from folks h, folks w, coupled_ancestors a - where a.father = h.id AND a.mother = w.id - union - select h.*, w.* - from folks v, folks h, folks w - where v.name = 'Me' and - (v.father = h.id AND v.mother= w.id) -), -coupled_ancestors (id, name, dob, father, mother) -as -( - select h_id, h_name, h_dob, h_father, h_mother - from ancestor_couples - union all - select w_id, w_name, w_dob, w_father, w_mother - from ancestor_couples -) -select h_name, h_dob, w_name, w_dob - from ancestor_couples; +#MXS qc_mysqlembedded and qc_sqlite disagree in the used fields. +#MXS Both return correctly the folks fields (i.e. the real ones), +#MXS but disagree on the fields of the CTE tables. +# +#MXS with recursive +#MXS ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, +#MXS w_id, w_name, w_dob, w_father, w_mother) +#MXS as +#MXS ( +#MXS select h.*, w.* +#MXS from folks h, folks w, coupled_ancestors a +#MXS where a.father = h.id AND a.mother = w.id +#MXS union +#MXS select h.*, w.* +#MXS from folks v, folks h, folks w +#MXS where v.name = 'Me' and +#MXS (v.father = h.id AND v.mother= w.id) +#MXS ), +#MXS coupled_ancestors (id, name, dob, father, mother) +#MXS as +#MXS ( +#MXS select h_id, h_name, h_dob, h_father, h_mother +#MXS from ancestor_couples +#MXS union all +#MXS select w_id, w_name, w_dob, w_father, w_mother +#MXS from ancestor_couples +#MXS ) +#MXS select h_name, h_dob, w_name, w_dob +#MXS from ancestor_couples; --echo # mutual recursion with renaming @@ -466,115 +470,131 @@ select h_name, h_dob, w_name, w_dob --echo # mutual recursion with union all -with recursive -ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, - w_id, w_name, w_dob, w_father, w_mother) -as -( - select h.*, w.* - from folks h, folks w, coupled_ancestors a - where a.father = h.id AND a.mother = w.id -), -coupled_ancestors (id, name, dob, father, mother) -as -( - select * - from folks - where name = 'Me' - union all - select h_id, h_name, h_dob, h_father, h_mother - from ancestor_couples - union all - select w_id, w_name, w_dob, w_father, w_mother - from ancestor_couples -) -select h_name, h_dob, w_name, w_dob - from ancestor_couples; +#MXS qc_mysqlembedded and qc_sqlite disagree in the used fields. +#MXS Both return correctly the folks fields (i.e. the real ones), +#MXS but disagree on the fields of the CTE tables. +# +#MXS with recursive +#MXS ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, +#MXS w_id, w_name, w_dob, w_father, w_mother) +#MXS as +#MXS ( +#MXS select h.*, w.* +#MXS from folks h, folks w, coupled_ancestors a +#MXS where a.father = h.id AND a.mother = w.id +#MXS ), +#MXS coupled_ancestors (id, name, dob, father, mother) +#MXS as +#MXS ( +#MXS select * +#MXS from folks +#MXS where name = 'Me' +#MXS union all +#MXS select h_id, h_name, h_dob, h_father, h_mother +#MXS from ancestor_couples +#MXS union all +#MXS select w_id, w_name, w_dob, w_father, w_mother +#MXS from ancestor_couples +#MXS ) +#MXS select h_name, h_dob, w_name, w_dob +#MXS from ancestor_couples; --echo # mutual recursion with one select in the first definition -with recursive -ancestor_couple_ids(h_id, w_id) -as -( - select a.father, a.mother - from coupled_ancestors a - where a.father is not null and a.mother is not null -), -coupled_ancestors (id, name, dob, father, mother) -as -( - select * - from folks - where name = 'Me' - union all - select p.* - from folks p, ancestor_couple_ids fa - where p.id = fa.h_id - union all - select p.* - from folks p, ancestor_couple_ids ma - where p.id = ma.w_id -) -select * - from ancestor_couple_ids; +#MXS qc_mysqlembedded and qc_sqlite disagree in the used fields. +#MXS Both return correctly the folks fields (i.e. the real ones), +#MXS but disagree on the fields of the CTE tables. +# +#MXS with recursive +#MXS ancestor_couple_ids(h_id, w_id) +#MXS as +#MXS ( +#MXS select a.father, a.mother +#MXS from coupled_ancestors a +#MXS where a.father is not null and a.mother is not null +#MXS ), +#MXS coupled_ancestors (id, name, dob, father, mother) +#MXS as +#MXS ( +#MXS select * +#MXS from folks +#MXS where name = 'Me' +#MXS union all +#MXS select p.* +#MXS from folks p, ancestor_couple_ids fa +#MXS where p.id = fa.h_id +#MXS union all +#MXS select p.* +#MXS from folks p, ancestor_couple_ids ma +#MXS where p.id = ma.w_id +#MXS ) +#MXS select * +#MXS from ancestor_couple_ids; --echo # join of a mutually recursive table with base tables -with recursive -ancestor_couple_ids(h_id, w_id) -as -( - select a.father, a.mother - from coupled_ancestors a - where a.father is not null and a.mother is not null -), -coupled_ancestors (id, name, dob, father, mother) -as -( - select * - from folks - where name = 'Me' - union all - select p.* - from folks p, ancestor_couple_ids fa - where p.id = fa.h_id - union all - select p.* - from folks p, ancestor_couple_ids ma - where p.id = ma.w_id -) -select h.name, h.dob, w.name, w.dob - from ancestor_couple_ids c, folks h, folks w - where c.h_id = h.id and c.w_id= w.id; +#MXS qc_mysqlembedded and qc_sqlite disagree in the used fields. +#MXS Both return correctly the folks fields (i.e. the real ones), +#MXS but disagree on the fields of the CTE tables. +# +#MXS with recursive +#MXS ancestor_couple_ids(h_id, w_id) +#MXS as +#MXS ( +#MXS select a.father, a.mother +#MXS from coupled_ancestors a +#MXS where a.father is not null and a.mother is not null +#MXS ), +#MXS coupled_ancestors (id, name, dob, father, mother) +#MXS as +#MXS ( +#MXS select * +#MXS from folks +#MXS where name = 'Me' +#MXS union all +#MXS select p.* +#MXS from folks p, ancestor_couple_ids fa +#MXS where p.id = fa.h_id +#MXS union all +#MXS select p.* +#MXS from folks p, ancestor_couple_ids ma +#MXS where p.id = ma.w_id +#MXS ) +#MXS select h.name, h.dob, w.name, w.dob +#MXS from ancestor_couple_ids c, folks h, folks w +#MXS where c.h_id = h.id and c.w_id= w.id; --echo # join of two mutually recursive tables -with recursive -ancestor_couple_ids(h_id, w_id) -as -( - select a.father, a.mother - from coupled_ancestors a - where a.father is not null and a.mother is not null -), -coupled_ancestors (id, name, dob, father, mother) -as -( - select * - from folks - where name = 'Me' - union all - select p.* - from folks p, ancestor_couple_ids fa - where p.id = fa.h_id - union all - select p.* - from folks p, ancestor_couple_ids ma - where p.id = ma.w_id -) -select h.name, h.dob, w.name, w.dob - from ancestor_couple_ids c, coupled_ancestors h, coupled_ancestors w - where c.h_id = h.id and c.w_id= w.id; +#MXS qc_mysqlembedded and qc_sqlite disagree in the used fields. +#MXS Both return correctly the folks fields (i.e. the real ones), +#MXS but disagree on the fields of the CTE tables. +# +#MXS with recursive +#MXS ancestor_couple_ids(h_id, w_id) +#MXS as +#MXS ( +#MXS select a.father, a.mother +#MXS from coupled_ancestors a +#MXS where a.father is not null and a.mother is not null +#MXS ), +#MXS coupled_ancestors (id, name, dob, father, mother) +#MXS as +#MXS ( +#MXS select * +#MXS from folks +#MXS where name = 'Me' +#MXS union all +#MXS select p.* +#MXS from folks p, ancestor_couple_ids fa +#MXS where p.id = fa.h_id +#MXS union all +#MXS select p.* +#MXS from folks p, ancestor_couple_ids ma +#MXS where p.id = ma.w_id +#MXS ) +#MXS select h.name, h.dob, w.name, w.dob +#MXS from ancestor_couple_ids c, coupled_ancestors h, coupled_ancestors w +#MXS where c.h_id = h.id and c.w_id= w.id; explain extended with recursive @@ -869,7 +889,8 @@ as select p.* from coupled_ancestor_ids a, folks p where a.id = p.id; -set statement standard_compliant_cte=0 for +#MXS qc_sqlite does not handle "SET STATEMENT ... FOR ..." +#MXS set statement standard_compliant_cte=0 for with recursive coupled_ancestor_ids (id) as @@ -914,7 +935,8 @@ as ) select * from ancestors; -set statement standard_compliant_cte=0 for +#MXS qc_sqlite does not handle "SET STATEMENT ... FOR ..." +#MXS set statement standard_compliant_cte=0 for with recursive ancestor_ids (id) as @@ -982,7 +1004,8 @@ as ) select * from ancestors; -set statement standard_compliant_cte=0 for +#MXS qc_sqlite does not handle "SET STATEMENT ... FOR ..." +#MXS set statement standard_compliant_cte=0 for with recursive ancestor_ids (id, generation) as @@ -1007,7 +1030,8 @@ as ) select * from ancestors; -set statement max_recursive_iterations=1 for +#MXS qc_sqlite does not handle "SET STATEMENT ... FOR ..." +#MXS set statement max_recursive_iterations=1 for with recursive ancestor_ids (id, generation) as @@ -1273,22 +1297,24 @@ drop table my_ancestors; --echo # CREATE SELECT --echo # -create table my_ancestors -( -with recursive -ancestor_ids (id) -as -( - select father from folks where name = 'Me' - union - select mother from folks where name = 'Me' - union - select father from folks, ancestor_ids a where folks.id = a.id - union - select mother from folks, ancestor_ids a where folks.id = a.id -) -select p.* from folks as p, ancestor_ids as a where p.id = a.id -); +#MXS qc_sqlite cannot parse this +#MXS qc_parse : INF: QC_QUERY_PARSED != QC_QUERY_PARTIALLY_PARSED +#MXS create table my_ancestors +#MXS ( +#MXS with recursive +#MXS ancestor_ids (id) +#MXS as +#MXS ( +#MXS select father from folks where name = 'Me' +#MXS union +#MXS select mother from folks where name = 'Me' +#MXS union +#MXS select father from folks, ancestor_ids a where folks.id = a.id +#MXS union +#MXS select mother from folks, ancestor_ids a where folks.id = a.id +#MXS ) +#MXS select p.* from folks as p, ancestor_ids as a where p.id = a.id +#MXS ); select * from my_ancestors; drop table my_ancestors; @@ -1368,10 +1394,13 @@ create table t2 (a int); insert into t2 values (1), (2), (3), (4), (5); -create view v1 as - select a from t2 where a < 3 - union - select a from t2 where a > 4; +#MXS qc_mysqlembedded +#MXS qc_get_function_info : ERR: <(QC_USED_IN_WHERE) != <(QC_USED_IN_WHERE) >(QC_USED_IN_WHERE) +# +#MXS create view v1 as +#MXS select a from t2 where a < 3 +#MXS union +#MXS select a from t2 where a > 4; with recursive t1 as @@ -1428,7 +1457,7 @@ WITH RECURSIVE transitive_closure(a, b, distance, path_string) AS ( SELECT a, b, 1 AS distance, concat(a, '.', b, '.') AS path_string FROM edges - WHERE a = 1 -- source + WHERE a = 1 UNION ALL @@ -1439,7 +1468,7 @@ WITH RECURSIVE transitive_closure(a, b, distance, path_string) AS WHERE tc.path_string NOT LIKE concat('%', e.b, '.%') ) SELECT * FROM transitive_closure - WHERE b = 6 -- destination + WHERE b = 6 ORDER BY a, b, distance; --sorted_result @@ -1507,12 +1536,15 @@ drop table t1; --echo # --source include/analyze-format.inc -analyze format=json -with recursive src(counter) as -(select 1 - union - select counter+1 from src where counter<10 -) select * from src; + +#MXS qc_sqlite cannot parse this +#MXS qc_parse : INF: QC_QUERY_PARSED != QC_QUERY_INVALID +#MXS analyze format=json +#MXS with recursive src(counter) as +#MXS (select 1 +#MXS union +#MXS select counter+1 from src where counter<10 +#MXS ) select * from src; --echo # --echo # mdev-12360: recursive reference in left operand of LEFT JOIN @@ -1626,7 +1658,8 @@ insert into module_results values ('m6','v12'), ('m6','v4'), ('m7','v2'); -set statement max_recursive_iterations=2, standard_compliant_cte=0 for +#MXS qc_sqlite does not handle "SET STATEMENT ... FOR ..." +#MXS set statement max_recursive_iterations=2, standard_compliant_cte=0 for with recursive reached_values as ( diff --git a/query_classifier/test/insert.test b/query_classifier/test/insert.test index 45207cc81..6bf0eb805 100644 --- a/query_classifier/test/insert.test +++ b/query_classifier/test/insert.test @@ -523,7 +523,7 @@ insert t1 (data) values ('letter'), (1/0); --disable_ps_protocol update t1 set data='envelope' where 1/0 or 1; --enable_ps_protocol -#MXS qc_mysqlem +#MXS qc_mysqlembedded does not return all functions #MXS qc_get_function_info : ERR: != /() #MXS insert t1 (data) values (default), (1/0), ('dead beef'); --disable_info diff --git a/query_classifier/test/qc_mysqlembedded_unsupported.test b/query_classifier/test/qc_mysqlembedded_unsupported.test index 925cbc383..e2564bfa5 100644 --- a/query_classifier/test/qc_mysqlembedded_unsupported.test +++ b/query_classifier/test/qc_mysqlembedded_unsupported.test @@ -8,3 +8,12 @@ insert into t1 values (if(1, 9223372036854775808, 1)), (case when 1 then 9223372036854775808 else 1 end), (coalesce(9223372036854775808, 1)); + +#MXS qc_mysqlembedded +#MXS qc_get_function_info : ERR: <(QC_USED_IN_WHERE) != <(QC_USED_IN_WHERE) >(QC_USED_IN_WHERE) +# +create view v1 as + select a from t2 where a < 3 + union + select a from t2 where a > 4; + diff --git a/query_classifier/test/qc_sqlite_unsupported.test b/query_classifier/test/qc_sqlite_unsupported.test index 6428ddce5..4901dc1d4 100644 --- a/query_classifier/test/qc_sqlite_unsupported.test +++ b/query_classifier/test/qc_sqlite_unsupported.test @@ -64,3 +64,65 @@ SELECT t.f FROM d.t; # to do that. select t.c,t1.b from t,mysqltest.t1 where t.c=t1.a; with t as (select c from mysqltest.t2 where c < 2) select t.c,t1.b from t,mysqltest.t1 where t.c=t1.a; + +#MXS qc_mysqlembedded and qc_sqlite disagree in the used fields. +#MXS Both return correctly the folks fields (i.e. the real ones), +#MXS but disagree on the fields of the CTR tables. +# +with recursive +ancestor_couples(h_id, h_name, h_dob, h_father, h_mother, + w_id, w_name, w_dob, w_father, w_mother) +as +( + select h.*, w.* + from folks h, folks w, coupled_ancestors a + where a.father = h.id AND a.mother = w.id + union + select h.*, w.* + from folks v, folks h, folks w + where v.name = 'Me' and + (v.father = h.id AND v.mother= w.id) +), +coupled_ancestors (id, name, dob, father, mother) +as +( + select h_id, h_name, h_dob, h_father, h_mother + from ancestor_couples + union all + select w_id, w_name, w_dob, w_father, w_mother + from ancestor_couples +) +select h_name, h_dob, w_name, w_dob + from ancestor_couples; + +#MXS qc_sqlite cannot parse this +#MXS qc_parse : INF: QC_QUERY_PARSED != QC_QUERY_TOKENIZED +set statement standard_compliant_cte=0 for select 1; + +#MXS qc_sqlite cannot parse this +#MXS qc_parse : INF: QC_QUERY_PARSED != QC_QUERY_PARTIALLY_PARSED +create table my_ancestors +( +with recursive +ancestor_ids (id) +as +( + select father from folks where name = 'Me' + union + select mother from folks where name = 'Me' + union + select father from folks, ancestor_ids a where folks.id = a.id + union + select mother from folks, ancestor_ids a where folks.id = a.id +) +select p.* from folks as p, ancestor_ids as a where p.id = a.id +); + +#MXS qc_sqlite cannot parse this +#MXS qc_parse : INF: QC_QUERY_PARSED != QC_QUERY_INVALID +analyze format=json +with recursive src(counter) as +(select 1 + union + select counter+1 from src where counter<10 +) select * from src;