diff --git a/simple-sql-parser.cabal b/simple-sql-parser.cabal index ce477a2..cbec849 100644 --- a/simple-sql-parser.cabal +++ b/simple-sql-parser.cabal @@ -52,15 +52,17 @@ Test-Suite Tests Language.SQL.SimpleSQL.Parser, Language.SQL.SimpleSQL.Syntax, Language.SQL.SimpleSQL.Fixity, + Language.SQL.SimpleSQL.FullQueries, - Language.SQL.SimpleSQL.Misc, Language.SQL.SimpleSQL.Postgres, + Language.SQL.SimpleSQL.QueryExprComponents, + Language.SQL.SimpleSQL.QueryExprs, Language.SQL.SimpleSQL.ScalarExprs, Language.SQL.SimpleSQL.TableRefs, Language.SQL.SimpleSQL.TestTypes, Language.SQL.SimpleSQL.Tests, - Language.SQL.SimpleSQL.Tpch, - Tpch + Language.SQL.SimpleSQL.Tpch + other-extensions: TupleSections default-language: Haskell2010 ghc-options: -Wall diff --git a/tools/Language/SQL/SimpleSQL/Postgres.lhs b/tools/Language/SQL/SimpleSQL/Postgres.lhs index 9b40b44..2baa09e 100644 --- a/tools/Language/SQL/SimpleSQL/Postgres.lhs +++ b/tools/Language/SQL/SimpleSQL/Postgres.lhs @@ -6,46 +6,266 @@ revisited when the dialect support is added. > module Language.SQL.SimpleSQL.Postgres (postgresTests) where > import Language.SQL.SimpleSQL.TestTypes -> import Language.SQL.SimpleSQL.Syntax +> --import Language.SQL.SimpleSQL.Syntax > postgresTests :: TestItem -> postgresTests = Group "postgresTests" -> [ +> postgresTests = Group "postgresTests" $ map ParseQueryExpr $ + +lexical syntax section + +TODO: get all the commented out tests working + +> [-- "SELECT 'foo'\n\ +> -- \'bar';" -- this should parse as select 'foobar' +> -- , +> "SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name)\n\ +> \ FROM states;" +> ,"SELECT ROW(1,2.5,'this is a test');" + +> --,"SELECT ROW(t.*, 42) FROM t;" -- needs the .* parsing to be enabled in more contexts +> ,"SELECT ROW(t.f1, t.f2, 42) FROM t;" +> ,"SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));" + +> ,"SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same');" + +> ,"SELECT ROW(table.*) IS NULL FROM table;" + +> ,"SELECT true OR somefunc();" + +> ,"SELECT somefunc() OR true;" + +queries section + +> ,"SELECT * FROM t1 CROSS JOIN t2;" +> ,"SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;" +> ,"SELECT * FROM t1 INNER JOIN t2 USING (num);" +> ,"SELECT * FROM t1 NATURAL INNER JOIN t2;" +> ,"SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;" +> ,"SELECT * FROM t1 LEFT JOIN t2 USING (num);" +> ,"SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;" +> ,"SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;" +> ,"SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';" +> ,"SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx';" + +> --,"SELECT * FROM some_very_long_table_name s JOIN another_fairly_long_name a ON s.id = a.num;" +> -- issue with join keyword on its own? +> --,"SELECT * FROM people AS mother JOIN people AS child ON mother.id = child.mother_id;" +> ,"SELECT * FROM my_table AS a CROSS JOIN my_table AS b;" +> ,"SELECT * FROM (my_table AS a CROSS JOIN my_table) AS b;" +> --,"SELECT * FROM getfoo(1) AS t1;" -- function tableref +> {-,"SELECT * FROM foo\n\ +> \ WHERE foosubid IN (\n\ +> \ SELECT foosubid\n\ +> \ FROM getfoo(foo.fooid) z\n\ +> \ WHERE z.fooid = foo.fooid\n\ +> \ );"-} -- function tableref +> {-,"SELECT *\n\ +> \ FROM dblink('dbname=mydb', 'SELECT proname, prosrc FROM pg_proc')\n\ +> \ AS t1(proname name, prosrc text)\n\ +> \ WHERE proname LIKE 'bytea%';"-} -- function tableref + +> --,"SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss;" -- lateral +> ,"SELECT * FROM foo, bar WHERE bar.id = foo.bar_id;" + +> {-,"SELECT p1.id, p2.id, v1, v2\n\ +> \FROM polygons p1, polygons p2,\n\ +> \ LATERAL vertices(p1.poly) v1,\n\ +> \ LATERAL vertices(p2.poly) v2\n\ +> \WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;"-} -- <-> operator?, lateral + +> {-,"SELECT p1.id, p2.id, v1, v2\n\ +> \FROM polygons p1 CROSS JOIN LATERAL vertices(p1.poly) v1,\n\ +> \ polygons p2 CROSS JOIN LATERAL vertices(p2.poly) v2\n\ +> \WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;"-} + +> {-,"SELECT m.name\n\ +> \FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true\n\ +> \WHERE pname IS NULL;"-} -- lateral, function ref + + +> ,"SELECT * FROM fdt WHERE c1 > 5" + +> ,"SELECT * FROM fdt WHERE c1 IN (1, 2, 3)" + +> ,"SELECT * FROM fdt WHERE c1 IN (SELECT c1 FROM t2)" + +> ,"SELECT * FROM fdt WHERE c1 IN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10)" + +> ,"SELECT * FROM fdt WHERE c1 BETWEEN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) AND 100" + +> ,"SELECT * FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 > fdt.c1)" + +> ,"SELECT * FROM test1;" + +> ,"SELECT x FROM test1 GROUP BY x;" +> ,"SELECT x, sum(y) FROM test1 GROUP BY x;" +> ,"SELECT product_id, p.name, (sum(s.units) * p.price) AS sales\n\ +> \ FROM products p LEFT JOIN sales s USING (product_id)\n\ +> \ GROUP BY product_id, p.name, p.price;" + +> ,"SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3;" +> ,"SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c';" +> {-,"SELECT product_id, p.name, (sum(s.units) * (p.price - p.cost)) AS profit\n\ +> \ FROM products p LEFT JOIN sales s USING (product_id)\n\ +> \ WHERE s.date > CURRENT_DATE - INTERVAL '4 weeks'\n\ +> \ GROUP BY product_id, p.name, p.price, p.cost\n\ +> \ HAVING sum(p.price * s.units) > 5000;"-} -- interval syntax? + +> ,"SELECT a, b, c FROM t" + +> ,"SELECT tbl1.a, tbl2.a, tbl1.b FROM t" + +> ,"SELECT tbl1.*, tbl2.a FROM t" + +> ,"SELECT a AS value, b + c AS sum FROM t" + +> --,"SELECT a \"value\", b + c AS sum FROM t" -- quoted identifier + +> ,"SELECT DISTINCT select_list t" + +> --,"VALUES (1, 'one'), (2, 'two'), (3, 'three');" -- values list + +> ,"SELECT 1 AS column1, 'one' AS column2\n\ +> \UNION ALL\n\ +> \SELECT 2, 'two'\n\ +> \UNION ALL\n\ +> \SELECT 3, 'three';" + +> --,"SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter);" +> -- values list + +> ,"WITH regional_sales AS (\n\ +> \ SELECT region, SUM(amount) AS total_sales\n\ +> \ FROM orders\n\ +> \ GROUP BY region\n\ +> \ ), top_regions AS (\n\ +> \ SELECT region\n\ +> \ FROM regional_sales\n\ +> \ WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)\n\ +> \ )\n\ +> \SELECT region,\n\ +> \ product,\n\ +> \ SUM(quantity) AS product_units,\n\ +> \ SUM(amount) AS product_sales\n\ +> \FROM orders\n\ +> \WHERE region IN (SELECT region FROM top_regions)\n\ +> \GROUP BY region, product;" + +> {-,"WITH RECURSIVE t(n) AS (\n\ +> \ VALUES (1)\n\ +> \ UNION ALL\n\ +> \ SELECT n+1 FROM t WHERE n < 100\n\ +> \)\n\ +> \SELECT sum(n) FROM t"-} -- full alias in cte + +> {-,"WITH RECURSIVE included_parts(sub_part, part, quantity) AS (\n\ +> \ SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'\n\ +> \ UNION ALL\n\ +> \ SELECT p.sub_part, p.part, p.quantity\n\ +> \ FROM included_parts pr, parts p\n\ +> \ WHERE p.part = pr.sub_part\n\ +> \ )\n\ +> \SELECT sub_part, SUM(quantity) as total_quantity\n\ +> \FROM included_parts\n\ +> \GROUP BY sub_part" + +> ,"WITH RECURSIVE search_graph(id, link, data, depth) AS (\n\ +> \ SELECT g.id, g.link, g.data, 1\n\ +> \ FROM graph g\n\ +> \ UNION ALL\n\ +> \ SELECT g.id, g.link, g.data, sg.depth + 1\n\ +> \ FROM graph g, search_graph sg\n\ +> \ WHERE g.id = sg.link\n\ +> \)\n\ +> \SELECT * FROM search_graph;" + +> ,"WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS (\n\ +> \ SELECT g.id, g.link, g.data, 1,\n\ +> \ ARRAY[g.id],\n\ +> \ false\n\ +> \ FROM graph g\n\ +> \ UNION ALL\n\ +> \ SELECT g.id, g.link, g.data, sg.depth + 1,\n\ +> \ path || g.id,\n\ +> \ g.id = ANY(path)\n\ +> \ FROM graph g, search_graph sg\n\ +> \ WHERE g.id = sg.link AND NOT cycle\n\ +> \)\n\ +> \SELECT * FROM search_graph;" + +> ,"WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS (\n\ +> \ SELECT g.id, g.link, g.data, 1,\n\ +> \ ARRAY[ROW(g.f1, g.f2)],\n\ +> \ false\n\ +> \ FROM graph g\n\ +> \ UNION ALL\n\ +> \ SELECT g.id, g.link, g.data, sg.depth + 1,\n\ +> \ path || ROW(g.f1, g.f2),\n\ +> \ ROW(g.f1, g.f2) = ANY(path)\n\ +> \ FROM graph g, search_graph sg\n\ +> \ WHERE g.id = sg.link AND NOT cycle\n\ +> \)\n\ +> \SELECT * FROM search_graph;" + +> ,"WITH RECURSIVE t(n) AS (\n\ +> \ SELECT 1\n\ +> \ UNION ALL\n\ +> \ SELECT n+1 FROM t\n\ +> \)\n\ +> \SELECT n FROM t LIMIT 100;"-} + +select page reference + +> ,"SELECT f.title, f.did, d.name, f.date_prod, f.kind\n\ +> \ FROM distributors d, films f\n\ +> \ WHERE f.did = d.did" + +> {-,"SELECT kind, sum(len) AS total\n\ +> \ FROM films\n\ +> \ GROUP BY kind\n\ +> \ HAVING sum(len) < interval '5 hours';"-} -- interval syntax? + +> ,"SELECT * FROM distributors ORDER BY name;" +> ,"SELECT * FROM distributors ORDER BY 2;" + +> ,"SELECT distributors.name\n\ +> \ FROM distributors\n\ +> \ WHERE distributors.name LIKE 'W%'\n\ +> \UNION\n\ +> \SELECT actors.name\n\ +> \ FROM actors\n\ +> \ WHERE actors.name LIKE 'W%';" + +> {-,"WITH t AS (\n\ +> \ SELECT random() as x FROM generate_series(1, 3)\n\ +> \ )\n\ +> \SELECT * FROM t\n\ +> \UNION ALL\n\ +> \SELECT * FROM t"-} -- function tref + +> {-,"WITH RECURSIVE employee_recursive(distance, employee_name, manager_name) AS (\n\ +> \ SELECT 1, employee_name, manager_name\n\ +> \ FROM employee\n\ +> \ WHERE manager_name = 'Mary'\n\ +> \ UNION ALL\n\ +> \ SELECT er.distance + 1, e.employee_name, e.manager_name\n\ +> \ FROM employee_recursive er, employee e\n\ +> \ WHERE er.employee_name = e.manager_name\n\ +> \ )\n\ +> \SELECT distance, employee_name FROM employee_recursive;"-} -- with recursive, full cte alias + +> {-,"SELECT m.name AS mname, pname\n\ +> \FROM manufacturers m, LATERAL get_product_names(m.id) pname;" + +> ,"SELECT m.name AS mname, pname\n\ +> \FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true;"-} -- lateral + +> ,"SELECT 2+2;" + +> ,"SELECT distributors.* WHERE distributors.name = 'Westward';" + > ] -lexical syntax - -SELECT 'foo' -'bar'; -> if there is a newline, this parses to select 'foobar' - -SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name) - FROM states; - -SELECT ROW(1,2.5,'this is a test'); - -SELECT ROW(t.*, 42) FROM t; -- needs the .* parsing to be enabled in more contexts -SELECT ROW(t.f1, t.f2, 42) FROM t; -SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype)); - -SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); - -SELECT ROW(table.*) IS NULL FROM table; - -SELECT true OR somefunc(); - -SELECT somefunc() OR true; - -queries -SELECT * FROM t1 CROSS JOIN t2; -SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num; -SELECT * FROM t1 INNER JOIN t2 USING (num); -SELECT * FROM t1 NATURAL INNER JOIN t2; -SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num; -SELECT * FROM t1 LEFT JOIN t2 USING (num); -SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num; -SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num; -SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx'; -SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx'; > {-f = mapM_ (putStrLn . either peFormattedError show . parseQueryExpr "" Nothing) > ["SELECT * FROM t1 CROSS JOIN t2;" @@ -59,222 +279,3 @@ SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx'; > ,"SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';" > - ,"SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx';"]-} - -SELECT * FROM some_very_long_table_name s JOIN another_fairly_long_name a ON s.id = a.num; -SELECT * FROM people AS mother JOIN people AS child ON mother.id = child.mother_id; -SELECT * FROM my_table AS a CROSS JOIN my_table AS b; -SELECT * FROM (my_table AS a CROSS JOIN my_table) AS b; -SELECT * FROM getfoo(1) AS t1; -SELECT * FROM foo - WHERE foosubid IN ( - SELECT foosubid - FROM getfoo(foo.fooid) z - WHERE z.fooid = foo.fooid - ); -SELECT * - FROM dblink('dbname=mydb', 'SELECT proname, prosrc FROM pg_proc') - AS t1(proname name, prosrc text) - WHERE proname LIKE 'bytea%'; - -SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss; -SELECT * FROM foo, bar WHERE bar.id = foo.bar_id; - -SELECT p1.id, p2.id, v1, v2 -FROM polygons p1, polygons p2, - LATERAL vertices(p1.poly) v1, - LATERAL vertices(p2.poly) v2 -WHERE (v1 <-> v2) < 10 AND p1.id != p2.id; - -SELECT p1.id, p2.id, v1, v2 -FROM polygons p1 CROSS JOIN LATERAL vertices(p1.poly) v1, - polygons p2 CROSS JOIN LATERAL vertices(p2.poly) v2 -WHERE (v1 <-> v2) < 10 AND p1.id != p2.id; - -SELECT m.name -FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true -WHERE pname IS NULL; - - -SELECT * FROM fdt WHERE c1 > 5 - -SELECT * FROM fdt WHERE c1 IN (1, 2, 3) - -SELECT * FROM fdt WHERE c1 IN (SELECT c1 FROM t2) - -SELECT * FROM fdt WHERE c1 IN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) - -SELECT * FROM fdt WHERE c1 BETWEEN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) AND 100 - -SELECT * FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 > fdt.c1) - -SELECT * FROM test1; - -SELECT x FROM test1 GROUP BY x; -SELECT x, sum(y) FROM test1 GROUP BY x; -SELECT product_id, p.name, (sum(s.units) * p.price) AS sales - FROM products p LEFT JOIN sales s USING (product_id) - GROUP BY product_id, p.name, p.price; - -SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3; -SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c'; -SELECT product_id, p.name, (sum(s.units) * (p.price - p.cost)) AS profit - FROM products p LEFT JOIN sales s USING (product_id) - WHERE s.date > CURRENT_DATE - INTERVAL '4 weeks' - GROUP BY product_id, p.name, p.price, p.cost - HAVING sum(p.price * s.units) > 5000; - -SELECT a, b, c FROM t - -SELECT tbl1.a, tbl2.a, tbl1.b FROM t - -SELECT tbl1.*, tbl2.a FROM t - -SELECT a AS value, b + c AS sum FROM t - --- bad keyword ---SELECT a value, b + c AS sum FROM ... - -SELECT a "value", b + c AS sum FROM t - -SELECT DISTINCT select_list t - -VALUES (1, 'one'), (2, 'two'), (3, 'three'); - -SELECT 1 AS column1, 'one' AS column2 -UNION ALL -SELECT 2, 'two' -UNION ALL -SELECT 3, 'three'; - -SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter); - -WITH regional_sales AS ( - SELECT region, SUM(amount) AS total_sales - FROM orders - GROUP BY region - ), top_regions AS ( - SELECT region - FROM regional_sales - WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales) - ) -SELECT region, - product, - SUM(quantity) AS product_units, - SUM(amount) AS product_sales -FROM orders -WHERE region IN (SELECT region FROM top_regions) -GROUP BY region, product; - -WITH RECURSIVE t(n) AS ( - VALUES (1) - UNION ALL - SELECT n+1 FROM t WHERE n < 100 -) -SELECT sum(n) FROM t - -WITH RECURSIVE included_parts(sub_part, part, quantity) AS ( - SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product' - UNION ALL - SELECT p.sub_part, p.part, p.quantity - FROM included_parts pr, parts p - WHERE p.part = pr.sub_part - ) -SELECT sub_part, SUM(quantity) as total_quantity -FROM included_parts -GROUP BY sub_part - -WITH RECURSIVE search_graph(id, link, data, depth) AS ( - SELECT g.id, g.link, g.data, 1 - FROM graph g - UNION ALL - SELECT g.id, g.link, g.data, sg.depth + 1 - FROM graph g, search_graph sg - WHERE g.id = sg.link -) -SELECT * FROM search_graph; - -WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS ( - SELECT g.id, g.link, g.data, 1, - ARRAY[g.id], - false - FROM graph g - UNION ALL - SELECT g.id, g.link, g.data, sg.depth + 1, - path || g.id, - g.id = ANY(path) - FROM graph g, search_graph sg - WHERE g.id = sg.link AND NOT cycle -) -SELECT * FROM search_graph; - -WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS ( - SELECT g.id, g.link, g.data, 1, - ARRAY[ROW(g.f1, g.f2)], - false - FROM graph g - UNION ALL - SELECT g.id, g.link, g.data, sg.depth + 1, - path || ROW(g.f1, g.f2), - ROW(g.f1, g.f2) = ANY(path) - FROM graph g, search_graph sg - WHERE g.id = sg.link AND NOT cycle -) -SELECT * FROM search_graph; - -WITH RECURSIVE t(n) AS ( - SELECT 1 - UNION ALL - SELECT n+1 FROM t -) -SELECT n FROM t LIMIT 100; - -select page reference - -SELECT f.title, f.did, d.name, f.date_prod, f.kind - FROM distributors d, films f - WHERE f.did = d.did - -SELECT kind, sum(len) AS total - FROM films - GROUP BY kind - HAVING sum(len) < interval '5 hours'; - -SELECT * FROM distributors ORDER BY name; -SELECT * FROM distributors ORDER BY 2; - -SELECT distributors.name - FROM distributors - WHERE distributors.name LIKE 'W%' -UNION -SELECT actors.name - FROM actors - WHERE actors.name LIKE 'W%'; - -WITH t AS ( - SELECT random() as x FROM generate_series(1, 3) - ) -SELECT * FROM t -UNION ALL -SELECT * FROM t - -WITH RECURSIVE employee_recursive(distance, employee_name, manager_name) AS ( - SELECT 1, employee_name, manager_name - FROM employee - WHERE manager_name = 'Mary' - UNION ALL - SELECT er.distance + 1, e.employee_name, e.manager_name - FROM employee_recursive er, employee e - WHERE er.employee_name = e.manager_name - ) -SELECT distance, employee_name FROM employee_recursive; - -SELECT m.name AS mname, pname -FROM manufacturers m, LATERAL get_product_names(m.id) pname; - -SELECT m.name AS mname, pname -FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true; - -SELECT 2+2; - -SELECT distributors.* WHERE distributors.name = 'Westward'; - diff --git a/tools/Language/SQL/SimpleSQL/Tests.lhs b/tools/Language/SQL/SimpleSQL/Tests.lhs index f699508..8d148b6 100644 --- a/tools/Language/SQL/SimpleSQL/Tests.lhs +++ b/tools/Language/SQL/SimpleSQL/Tests.lhs @@ -19,7 +19,7 @@ tpch tests > import Test.Framework.Providers.HUnit > import qualified Test.HUnit as H -> import Language.SQL.SimpleSQL.Syntax +> --import Language.SQL.SimpleSQL.Syntax > import Language.SQL.SimpleSQL.Pretty > import Language.SQL.SimpleSQL.Parser diff --git a/tools/Language/SQL/SimpleSQL/Tpch.lhs b/tools/Language/SQL/SimpleSQL/Tpch.lhs index 662896c..0aefbdc 100644 --- a/tools/Language/SQL/SimpleSQL/Tpch.lhs +++ b/tools/Language/SQL/SimpleSQL/Tpch.lhs @@ -2,12 +2,678 @@ Some tests for parsing the tpch queries -> module Language.SQL.SimpleSQL.Tpch (tpchTests) where +> module Language.SQL.SimpleSQL.Tpch (tpchTests,tpchQueries) where > import Language.SQL.SimpleSQL.TestTypes -> import Tpch > tpchTests :: TestItem > tpchTests = > Group "parse tpch" > $ map (ParseQueryExpr . snd) tpchQueries + +> tpchQueries :: [(String,String)] +> tpchQueries = +> [("Q1","\n\ +> \select\n\ +> \ l_returnflag,\n\ +> \ l_linestatus,\n\ +> \ sum(l_quantity) as sum_qty,\n\ +> \ sum(l_extendedprice) as sum_base_price,\n\ +> \ sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,\n\ +> \ sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,\n\ +> \ avg(l_quantity) as avg_qty,\n\ +> \ avg(l_extendedprice) as avg_price,\n\ +> \ avg(l_discount) as avg_disc,\n\ +> \ count(*) as count_order\n\ +> \from\n\ +> \ lineitem\n\ +> \where\n\ +> \ l_shipdate <= date '1998-12-01' - interval '63' day (3)\n\ +> \group by\n\ +> \ l_returnflag,\n\ +> \ l_linestatus\n\ +> \order by\n\ +> \ l_returnflag,\n\ +> \ l_linestatus") +> ,("Q2","\n\ +> \select\n\ +> \ s_acctbal,\n\ +> \ s_name,\n\ +> \ n_name,\n\ +> \ p_partkey,\n\ +> \ p_mfgr,\n\ +> \ s_address,\n\ +> \ s_phone,\n\ +> \ s_comment\n\ +> \from\n\ +> \ part,\n\ +> \ supplier,\n\ +> \ partsupp,\n\ +> \ nation,\n\ +> \ region\n\ +> \where\n\ +> \ p_partkey = ps_partkey\n\ +> \ and s_suppkey = ps_suppkey\n\ +> \ and p_size = 15\n\ +> \ and p_type like '%BRASS'\n\ +> \ and s_nationkey = n_nationkey\n\ +> \ and n_regionkey = r_regionkey\n\ +> \ and r_name = 'EUROPE'\n\ +> \ and ps_supplycost = (\n\ +> \ select\n\ +> \ min(ps_supplycost)\n\ +> \ from\n\ +> \ partsupp,\n\ +> \ supplier,\n\ +> \ nation,\n\ +> \ region\n\ +> \ where\n\ +> \ p_partkey = ps_partkey\n\ +> \ and s_suppkey = ps_suppkey\n\ +> \ and s_nationkey = n_nationkey\n\ +> \ and n_regionkey = r_regionkey\n\ +> \ and r_name = 'EUROPE'\n\ +> \ )\n\ +> \order by\n\ +> \ s_acctbal desc,\n\ +> \ n_name,\n\ +> \ s_name,\n\ +> \ p_partkey\n\ +> \limit 100") +> ,("Q3","\n\ +> \ select\n\ +> \ l_orderkey,\n\ +> \ sum(l_extendedprice * (1 - l_discount)) as revenue,\n\ +> \ o_orderdate,\n\ +> \ o_shippriority\n\ +> \ from\n\ +> \ customer,\n\ +> \ orders,\n\ +> \ lineitem\n\ +> \ where\n\ +> \ c_mktsegment = 'MACHINERY'\n\ +> \ and c_custkey = o_custkey\n\ +> \ and l_orderkey = o_orderkey\n\ +> \ and o_orderdate < date '1995-03-21'\n\ +> \ and l_shipdate > date '1995-03-21'\n\ +> \ group by\n\ +> \ l_orderkey,\n\ +> \ o_orderdate,\n\ +> \ o_shippriority\n\ +> \ order by\n\ +> \ revenue desc,\n\ +> \ o_orderdate\n\ +> \ limit 10") +> ,("Q4","\n\ +> \ select\n\ +> \ o_orderpriority,\n\ +> \ count(*) as order_count\n\ +> \ from\n\ +> \ orders\n\ +> \ where\n\ +> \ o_orderdate >= date '1996-03-01'\n\ +> \ and o_orderdate < date '1996-03-01' + interval '3' month\n\ +> \ and exists (\n\ +> \ select\n\ +> \ *\n\ +> \ from\n\ +> \ lineitem\n\ +> \ where\n\ +> \ l_orderkey = o_orderkey\n\ +> \ and l_commitdate < l_receiptdate\n\ +> \ )\n\ +> \ group by\n\ +> \ o_orderpriority\n\ +> \ order by\n\ +> \ o_orderpriority") +> ,("Q5","\n\ +> \ select\n\ +> \ n_name,\n\ +> \ sum(l_extendedprice * (1 - l_discount)) as revenue\n\ +> \ from\n\ +> \ customer,\n\ +> \ orders,\n\ +> \ lineitem,\n\ +> \ supplier,\n\ +> \ nation,\n\ +> \ region\n\ +> \ where\n\ +> \ c_custkey = o_custkey\n\ +> \ and l_orderkey = o_orderkey\n\ +> \ and l_suppkey = s_suppkey\n\ +> \ and c_nationkey = s_nationkey\n\ +> \ and s_nationkey = n_nationkey\n\ +> \ and n_regionkey = r_regionkey\n\ +> \ and r_name = 'EUROPE'\n\ +> \ and o_orderdate >= date '1997-01-01'\n\ +> \ and o_orderdate < date '1997-01-01' + interval '1' year\n\ +> \ group by\n\ +> \ n_name\n\ +> \ order by\n\ +> \ revenue desc") +> ,("Q6","\n\ +> \ select\n\ +> \ sum(l_extendedprice * l_discount) as revenue\n\ +> \ from\n\ +> \ lineitem\n\ +> \ where\n\ +> \ l_shipdate >= date '1997-01-01'\n\ +> \ and l_shipdate < date '1997-01-01' + interval '1' year\n\ +> \ and l_discount between 0.07 - 0.01 and 0.07 + 0.01\n\ +> \ and l_quantity < 24") +> ,("Q7","\n\ +> \ select\n\ +> \ supp_nation,\n\ +> \ cust_nation,\n\ +> \ l_year,\n\ +> \ sum(volume) as revenue\n\ +> \ from\n\ +> \ (\n\ +> \ select\n\ +> \ n1.n_name as supp_nation,\n\ +> \ n2.n_name as cust_nation,\n\ +> \ extract(year from l_shipdate) as l_year,\n\ +> \ l_extendedprice * (1 - l_discount) as volume\n\ +> \ from\n\ +> \ supplier,\n\ +> \ lineitem,\n\ +> \ orders,\n\ +> \ customer,\n\ +> \ nation n1,\n\ +> \ nation n2\n\ +> \ where\n\ +> \ s_suppkey = l_suppkey\n\ +> \ and o_orderkey = l_orderkey\n\ +> \ and c_custkey = o_custkey\n\ +> \ and s_nationkey = n1.n_nationkey\n\ +> \ and c_nationkey = n2.n_nationkey\n\ +> \ and (\n\ +> \ (n1.n_name = 'PERU' and n2.n_name = 'IRAQ')\n\ +> \ or (n1.n_name = 'IRAQ' and n2.n_name = 'PERU')\n\ +> \ )\n\ +> \ and l_shipdate between date '1995-01-01' and date '1996-12-31'\n\ +> \ ) as shipping\n\ +> \ group by\n\ +> \ supp_nation,\n\ +> \ cust_nation,\n\ +> \ l_year\n\ +> \ order by\n\ +> \ supp_nation,\n\ +> \ cust_nation,\n\ +> \ l_year") +> ,("Q8","\n\ +> \ select\n\ +> \ o_year,\n\ +> \ sum(case\n\ +> \ when nation = 'IRAQ' then volume\n\ +> \ else 0\n\ +> \ end) / sum(volume) as mkt_share\n\ +> \ from\n\ +> \ (\n\ +> \ select\n\ +> \ extract(year from o_orderdate) as o_year,\n\ +> \ l_extendedprice * (1 - l_discount) as volume,\n\ +> \ n2.n_name as nation\n\ +> \ from\n\ +> \ part,\n\ +> \ supplier,\n\ +> \ lineitem,\n\ +> \ orders,\n\ +> \ customer,\n\ +> \ nation n1,\n\ +> \ nation n2,\n\ +> \ region\n\ +> \ where\n\ +> \ p_partkey = l_partkey\n\ +> \ and s_suppkey = l_suppkey\n\ +> \ and l_orderkey = o_orderkey\n\ +> \ and o_custkey = c_custkey\n\ +> \ and c_nationkey = n1.n_nationkey\n\ +> \ and n1.n_regionkey = r_regionkey\n\ +> \ and r_name = 'MIDDLE EAST'\n\ +> \ and s_nationkey = n2.n_nationkey\n\ +> \ and o_orderdate between date '1995-01-01' and date '1996-12-31'\n\ +> \ and p_type = 'STANDARD ANODIZED BRASS'\n\ +> \ ) as all_nations\n\ +> \ group by\n\ +> \ o_year\n\ +> \ order by\n\ +> \ o_year") +> ,("Q9","\n\ +> \ select\n\ +> \ nation,\n\ +> \ o_year,\n\ +> \ sum(amount) as sum_profit\n\ +> \ from\n\ +> \ (\n\ +> \ select\n\ +> \ n_name as nation,\n\ +> \ extract(year from o_orderdate) as o_year,\n\ +> \ l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount\n\ +> \ from\n\ +> \ part,\n\ +> \ supplier,\n\ +> \ lineitem,\n\ +> \ partsupp,\n\ +> \ orders,\n\ +> \ nation\n\ +> \ where\n\ +> \ s_suppkey = l_suppkey\n\ +> \ and ps_suppkey = l_suppkey\n\ +> \ and ps_partkey = l_partkey\n\ +> \ and p_partkey = l_partkey\n\ +> \ and o_orderkey = l_orderkey\n\ +> \ and s_nationkey = n_nationkey\n\ +> \ and p_name like '%antique%'\n\ +> \ ) as profit\n\ +> \ group by\n\ +> \ nation,\n\ +> \ o_year\n\ +> \ order by\n\ +> \ nation,\n\ +> \ o_year desc") +> ,("Q10","\n\ +> \ select\n\ +> \ c_custkey,\n\ +> \ c_name,\n\ +> \ sum(l_extendedprice * (1 - l_discount)) as revenue,\n\ +> \ c_acctbal,\n\ +> \ n_name,\n\ +> \ c_address,\n\ +> \ c_phone,\n\ +> \ c_comment\n\ +> \ from\n\ +> \ customer,\n\ +> \ orders,\n\ +> \ lineitem,\n\ +> \ nation\n\ +> \ where\n\ +> \ c_custkey = o_custkey\n\ +> \ and l_orderkey = o_orderkey\n\ +> \ and o_orderdate >= date '1993-12-01'\n\ +> \ and o_orderdate < date '1993-12-01' + interval '3' month\n\ +> \ and l_returnflag = 'R'\n\ +> \ and c_nationkey = n_nationkey\n\ +> \ group by\n\ +> \ c_custkey,\n\ +> \ c_name,\n\ +> \ c_acctbal,\n\ +> \ c_phone,\n\ +> \ n_name,\n\ +> \ c_address,\n\ +> \ c_comment\n\ +> \ order by\n\ +> \ revenue desc\n\ +> \ limit 20") +> ,("Q11","\n\ +> \ select\n\ +> \ ps_partkey,\n\ +> \ sum(ps_supplycost * ps_availqty) as value\n\ +> \ from\n\ +> \ partsupp,\n\ +> \ supplier,\n\ +> \ nation\n\ +> \ where\n\ +> \ ps_suppkey = s_suppkey\n\ +> \ and s_nationkey = n_nationkey\n\ +> \ and n_name = 'CHINA'\n\ +> \ group by\n\ +> \ ps_partkey having\n\ +> \ sum(ps_supplycost * ps_availqty) > (\n\ +> \ select\n\ +> \ sum(ps_supplycost * ps_availqty) * 0.0001000000\n\ +> \ from\n\ +> \ partsupp,\n\ +> \ supplier,\n\ +> \ nation\n\ +> \ where\n\ +> \ ps_suppkey = s_suppkey\n\ +> \ and s_nationkey = n_nationkey\n\ +> \ and n_name = 'CHINA'\n\ +> \ )\n\ +> \ order by\n\ +> \ value desc") +> ,("Q12","\n\ +> \ select\n\ +> \ l_shipmode,\n\ +> \ sum(case\n\ +> \ when o_orderpriority = '1-URGENT'\n\ +> \ or o_orderpriority = '2-HIGH'\n\ +> \ then 1\n\ +> \ else 0\n\ +> \ end) as high_line_count,\n\ +> \ sum(case\n\ +> \ when o_orderpriority <> '1-URGENT'\n\ +> \ and o_orderpriority <> '2-HIGH'\n\ +> \ then 1\n\ +> \ else 0\n\ +> \ end) as low_line_count\n\ +> \ from\n\ +> \ orders,\n\ +> \ lineitem\n\ +> \ where\n\ +> \ o_orderkey = l_orderkey\n\ +> \ and l_shipmode in ('AIR', 'RAIL')\n\ +> \ and l_commitdate < l_receiptdate\n\ +> \ and l_shipdate < l_commitdate\n\ +> \ and l_receiptdate >= date '1994-01-01'\n\ +> \ and l_receiptdate < date '1994-01-01' + interval '1' year\n\ +> \ group by\n\ +> \ l_shipmode\n\ +> \ order by\n\ +> \ l_shipmode") +> ,("Q13","\n\ +> \ select\n\ +> \ c_count,\n\ +> \ count(*) as custdist\n\ +> \ from\n\ +> \ (\n\ +> \ select\n\ +> \ c_custkey,\n\ +> \ count(o_orderkey)\n\ +> \ from\n\ +> \ customer left outer join orders on\n\ +> \ c_custkey = o_custkey\n\ +> \ and o_comment not like '%pending%requests%'\n\ +> \ group by\n\ +> \ c_custkey\n\ +> \ ) as c_orders (c_custkey, c_count)\n\ +> \ group by\n\ +> \ c_count\n\ +> \ order by\n\ +> \ custdist desc,\n\ +> \ c_count desc") +> ,("Q14","\n\ +> \ select\n\ +> \ 100.00 * sum(case\n\ +> \ when p_type like 'PROMO%'\n\ +> \ then l_extendedprice * (1 - l_discount)\n\ +> \ else 0\n\ +> \ end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue\n\ +> \ from\n\ +> \ lineitem,\n\ +> \ part\n\ +> \ where\n\ +> \ l_partkey = p_partkey\n\ +> \ and l_shipdate >= date '1994-12-01'\n\ +> \ and l_shipdate < date '1994-12-01' + interval '1' month") +> ,("Q15","\n\ +> \ /*create view revenue0 (supplier_no, total_revenue) as\n\ +> \ select\n\ +> \ l_suppkey,\n\ +> \ sum(l_extendedprice * (1 - l_discount))\n\ +> \ from\n\ +> \ lineitem\n\ +> \ where\n\ +> \ l_shipdate >= date '1995-06-01'\n\ +> \ and l_shipdate < date '1995-06-01' + interval '3' month\n\ +> \ group by\n\ +> \ l_suppkey;*/\n\ +> \ with\n\ +> \ revenue0 as\n\ +> \ (select\n\ +> \ l_suppkey as supplier_no,\n\ +> \ sum(l_extendedprice * (1 - l_discount)) as total_revenue\n\ +> \ from\n\ +> \ lineitem\n\ +> \ where\n\ +> \ l_shipdate >= date '1995-06-01'\n\ +> \ and l_shipdate < date '1995-06-01' + interval '3' month\n\ +> \ group by\n\ +> \ l_suppkey)\n\ +> \ select\n\ +> \ s_suppkey,\n\ +> \ s_name,\n\ +> \ s_address,\n\ +> \ s_phone,\n\ +> \ total_revenue\n\ +> \ from\n\ +> \ supplier,\n\ +> \ revenue0\n\ +> \ where\n\ +> \ s_suppkey = supplier_no\n\ +> \ and total_revenue = (\n\ +> \ select\n\ +> \ max(total_revenue)\n\ +> \ from\n\ +> \ revenue0\n\ +> \ )\n\ +> \ order by\n\ +> \ s_suppkey") +> ,("Q16","\n\ +> \ select\n\ +> \ p_brand,\n\ +> \ p_type,\n\ +> \ p_size,\n\ +> \ count(distinct ps_suppkey) as supplier_cnt\n\ +> \ from\n\ +> \ partsupp,\n\ +> \ part\n\ +> \ where\n\ +> \ p_partkey = ps_partkey\n\ +> \ and p_brand <> 'Brand#15'\n\ +> \ and p_type not like 'MEDIUM BURNISHED%'\n\ +> \ and p_size in (39, 26, 18, 45, 19, 1, 3, 9)\n\ +> \ and ps_suppkey not in (\n\ +> \ select\n\ +> \ s_suppkey\n\ +> \ from\n\ +> \ supplier\n\ +> \ where\n\ +> \ s_comment like '%Customer%Complaints%'\n\ +> \ )\n\ +> \ group by\n\ +> \ p_brand,\n\ +> \ p_type,\n\ +> \ p_size\n\ +> \ order by\n\ +> \ supplier_cnt desc,\n\ +> \ p_brand,\n\ +> \ p_type,\n\ +> \ p_size") +> ,("Q17","\n\ +> \ select\n\ +> \ sum(l_extendedprice) / 7.0 as avg_yearly\n\ +> \ from\n\ +> \ lineitem,\n\ +> \ part\n\ +> \ where\n\ +> \ p_partkey = l_partkey\n\ +> \ and p_brand = 'Brand#52'\n\ +> \ and p_container = 'JUMBO CAN'\n\ +> \ and l_quantity < (\n\ +> \ select\n\ +> \ 0.2 * avg(l_quantity)\n\ +> \ from\n\ +> \ lineitem\n\ +> \ where\n\ +> \ l_partkey = p_partkey\n\ +> \ )") +> ,("Q18","\n\ +> \ select\n\ +> \ c_name,\n\ +> \ c_custkey,\n\ +> \ o_orderkey,\n\ +> \ o_orderdate,\n\ +> \ o_totalprice,\n\ +> \ sum(l_quantity)\n\ +> \ from\n\ +> \ customer,\n\ +> \ orders,\n\ +> \ lineitem\n\ +> \ where\n\ +> \ o_orderkey in (\n\ +> \ select\n\ +> \ l_orderkey\n\ +> \ from\n\ +> \ lineitem\n\ +> \ group by\n\ +> \ l_orderkey having\n\ +> \ sum(l_quantity) > 313\n\ +> \ )\n\ +> \ and c_custkey = o_custkey\n\ +> \ and o_orderkey = l_orderkey\n\ +> \ group by\n\ +> \ c_name,\n\ +> \ c_custkey,\n\ +> \ o_orderkey,\n\ +> \ o_orderdate,\n\ +> \ o_totalprice\n\ +> \ order by\n\ +> \ o_totalprice desc,\n\ +> \ o_orderdate\n\ +> \ limit 100") +> ,("Q19","\n\ +> \ select\n\ +> \ sum(l_extendedprice* (1 - l_discount)) as revenue\n\ +> \ from\n\ +> \ lineitem,\n\ +> \ part\n\ +> \ where\n\ +> \ (\n\ +> \ p_partkey = l_partkey\n\ +> \ and p_brand = 'Brand#43'\n\ +> \ and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG')\n\ +> \ and l_quantity >= 3 and l_quantity <= 3 + 10\n\ +> \ and p_size between 1 and 5\n\ +> \ and l_shipmode in ('AIR', 'AIR REG')\n\ +> \ and l_shipinstruct = 'DELIVER IN PERSON'\n\ +> \ )\n\ +> \ or\n\ +> \ (\n\ +> \ p_partkey = l_partkey\n\ +> \ and p_brand = 'Brand#25'\n\ +> \ and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK')\n\ +> \ and l_quantity >= 10 and l_quantity <= 10 + 10\n\ +> \ and p_size between 1 and 10\n\ +> \ and l_shipmode in ('AIR', 'AIR REG')\n\ +> \ and l_shipinstruct = 'DELIVER IN PERSON'\n\ +> \ )\n\ +> \ or\n\ +> \ (\n\ +> \ p_partkey = l_partkey\n\ +> \ and p_brand = 'Brand#24'\n\ +> \ and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG')\n\ +> \ and l_quantity >= 22 and l_quantity <= 22 + 10\n\ +> \ and p_size between 1 and 15\n\ +> \ and l_shipmode in ('AIR', 'AIR REG')\n\ +> \ and l_shipinstruct = 'DELIVER IN PERSON'\n\ +> \ )") +> ,("Q20","\n\ +> \ select\n\ +> \ s_name,\n\ +> \ s_address\n\ +> \ from\n\ +> \ supplier,\n\ +> \ nation\n\ +> \ where\n\ +> \ s_suppkey in (\n\ +> \ select\n\ +> \ ps_suppkey\n\ +> \ from\n\ +> \ partsupp\n\ +> \ where\n\ +> \ ps_partkey in (\n\ +> \ select\n\ +> \ p_partkey\n\ +> \ from\n\ +> \ part\n\ +> \ where\n\ +> \ p_name like 'lime%'\n\ +> \ )\n\ +> \ and ps_availqty > (\n\ +> \ select\n\ +> \ 0.5 * sum(l_quantity)\n\ +> \ from\n\ +> \ lineitem\n\ +> \ where\n\ +> \ l_partkey = ps_partkey\n\ +> \ and l_suppkey = ps_suppkey\n\ +> \ and l_shipdate >= date '1994-01-01'\n\ +> \ and l_shipdate < date '1994-01-01' + interval '1' year\n\ +> \ )\n\ +> \ )\n\ +> \ and s_nationkey = n_nationkey\n\ +> \ and n_name = 'VIETNAM'\n\ +> \ order by\n\ +> \ s_name") +> ,("Q21","\n\ +> \ select\n\ +> \ s_name,\n\ +> \ count(*) as numwait\n\ +> \ from\n\ +> \ supplier,\n\ +> \ lineitem l1,\n\ +> \ orders,\n\ +> \ nation\n\ +> \ where\n\ +> \ s_suppkey = l1.l_suppkey\n\ +> \ and o_orderkey = l1.l_orderkey\n\ +> \ and o_orderstatus = 'F'\n\ +> \ and l1.l_receiptdate > l1.l_commitdate\n\ +> \ and exists (\n\ +> \ select\n\ +> \ *\n\ +> \ from\n\ +> \ lineitem l2\n\ +> \ where\n\ +> \ l2.l_orderkey = l1.l_orderkey\n\ +> \ and l2.l_suppkey <> l1.l_suppkey\n\ +> \ )\n\ +> \ and not exists (\n\ +> \ select\n\ +> \ *\n\ +> \ from\n\ +> \ lineitem l3\n\ +> \ where\n\ +> \ l3.l_orderkey = l1.l_orderkey\n\ +> \ and l3.l_suppkey <> l1.l_suppkey\n\ +> \ and l3.l_receiptdate > l3.l_commitdate\n\ +> \ )\n\ +> \ and s_nationkey = n_nationkey\n\ +> \ and n_name = 'INDIA'\n\ +> \ group by\n\ +> \ s_name\n\ +> \ order by\n\ +> \ numwait desc,\n\ +> \ s_name\n\ +> \ limit 100") +> ,("Q22","\n\ +> \ select\n\ +> \ cntrycode,\n\ +> \ count(*) as numcust,\n\ +> \ sum(c_acctbal) as totacctbal\n\ +> \ from\n\ +> \ (\n\ +> \ select\n\ +> \ substring(c_phone from 1 for 2) as cntrycode,\n\ +> \ c_acctbal\n\ +> \ from\n\ +> \ customer\n\ +> \ where\n\ +> \ substring(c_phone from 1 for 2) in\n\ +> \ ('41', '28', '39', '21', '24', '29', '44')\n\ +> \ and c_acctbal > (\n\ +> \ select\n\ +> \ avg(c_acctbal)\n\ +> \ from\n\ +> \ customer\n\ +> \ where\n\ +> \ c_acctbal > 0.00\n\ +> \ and substring(c_phone from 1 for 2) in\n\ +> \ ('41', '28', '39', '21', '24', '29', '44')\n\ +> \ )\n\ +> \ and not exists (\n\ +> \ select\n\ +> \ *\n\ +> \ from\n\ +> \ orders\n\ +> \ where\n\ +> \ o_custkey = c_custkey\n\ +> \ )\n\ +> \ ) as custsale\n\ +> \ group by\n\ +> \ cntrycode\n\ +> \ order by\n\ +> \ cntrycode") +> ] diff --git a/tools/Tpch.lhs b/tools/Tpch.lhs deleted file mode 100644 index a90f24c..0000000 --- a/tools/Tpch.lhs +++ /dev/null @@ -1,675 +0,0 @@ - -test data for tpch queries - - -> {-# LANGUAGE OverloadedStrings #-} - -> module Tpch (tpchQueries) where -> - -> tpchQueries :: [(String,String)] -> tpchQueries = -> [("Q1","\n\ -> \select\n\ -> \ l_returnflag,\n\ -> \ l_linestatus,\n\ -> \ sum(l_quantity) as sum_qty,\n\ -> \ sum(l_extendedprice) as sum_base_price,\n\ -> \ sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,\n\ -> \ sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,\n\ -> \ avg(l_quantity) as avg_qty,\n\ -> \ avg(l_extendedprice) as avg_price,\n\ -> \ avg(l_discount) as avg_disc,\n\ -> \ count(*) as count_order\n\ -> \from\n\ -> \ lineitem\n\ -> \where\n\ -> \ l_shipdate <= date '1998-12-01' - interval '63' day (3)\n\ -> \group by\n\ -> \ l_returnflag,\n\ -> \ l_linestatus\n\ -> \order by\n\ -> \ l_returnflag,\n\ -> \ l_linestatus") -> ,("Q2","\n\ -> \select\n\ -> \ s_acctbal,\n\ -> \ s_name,\n\ -> \ n_name,\n\ -> \ p_partkey,\n\ -> \ p_mfgr,\n\ -> \ s_address,\n\ -> \ s_phone,\n\ -> \ s_comment\n\ -> \from\n\ -> \ part,\n\ -> \ supplier,\n\ -> \ partsupp,\n\ -> \ nation,\n\ -> \ region\n\ -> \where\n\ -> \ p_partkey = ps_partkey\n\ -> \ and s_suppkey = ps_suppkey\n\ -> \ and p_size = 15\n\ -> \ and p_type like '%BRASS'\n\ -> \ and s_nationkey = n_nationkey\n\ -> \ and n_regionkey = r_regionkey\n\ -> \ and r_name = 'EUROPE'\n\ -> \ and ps_supplycost = (\n\ -> \ select\n\ -> \ min(ps_supplycost)\n\ -> \ from\n\ -> \ partsupp,\n\ -> \ supplier,\n\ -> \ nation,\n\ -> \ region\n\ -> \ where\n\ -> \ p_partkey = ps_partkey\n\ -> \ and s_suppkey = ps_suppkey\n\ -> \ and s_nationkey = n_nationkey\n\ -> \ and n_regionkey = r_regionkey\n\ -> \ and r_name = 'EUROPE'\n\ -> \ )\n\ -> \order by\n\ -> \ s_acctbal desc,\n\ -> \ n_name,\n\ -> \ s_name,\n\ -> \ p_partkey\n\ -> \limit 100") -> ,("Q3","\n\ -> \ select\n\ -> \ l_orderkey,\n\ -> \ sum(l_extendedprice * (1 - l_discount)) as revenue,\n\ -> \ o_orderdate,\n\ -> \ o_shippriority\n\ -> \ from\n\ -> \ customer,\n\ -> \ orders,\n\ -> \ lineitem\n\ -> \ where\n\ -> \ c_mktsegment = 'MACHINERY'\n\ -> \ and c_custkey = o_custkey\n\ -> \ and l_orderkey = o_orderkey\n\ -> \ and o_orderdate < date '1995-03-21'\n\ -> \ and l_shipdate > date '1995-03-21'\n\ -> \ group by\n\ -> \ l_orderkey,\n\ -> \ o_orderdate,\n\ -> \ o_shippriority\n\ -> \ order by\n\ -> \ revenue desc,\n\ -> \ o_orderdate\n\ -> \ limit 10") -> ,("Q4","\n\ -> \ select\n\ -> \ o_orderpriority,\n\ -> \ count(*) as order_count\n\ -> \ from\n\ -> \ orders\n\ -> \ where\n\ -> \ o_orderdate >= date '1996-03-01'\n\ -> \ and o_orderdate < date '1996-03-01' + interval '3' month\n\ -> \ and exists (\n\ -> \ select\n\ -> \ *\n\ -> \ from\n\ -> \ lineitem\n\ -> \ where\n\ -> \ l_orderkey = o_orderkey\n\ -> \ and l_commitdate < l_receiptdate\n\ -> \ )\n\ -> \ group by\n\ -> \ o_orderpriority\n\ -> \ order by\n\ -> \ o_orderpriority") -> ,("Q5","\n\ -> \ select\n\ -> \ n_name,\n\ -> \ sum(l_extendedprice * (1 - l_discount)) as revenue\n\ -> \ from\n\ -> \ customer,\n\ -> \ orders,\n\ -> \ lineitem,\n\ -> \ supplier,\n\ -> \ nation,\n\ -> \ region\n\ -> \ where\n\ -> \ c_custkey = o_custkey\n\ -> \ and l_orderkey = o_orderkey\n\ -> \ and l_suppkey = s_suppkey\n\ -> \ and c_nationkey = s_nationkey\n\ -> \ and s_nationkey = n_nationkey\n\ -> \ and n_regionkey = r_regionkey\n\ -> \ and r_name = 'EUROPE'\n\ -> \ and o_orderdate >= date '1997-01-01'\n\ -> \ and o_orderdate < date '1997-01-01' + interval '1' year\n\ -> \ group by\n\ -> \ n_name\n\ -> \ order by\n\ -> \ revenue desc") -> ,("Q6","\n\ -> \ select\n\ -> \ sum(l_extendedprice * l_discount) as revenue\n\ -> \ from\n\ -> \ lineitem\n\ -> \ where\n\ -> \ l_shipdate >= date '1997-01-01'\n\ -> \ and l_shipdate < date '1997-01-01' + interval '1' year\n\ -> \ and l_discount between 0.07 - 0.01 and 0.07 + 0.01\n\ -> \ and l_quantity < 24") -> ,("Q7","\n\ -> \ select\n\ -> \ supp_nation,\n\ -> \ cust_nation,\n\ -> \ l_year,\n\ -> \ sum(volume) as revenue\n\ -> \ from\n\ -> \ (\n\ -> \ select\n\ -> \ n1.n_name as supp_nation,\n\ -> \ n2.n_name as cust_nation,\n\ -> \ extract(year from l_shipdate) as l_year,\n\ -> \ l_extendedprice * (1 - l_discount) as volume\n\ -> \ from\n\ -> \ supplier,\n\ -> \ lineitem,\n\ -> \ orders,\n\ -> \ customer,\n\ -> \ nation n1,\n\ -> \ nation n2\n\ -> \ where\n\ -> \ s_suppkey = l_suppkey\n\ -> \ and o_orderkey = l_orderkey\n\ -> \ and c_custkey = o_custkey\n\ -> \ and s_nationkey = n1.n_nationkey\n\ -> \ and c_nationkey = n2.n_nationkey\n\ -> \ and (\n\ -> \ (n1.n_name = 'PERU' and n2.n_name = 'IRAQ')\n\ -> \ or (n1.n_name = 'IRAQ' and n2.n_name = 'PERU')\n\ -> \ )\n\ -> \ and l_shipdate between date '1995-01-01' and date '1996-12-31'\n\ -> \ ) as shipping\n\ -> \ group by\n\ -> \ supp_nation,\n\ -> \ cust_nation,\n\ -> \ l_year\n\ -> \ order by\n\ -> \ supp_nation,\n\ -> \ cust_nation,\n\ -> \ l_year") -> ,("Q8","\n\ -> \ select\n\ -> \ o_year,\n\ -> \ sum(case\n\ -> \ when nation = 'IRAQ' then volume\n\ -> \ else 0\n\ -> \ end) / sum(volume) as mkt_share\n\ -> \ from\n\ -> \ (\n\ -> \ select\n\ -> \ extract(year from o_orderdate) as o_year,\n\ -> \ l_extendedprice * (1 - l_discount) as volume,\n\ -> \ n2.n_name as nation\n\ -> \ from\n\ -> \ part,\n\ -> \ supplier,\n\ -> \ lineitem,\n\ -> \ orders,\n\ -> \ customer,\n\ -> \ nation n1,\n\ -> \ nation n2,\n\ -> \ region\n\ -> \ where\n\ -> \ p_partkey = l_partkey\n\ -> \ and s_suppkey = l_suppkey\n\ -> \ and l_orderkey = o_orderkey\n\ -> \ and o_custkey = c_custkey\n\ -> \ and c_nationkey = n1.n_nationkey\n\ -> \ and n1.n_regionkey = r_regionkey\n\ -> \ and r_name = 'MIDDLE EAST'\n\ -> \ and s_nationkey = n2.n_nationkey\n\ -> \ and o_orderdate between date '1995-01-01' and date '1996-12-31'\n\ -> \ and p_type = 'STANDARD ANODIZED BRASS'\n\ -> \ ) as all_nations\n\ -> \ group by\n\ -> \ o_year\n\ -> \ order by\n\ -> \ o_year") -> ,("Q9","\n\ -> \ select\n\ -> \ nation,\n\ -> \ o_year,\n\ -> \ sum(amount) as sum_profit\n\ -> \ from\n\ -> \ (\n\ -> \ select\n\ -> \ n_name as nation,\n\ -> \ extract(year from o_orderdate) as o_year,\n\ -> \ l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount\n\ -> \ from\n\ -> \ part,\n\ -> \ supplier,\n\ -> \ lineitem,\n\ -> \ partsupp,\n\ -> \ orders,\n\ -> \ nation\n\ -> \ where\n\ -> \ s_suppkey = l_suppkey\n\ -> \ and ps_suppkey = l_suppkey\n\ -> \ and ps_partkey = l_partkey\n\ -> \ and p_partkey = l_partkey\n\ -> \ and o_orderkey = l_orderkey\n\ -> \ and s_nationkey = n_nationkey\n\ -> \ and p_name like '%antique%'\n\ -> \ ) as profit\n\ -> \ group by\n\ -> \ nation,\n\ -> \ o_year\n\ -> \ order by\n\ -> \ nation,\n\ -> \ o_year desc") -> ,("Q10","\n\ -> \ select\n\ -> \ c_custkey,\n\ -> \ c_name,\n\ -> \ sum(l_extendedprice * (1 - l_discount)) as revenue,\n\ -> \ c_acctbal,\n\ -> \ n_name,\n\ -> \ c_address,\n\ -> \ c_phone,\n\ -> \ c_comment\n\ -> \ from\n\ -> \ customer,\n\ -> \ orders,\n\ -> \ lineitem,\n\ -> \ nation\n\ -> \ where\n\ -> \ c_custkey = o_custkey\n\ -> \ and l_orderkey = o_orderkey\n\ -> \ and o_orderdate >= date '1993-12-01'\n\ -> \ and o_orderdate < date '1993-12-01' + interval '3' month\n\ -> \ and l_returnflag = 'R'\n\ -> \ and c_nationkey = n_nationkey\n\ -> \ group by\n\ -> \ c_custkey,\n\ -> \ c_name,\n\ -> \ c_acctbal,\n\ -> \ c_phone,\n\ -> \ n_name,\n\ -> \ c_address,\n\ -> \ c_comment\n\ -> \ order by\n\ -> \ revenue desc\n\ -> \ limit 20") -> ,("Q11","\n\ -> \ select\n\ -> \ ps_partkey,\n\ -> \ sum(ps_supplycost * ps_availqty) as value\n\ -> \ from\n\ -> \ partsupp,\n\ -> \ supplier,\n\ -> \ nation\n\ -> \ where\n\ -> \ ps_suppkey = s_suppkey\n\ -> \ and s_nationkey = n_nationkey\n\ -> \ and n_name = 'CHINA'\n\ -> \ group by\n\ -> \ ps_partkey having\n\ -> \ sum(ps_supplycost * ps_availqty) > (\n\ -> \ select\n\ -> \ sum(ps_supplycost * ps_availqty) * 0.0001000000\n\ -> \ from\n\ -> \ partsupp,\n\ -> \ supplier,\n\ -> \ nation\n\ -> \ where\n\ -> \ ps_suppkey = s_suppkey\n\ -> \ and s_nationkey = n_nationkey\n\ -> \ and n_name = 'CHINA'\n\ -> \ )\n\ -> \ order by\n\ -> \ value desc") -> ,("Q12","\n\ -> \ select\n\ -> \ l_shipmode,\n\ -> \ sum(case\n\ -> \ when o_orderpriority = '1-URGENT'\n\ -> \ or o_orderpriority = '2-HIGH'\n\ -> \ then 1\n\ -> \ else 0\n\ -> \ end) as high_line_count,\n\ -> \ sum(case\n\ -> \ when o_orderpriority <> '1-URGENT'\n\ -> \ and o_orderpriority <> '2-HIGH'\n\ -> \ then 1\n\ -> \ else 0\n\ -> \ end) as low_line_count\n\ -> \ from\n\ -> \ orders,\n\ -> \ lineitem\n\ -> \ where\n\ -> \ o_orderkey = l_orderkey\n\ -> \ and l_shipmode in ('AIR', 'RAIL')\n\ -> \ and l_commitdate < l_receiptdate\n\ -> \ and l_shipdate < l_commitdate\n\ -> \ and l_receiptdate >= date '1994-01-01'\n\ -> \ and l_receiptdate < date '1994-01-01' + interval '1' year\n\ -> \ group by\n\ -> \ l_shipmode\n\ -> \ order by\n\ -> \ l_shipmode") -> ,("Q13","\n\ -> \ select\n\ -> \ c_count,\n\ -> \ count(*) as custdist\n\ -> \ from\n\ -> \ (\n\ -> \ select\n\ -> \ c_custkey,\n\ -> \ count(o_orderkey)\n\ -> \ from\n\ -> \ customer left outer join orders on\n\ -> \ c_custkey = o_custkey\n\ -> \ and o_comment not like '%pending%requests%'\n\ -> \ group by\n\ -> \ c_custkey\n\ -> \ ) as c_orders (c_custkey, c_count)\n\ -> \ group by\n\ -> \ c_count\n\ -> \ order by\n\ -> \ custdist desc,\n\ -> \ c_count desc") -> ,("Q14","\n\ -> \ select\n\ -> \ 100.00 * sum(case\n\ -> \ when p_type like 'PROMO%'\n\ -> \ then l_extendedprice * (1 - l_discount)\n\ -> \ else 0\n\ -> \ end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue\n\ -> \ from\n\ -> \ lineitem,\n\ -> \ part\n\ -> \ where\n\ -> \ l_partkey = p_partkey\n\ -> \ and l_shipdate >= date '1994-12-01'\n\ -> \ and l_shipdate < date '1994-12-01' + interval '1' month") -> ,("Q15","\n\ -> \ /*create view revenue0 (supplier_no, total_revenue) as\n\ -> \ select\n\ -> \ l_suppkey,\n\ -> \ sum(l_extendedprice * (1 - l_discount))\n\ -> \ from\n\ -> \ lineitem\n\ -> \ where\n\ -> \ l_shipdate >= date '1995-06-01'\n\ -> \ and l_shipdate < date '1995-06-01' + interval '3' month\n\ -> \ group by\n\ -> \ l_suppkey;*/\n\ -> \ with\n\ -> \ revenue0 as\n\ -> \ (select\n\ -> \ l_suppkey as supplier_no,\n\ -> \ sum(l_extendedprice * (1 - l_discount)) as total_revenue\n\ -> \ from\n\ -> \ lineitem\n\ -> \ where\n\ -> \ l_shipdate >= date '1995-06-01'\n\ -> \ and l_shipdate < date '1995-06-01' + interval '3' month\n\ -> \ group by\n\ -> \ l_suppkey)\n\ -> \ select\n\ -> \ s_suppkey,\n\ -> \ s_name,\n\ -> \ s_address,\n\ -> \ s_phone,\n\ -> \ total_revenue\n\ -> \ from\n\ -> \ supplier,\n\ -> \ revenue0\n\ -> \ where\n\ -> \ s_suppkey = supplier_no\n\ -> \ and total_revenue = (\n\ -> \ select\n\ -> \ max(total_revenue)\n\ -> \ from\n\ -> \ revenue0\n\ -> \ )\n\ -> \ order by\n\ -> \ s_suppkey") -> ,("Q16","\n\ -> \ select\n\ -> \ p_brand,\n\ -> \ p_type,\n\ -> \ p_size,\n\ -> \ count(distinct ps_suppkey) as supplier_cnt\n\ -> \ from\n\ -> \ partsupp,\n\ -> \ part\n\ -> \ where\n\ -> \ p_partkey = ps_partkey\n\ -> \ and p_brand <> 'Brand#15'\n\ -> \ and p_type not like 'MEDIUM BURNISHED%'\n\ -> \ and p_size in (39, 26, 18, 45, 19, 1, 3, 9)\n\ -> \ and ps_suppkey not in (\n\ -> \ select\n\ -> \ s_suppkey\n\ -> \ from\n\ -> \ supplier\n\ -> \ where\n\ -> \ s_comment like '%Customer%Complaints%'\n\ -> \ )\n\ -> \ group by\n\ -> \ p_brand,\n\ -> \ p_type,\n\ -> \ p_size\n\ -> \ order by\n\ -> \ supplier_cnt desc,\n\ -> \ p_brand,\n\ -> \ p_type,\n\ -> \ p_size") -> ,("Q17","\n\ -> \ select\n\ -> \ sum(l_extendedprice) / 7.0 as avg_yearly\n\ -> \ from\n\ -> \ lineitem,\n\ -> \ part\n\ -> \ where\n\ -> \ p_partkey = l_partkey\n\ -> \ and p_brand = 'Brand#52'\n\ -> \ and p_container = 'JUMBO CAN'\n\ -> \ and l_quantity < (\n\ -> \ select\n\ -> \ 0.2 * avg(l_quantity)\n\ -> \ from\n\ -> \ lineitem\n\ -> \ where\n\ -> \ l_partkey = p_partkey\n\ -> \ )") -> ,("Q18","\n\ -> \ select\n\ -> \ c_name,\n\ -> \ c_custkey,\n\ -> \ o_orderkey,\n\ -> \ o_orderdate,\n\ -> \ o_totalprice,\n\ -> \ sum(l_quantity)\n\ -> \ from\n\ -> \ customer,\n\ -> \ orders,\n\ -> \ lineitem\n\ -> \ where\n\ -> \ o_orderkey in (\n\ -> \ select\n\ -> \ l_orderkey\n\ -> \ from\n\ -> \ lineitem\n\ -> \ group by\n\ -> \ l_orderkey having\n\ -> \ sum(l_quantity) > 313\n\ -> \ )\n\ -> \ and c_custkey = o_custkey\n\ -> \ and o_orderkey = l_orderkey\n\ -> \ group by\n\ -> \ c_name,\n\ -> \ c_custkey,\n\ -> \ o_orderkey,\n\ -> \ o_orderdate,\n\ -> \ o_totalprice\n\ -> \ order by\n\ -> \ o_totalprice desc,\n\ -> \ o_orderdate\n\ -> \ limit 100") -> ,("Q19","\n\ -> \ select\n\ -> \ sum(l_extendedprice* (1 - l_discount)) as revenue\n\ -> \ from\n\ -> \ lineitem,\n\ -> \ part\n\ -> \ where\n\ -> \ (\n\ -> \ p_partkey = l_partkey\n\ -> \ and p_brand = 'Brand#43'\n\ -> \ and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG')\n\ -> \ and l_quantity >= 3 and l_quantity <= 3 + 10\n\ -> \ and p_size between 1 and 5\n\ -> \ and l_shipmode in ('AIR', 'AIR REG')\n\ -> \ and l_shipinstruct = 'DELIVER IN PERSON'\n\ -> \ )\n\ -> \ or\n\ -> \ (\n\ -> \ p_partkey = l_partkey\n\ -> \ and p_brand = 'Brand#25'\n\ -> \ and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK')\n\ -> \ and l_quantity >= 10 and l_quantity <= 10 + 10\n\ -> \ and p_size between 1 and 10\n\ -> \ and l_shipmode in ('AIR', 'AIR REG')\n\ -> \ and l_shipinstruct = 'DELIVER IN PERSON'\n\ -> \ )\n\ -> \ or\n\ -> \ (\n\ -> \ p_partkey = l_partkey\n\ -> \ and p_brand = 'Brand#24'\n\ -> \ and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG')\n\ -> \ and l_quantity >= 22 and l_quantity <= 22 + 10\n\ -> \ and p_size between 1 and 15\n\ -> \ and l_shipmode in ('AIR', 'AIR REG')\n\ -> \ and l_shipinstruct = 'DELIVER IN PERSON'\n\ -> \ )") -> ,("Q20","\n\ -> \ select\n\ -> \ s_name,\n\ -> \ s_address\n\ -> \ from\n\ -> \ supplier,\n\ -> \ nation\n\ -> \ where\n\ -> \ s_suppkey in (\n\ -> \ select\n\ -> \ ps_suppkey\n\ -> \ from\n\ -> \ partsupp\n\ -> \ where\n\ -> \ ps_partkey in (\n\ -> \ select\n\ -> \ p_partkey\n\ -> \ from\n\ -> \ part\n\ -> \ where\n\ -> \ p_name like 'lime%'\n\ -> \ )\n\ -> \ and ps_availqty > (\n\ -> \ select\n\ -> \ 0.5 * sum(l_quantity)\n\ -> \ from\n\ -> \ lineitem\n\ -> \ where\n\ -> \ l_partkey = ps_partkey\n\ -> \ and l_suppkey = ps_suppkey\n\ -> \ and l_shipdate >= date '1994-01-01'\n\ -> \ and l_shipdate < date '1994-01-01' + interval '1' year\n\ -> \ )\n\ -> \ )\n\ -> \ and s_nationkey = n_nationkey\n\ -> \ and n_name = 'VIETNAM'\n\ -> \ order by\n\ -> \ s_name") -> ,("Q21","\n\ -> \ select\n\ -> \ s_name,\n\ -> \ count(*) as numwait\n\ -> \ from\n\ -> \ supplier,\n\ -> \ lineitem l1,\n\ -> \ orders,\n\ -> \ nation\n\ -> \ where\n\ -> \ s_suppkey = l1.l_suppkey\n\ -> \ and o_orderkey = l1.l_orderkey\n\ -> \ and o_orderstatus = 'F'\n\ -> \ and l1.l_receiptdate > l1.l_commitdate\n\ -> \ and exists (\n\ -> \ select\n\ -> \ *\n\ -> \ from\n\ -> \ lineitem l2\n\ -> \ where\n\ -> \ l2.l_orderkey = l1.l_orderkey\n\ -> \ and l2.l_suppkey <> l1.l_suppkey\n\ -> \ )\n\ -> \ and not exists (\n\ -> \ select\n\ -> \ *\n\ -> \ from\n\ -> \ lineitem l3\n\ -> \ where\n\ -> \ l3.l_orderkey = l1.l_orderkey\n\ -> \ and l3.l_suppkey <> l1.l_suppkey\n\ -> \ and l3.l_receiptdate > l3.l_commitdate\n\ -> \ )\n\ -> \ and s_nationkey = n_nationkey\n\ -> \ and n_name = 'INDIA'\n\ -> \ group by\n\ -> \ s_name\n\ -> \ order by\n\ -> \ numwait desc,\n\ -> \ s_name\n\ -> \ limit 100") -> ,("Q22","\n\ -> \ select\n\ -> \ cntrycode,\n\ -> \ count(*) as numcust,\n\ -> \ sum(c_acctbal) as totacctbal\n\ -> \ from\n\ -> \ (\n\ -> \ select\n\ -> \ substring(c_phone from 1 for 2) as cntrycode,\n\ -> \ c_acctbal\n\ -> \ from\n\ -> \ customer\n\ -> \ where\n\ -> \ substring(c_phone from 1 for 2) in\n\ -> \ ('41', '28', '39', '21', '24', '29', '44')\n\ -> \ and c_acctbal > (\n\ -> \ select\n\ -> \ avg(c_acctbal)\n\ -> \ from\n\ -> \ customer\n\ -> \ where\n\ -> \ c_acctbal > 0.00\n\ -> \ and substring(c_phone from 1 for 2) in\n\ -> \ ('41', '28', '39', '21', '24', '29', '44')\n\ -> \ )\n\ -> \ and not exists (\n\ -> \ select\n\ -> \ *\n\ -> \ from\n\ -> \ orders\n\ -> \ where\n\ -> \ o_custkey = c_custkey\n\ -> \ )\n\ -> \ ) as custsale\n\ -> \ group by\n\ -> \ cntrycode\n\ -> \ order by\n\ -> \ cntrycode") -> ]