diff --git a/partiql-test-data/fail/parser/select/select-from-where.ion b/partiql-test-data/fail/parser/select/select-from-where.ion index 79cdbd2..20a3d2e 100644 --- a/partiql-test-data/fail/parser/select/select-from-where.ion +++ b/partiql-test-data/fail/parser/select/select-from-where.ion @@ -2,6 +2,6 @@ parse::{ name: "SFW without WHERE expression", statement: "SELECT * FROM foo WHERE", assert: { - result: ParserError + result: ParseError }, } diff --git a/partiql-test-data/pass/parser/primitives/aggregate-function-call.ion b/partiql-test-data/pass/parser/primitives/aggregate-function-call.ion new file mode 100644 index 0000000..7e95c3c --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/aggregate-function-call.ion @@ -0,0 +1,39 @@ +parse::{ + name: "COUNT aggregate function call", + statement: "COUNT(a)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "SUM DISTINCT aggregate function call", + statement: "SUM(DISTINCT a)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "COUNT star aggregate function call", + statement: "COUNT(*)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "COUNT DISTINCT aggregate function call", + statement: "COUNT(DISTINCT a)", + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/call.ion b/partiql-test-data/pass/parser/primitives/call.ion new file mode 100644 index 0000000..3e95f10 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/call.ion @@ -0,0 +1,141 @@ +parse::{ + name: "call empty", + statement: "foobar()", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call one argument", + statement: "foobar(1)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call two arguments", + statement: "foobar(1, 2)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call with multiple", + statement: "foobar(1, 2, 3)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call with case insensitive function name", + statement: "mY_fUnCtIoN(a)", + assert: [ + { + result: ParseOk + }, + ] +} + + +'substring'::[ + 'sql92'::[ + parse::{ + name: "call SUBSTRING sql92 syntax", + statement: "substring('test' from 100)", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "call SUBSTRING sql92 syntax with length", + statement: "substring('test' from 100 for 50)", + assert: [ + { + result: ParseOk + }, + ] + }, + ], + 'partiql'::[ + parse::{ + name: "call SUBSTRING function argument list syntax", + statement: "substring('test', 100)", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "call SUBSTRING function argument list syntax with length", + statement: "substring('test', 100, 50)", + assert: [ + { + result: ParseOk + }, + ] + }, + ] +] + +'trim'::[ + parse::{ + name: "call TRIM single argument", + statement: "trim('test')", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "call TRIM two arguments default specification", + statement: "trim(' ' from 'test')", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "call TRIM two arguments using BOTH", + statement: "trim(both from 'test')", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "call TRIM two arguments using LEADING", + statement: "trim(leading from 'test')", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "call TRIM two arguments using TRAILING", + statement: "trim(trailing from 'test')", + assert: [ + { + result: ParseOk + }, + ] + }, +] diff --git a/partiql-test-data/pass/parser/primitives/case.ion b/partiql-test-data/pass/parser/primitives/case.ion new file mode 100644 index 0000000..f254739 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/case.ion @@ -0,0 +1,59 @@ +'searched-case'::[ + parse::{ + name: "searched CASE single WHEN no ELSE", + statement: "CASE WHEN name = 'zoe' THEN 1 END", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "searched CASE single WHEN with ELSE", + statement: "CASE WHEN name = 'zoe' THEN 1 ELSE 0 END", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "searched CASE multi WHEN with ELSE", + statement: "CASE WHEN name = 'zoe' THEN 1 WHEN name > 'kumo' THEN 2 ELSE 0 END", + assert: [ + { + result: ParseOk + }, + ] + } +] + +'simple-case'::[ + parse::{ + name: "simple CASE single WHEN no ELSE", + statement: "CASE name WHEN 'zoe' THEN 1 END", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "simple CASE single WHEN with ELSE", + statement: "CASE name WHEN 'zoe' THEN 1 ELSE 0 END", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "simple CASE multi WHEN with ELSE ", + statement: "CASE name WHEN 'zoe' THEN 1 WHEN 'kumo' THEN 2 WHEN 'mary' THEN 3 ELSE 0 END", + assert: [ + { + result: ParseOk + }, + ] + } +] diff --git a/partiql-test-data/pass/parser/primitives/cast.ion b/partiql-test-data/pass/parser/primitives/cast.ion new file mode 100644 index 0000000..afac1be --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/cast.ion @@ -0,0 +1,79 @@ +parse::{ + name: "CAST as VARCHAR", + statement: "CAST(5 AS VARCHAR)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "CAST as VARCHAR with length", + statement: "CAST(5 AS VARCHAR(5))", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "CAST as DECIMAL", + statement: "CAST(a AS DECIMAL)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "CAST as DECIMAL scale only", + statement: "CAST(a AS DECIMAL(1))", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "CAST as DECIMAL scale and precision", + statement: "CAST(a AS DECIMAL(1, 2))", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "CAST as NUMERIC", + statement: "CAST(a AS NUMERIC)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "CAST as NUMERIC scale only", + statement: "CAST(a AS NUMERIC(1))", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "CAST as NUMERIC scale and precision", + statement: "CAST(a AS NUMERIC(1, 2))", + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/container-constructors.ion b/partiql-test-data/pass/parser/primitives/container-constructors.ion new file mode 100644 index 0000000..a82bc4a --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/container-constructors.ion @@ -0,0 +1,41 @@ +'row-value-constructor'::[ + parse::{ + name: "row value constructor with simple expressions", + statement: "(1, 2, 3, 4)", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "row value constructor with row value constructors", + statement: "((1, 2), (3, 4))", + assert: [ + { + result: ParseOk + }, + ] + } +] + +'table-value-constructor'::[ + parse::{ + name: "table value constructor with row value constructors", + statement: "VALUES (1, 2), (3, 4)", + assert: [ + { + result: ParseOk + }, + ] + }, + parse::{ + name: "table value constructor with singleton row value constructors", + statement: "VALUES (1), (2), (3)", + assert: [ + { + result: ParseOk + }, + ] + } +] diff --git a/partiql-test-data/pass/parser/primitives/extract.ion b/partiql-test-data/pass/parser/primitives/extract.ion new file mode 100644 index 0000000..74f0ec8 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/extract.ion @@ -0,0 +1,79 @@ +parse::{ + name: "call EXTRACT YEAR", + statement: "extract(year from a)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call EXTRACT MONTH", + statement: "extract(month from a)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call EXTRACT DAY", + statement: "extract(day from a)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call EXTRACT HOUR", + statement: "extract(hour from a)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call EXTRACT MINUTE", + statement: "extract(minute from a)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call EXTRACT SECOND", + statement: "extract(second from a)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call EXTRACT TIMEZONE_HOUR", + statement: "extract(timezone_hour from a)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "call EXTRACT TIMEZONE_MINUTE", + statement: "extract(timezone_minute from a)", + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/identifiers.ion b/partiql-test-data/pass/parser/primitives/identifiers.ion new file mode 100644 index 0000000..fb36b06 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/identifiers.ion @@ -0,0 +1,19 @@ +parse::{ + name: "identifier case insensitive", + statement: "kumo", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "identifier case sensitive", + statement: ''' "kumo" ''', + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/operators/at-operator.ion b/partiql-test-data/pass/parser/primitives/operators/at-operator.ion new file mode 100644 index 0000000..c206213 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/operators/at-operator.ion @@ -0,0 +1,19 @@ +parse::{ + name: "at operator on identifier", + statement: "@a", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "at operator on path", + statement: "@a.b", + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/operators/between-operator.ion b/partiql-test-data/pass/parser/primitives/operators/between-operator.ion new file mode 100644 index 0000000..073c920 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/operators/between-operator.ion @@ -0,0 +1,19 @@ +parse::{ + name: "BETWEEN operator", + statement: "5 BETWEEN 1 AND 10", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "NOT BETWEEN operator", + statement: "5 NOT BETWEEN 1 AND 10", + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/operators/in-operator.ion b/partiql-test-data/pass/parser/primitives/operators/in-operator.ion new file mode 100644 index 0000000..cdeecf4 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/operators/in-operator.ion @@ -0,0 +1,29 @@ +parse::{ + name: "IN operator with implicit values", + statement: "a IN (1, 2, 3, 4)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "NOT IN operator with implicit values", + statement: "a NOT IN (1, 2, 3, 4)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "IN operator with implicit values row constructor", + statement: "(a, b) IN ((1, 2), (3, 4))", + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/operators/is-operator.ion b/partiql-test-data/pass/parser/primitives/operators/is-operator.ion new file mode 100644 index 0000000..5f602e5 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/operators/is-operator.ion @@ -0,0 +1,59 @@ +parse::{ + name: "NULL IS NULL", + statement: "null IS NULL", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "MISSING IS MISSING", + statement: "mIsSiNg IS MISSING", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "CALL IS VARCHAR", + statement: "f() IS VARCHAR(200)", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "NULL IS NOT NULL", + statement: "null IS NOT NULL", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "MISSING IS NOT MISSING", + statement: "mIsSiNg IS NOT MISSING", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "CALL IS NOT VARACHAR", + statement: "f() IS NOT VARCHAR(200)", + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/operators/like-operator.ion b/partiql-test-data/pass/parser/primitives/operators/like-operator.ion new file mode 100644 index 0000000..b0a6947 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/operators/like-operator.ion @@ -0,0 +1,88 @@ +/* + From SQL92 https://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt + ::= [ NOT ] LIKE + [ ESCAPE ] + ::= + ::= + ::= +*/ + +parse::{ + name: "col name LIKE string", + statement: "a LIKE '_AAA%'", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "col name LIKE col name", + statement: "a LIKE b", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "path LIKE path", + statement: "a.name LIKE b.pattern", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "col name LIKE string escape", + statement: "a LIKE '_AAA%' ESCAPE '['", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "col name NOT LIKE string", + statement: "a NOT LIKE '_AAA%'", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "col name LIKE col name escape", + statement: "a LIKE b ESCAPE '\\'", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "col name LIKE col name escape non lit", + statement: "a LIKE b ESCAPE c", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "col name LIKE col name escape path", + statement: "a LIKE b ESCAPE x.c", + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/operators/unary-operators.ion b/partiql-test-data/pass/parser/primitives/operators/unary-operators.ion new file mode 100644 index 0000000..4cb256b --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/operators/unary-operators.ion @@ -0,0 +1,69 @@ +parse::{ + name: "neg call", + statement: "-baz()", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "pos neg call", + statement: "+(-baz())", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "pos neg call no spaces", + statement: "+-baz()", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "unary ion int literal", + statement: "-1", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "unary ion float literal", + statement: "+-+-+-`-5e0`", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "unary ion timestamp literal", + statement: "+-`2017-01-01`", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "unary NOT literal", + statement: "not 1", + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/parameter.ion b/partiql-test-data/pass/parser/primitives/parameter.ion new file mode 100644 index 0000000..49577f5 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/parameter.ion @@ -0,0 +1,17 @@ +parse::{ + name: "parameter expression", + statement: "?", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "SELECT with parameter and literals", + statement: "SELECT ?, f.a from foo f where f.bar = ? and f.spam = 'eggs' and f.baz = ?", + assert: { + result: ParseOk + } +} diff --git a/partiql-test-data/pass/parser/primitives/path-expression.ion b/partiql-test-data/pass/parser/primitives/path-expression.ion new file mode 100644 index 0000000..04eb394 --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/path-expression.ion @@ -0,0 +1,139 @@ +parse::{ + name: "dot case one insensitive component", + statement: "a.b", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "dot case two insensitive components", + statement: "a.b.c", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "dot case three insensitive components", + statement: "a.b.c.d", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "dot case sensitive", + statement: ''' "a"."b" ''', + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "dot case sensitive component", + statement: ''' a."b" ''', + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "group dot", + statement: "(a).b", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "path with one square bracket", + statement: "a[5]", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "path with three square brackets", + statement: "a[5]['b'][(a + 3)]", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "dot star", + statement: "a.*", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "dot two star", + statement: "a.b.*", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "dot wildcard", + statement: "a[*]", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "dot two wildcard", + statement: "a.b[*]", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "path with call and dot star", + statement: "foo(x, y).a.*.b", + assert: [ + { + result: ParseOk + }, + ] +} + +parse::{ + name: "dot and bracket star", + statement: "x.a[*].b", + assert: [ + { + result: ParseOk + }, + ] +} diff --git a/partiql-test-data/pass/parser/primitives/union-except-intersect.ion b/partiql-test-data/pass/parser/primitives/union-except-intersect.ion new file mode 100644 index 0000000..f28519e --- /dev/null +++ b/partiql-test-data/pass/parser/primitives/union-except-intersect.ion @@ -0,0 +1,57 @@ +'union-sql'::[ + parse::{ + name: "a UNION b", + statement: "a UNION b", + assert: { + result: ParseOk + } + }, + parse::{ + name: "UNION SELECT precedence", + statement: "SELECT * FROM foo UNION SELECT * FROM bar", + assert: { + result: ParseOk + } + }, + parse::{ + name: "a UNION ALL b", + statement: "a UNION ALL b", + assert: { + result: ParseOk + } + }, +] + +'except-sql'::[ + parse::{ + name: "a EXCEPT b", + statement: "a EXCEPT b", + assert: { + result: ParseOk + } + }, + parse::{ + name: "a EXCEPT ALL b", + statement: "a EXCEPT ALL b", + assert: { + result: ParseOk + } + }, +] + +'intersect-sql'::[ + parse::{ + name: "a INTERSECT b", + statement: "a INTERSECT b", + assert: { + result: ParseOk + } + }, + parse::{ + name: "a INTERSECT ALL b", + statement: "a INTERSECT ALL b", + assert: { + result: ParseOk + } + }, +] diff --git a/partiql-test-data/pass/parser/query/pivot.ion b/partiql-test-data/pass/parser/query/pivot.ion new file mode 100644 index 0000000..ea61f87 --- /dev/null +++ b/partiql-test-data/pass/parser/query/pivot.ion @@ -0,0 +1,15 @@ +parse::{ + name: "PIVOT with only FROM", + statement: "PIVOT v AT n FROM data", + assert: { + result: ParseOk + } +} + +parse::{ + name: "PIVOT HAVING with WHERE and GROUP BY", + statement: "PIVOT g AT ('prefix:' || c) FROM data WHERE a = b GROUP BY c, d GROUP AS g HAVING d > 6", + assert: { + result: ParseOk + } +} diff --git a/partiql-test-data/pass/parser/query/select/group-by.ion b/partiql-test-data/pass/parser/query/select/group-by.ion new file mode 100644 index 0000000..d5cbda4 --- /dev/null +++ b/partiql-test-data/pass/parser/query/select/group-by.ion @@ -0,0 +1,23 @@ +'group-by'::[ + parse::{ + name: "GROUP BY single id", + statement: "SELECT a FROM data GROUP BY a", + assert: { + result: ParseOk + } + }, + parse::{ + name: "GROUP BY single expr", + statement: "SELECT a + b FROM data GROUP BY a + b", + assert: { + result: ParseOk + } + }, + parse::{ + name: "GROUP PARTIAL BY multi aliased and group aliased", + statement: "SELECT g FROM data GROUP PARTIAL BY a AS x, b + c AS y, foo(d) AS z GROUP AS g", + assert: { + result: ParseOk + } + }, +] diff --git a/partiql-test-data/pass/parser/query/select/having.ion b/partiql-test-data/pass/parser/query/select/having.ion new file mode 100644 index 0000000..e609e98 --- /dev/null +++ b/partiql-test-data/pass/parser/query/select/having.ion @@ -0,0 +1,23 @@ +'having'::[ + parse::{ + name: "HAVING minimal", + statement: "SELECT a FROM data HAVING a = b", + assert: { + result: ParseOk + } + }, + parse::{ + name: "HAVING with WHERE", + statement: "SELECT a FROM data WHERE a = b HAVING c = d", + assert: { + result: ParseOk + } + }, + parse::{ + name: "HAVING with WHERE and GROUP BY", + statement: "SELECT g FROM data WHERE a = b GROUP BY c, d GROUP AS g HAVING d > 6", + assert: { + result: ParseOk + } + }, +] diff --git a/partiql-test-data/pass/parser/query/select/joins.ion b/partiql-test-data/pass/parser/query/select/joins.ion new file mode 100644 index 0000000..d76a8bf --- /dev/null +++ b/partiql-test-data/pass/parser/query/select/joins.ion @@ -0,0 +1,31 @@ +parse::{ + name: "SELECT comma CROSS JOIN two tables", + statement: "SELECT a FROM table1, table2", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT comma CROSS JOIN three tables", + statement: "SELECT a FROM table1, table2, table3", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT multiple with CROSS JOIN and simple WHERE", + statement: "SELECT a, b FROM table1 as t1, table2 WHERE f(t1)", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT multiple with CROSS JOIN and simple WHERE no AS alias", + statement: "SELECT a a1, b b1 FROM table1 t1, table2 WHERE f(t1)", + assert: { + result: ParseOk + } +} diff --git a/partiql-test-data/pass/parser/query/select/limit-offset.ion b/partiql-test-data/pass/parser/query/select/limit-offset.ion new file mode 100644 index 0000000..c5138f5 --- /dev/null +++ b/partiql-test-data/pass/parser/query/select/limit-offset.ion @@ -0,0 +1,47 @@ +'limit'::[ + parse::{ + name: "SELECT LIMIT", + statement: "SELECT * FROM a LIMIT 10", + assert: { + result: ParseOk + } + }, + parse::{ + name: "SELECT WHERE LIMIT", + statement: "SELECT * FROM a WHERE a = 5 LIMIT 10", + assert: { + result: ParseOk + } + } +] + +'offset'::[ + parse::{ + name: "SELECT OFFSET", + statement: "SELECT x FROM a OFFSET 5", + assert: { + result: ParseOk + } + }, + parse::{ + name: "SELECT LIMIT OFFSET", + statement: "SELECT x FROM a LIMIT 7 OFFSET 5", + assert: { + result: ParseOk + } + }, + parse::{ + name: "SELECT WHERE LIMIT OFFSET", + statement: "SELECT x FROM a WHERE y = 10 LIMIT 7 OFFSET 5", + assert: { + result: ParseOk + } + }, + parse::{ + name: "SELECT ORDER BY LIMIT OFFSET", + statement: "SELECT x FROM a ORDER BY y DESC LIMIT 10 OFFSET 5", + assert: { + result: ParseOk + } + }, +] diff --git a/partiql-test-data/pass/parser/query/select/order-by.ion b/partiql-test-data/pass/parser/query/select/order-by.ion new file mode 100644 index 0000000..f67bdbe --- /dev/null +++ b/partiql-test-data/pass/parser/query/select/order-by.ion @@ -0,0 +1,51 @@ +'order-by'::[ + parse::{ + name: "ORDER BY single id", + statement: "SELECT a FROM tb WHERE hk = 1 ORDER BY rk1", + assert: { + result: ParseOk + } + }, + parse::{ + name: "ORDER BY multiple ids", + statement: "SELECT a FROM tb WHERE hk = 1 ORDER BY rk1, rk2, rk3", + assert: { + result: ParseOk + } + }, + parse::{ + name: "ORDER BY single id DESC", + statement: "SELECT a FROM tb WHERE hk = 1 ORDER BY rk1 DESC", + assert: { + result: ParseOk + } + }, + parse::{ + name: "ORDER BY multiple ids with ordering spec", + statement: "SELECT a FROM tb WHERE hk = 1 ORDER BY rk1 ASC, rk2 DESC", + assert: { + result: ParseOk + } + }, + parse::{ + name: "ORDER BY ASC with nulls spec", + statement: "SELECT x FROM tb ORDER BY rk1 asc NULLS FIRST, rk2 asc NULLS LAST", + assert: { + result: ParseOk + } + }, + parse::{ + name: "ORDER BY DESC with nulls spec", + statement: "SELECT x FROM tb ORDER BY rk1 desc NULLS FIRST, rk2 desc NULLS LAST", + assert: { + result: ParseOk + } + }, + parse::{ + name: "ORDER BY with ordering and null spec", + statement: "SELECT x FROM tb ORDER BY rk1 desc NULLS FIRST, rk2 asc NULLS LAST, rk3 desc NULLS LAST, rk4 asc NULLS FIRST", + assert: { + result: ParseOk + } + }, +] diff --git a/partiql-test-data/pass/parser/query/select/select-value.ion b/partiql-test-data/pass/parser/query/select/select-value.ion new file mode 100644 index 0000000..67c40f4 --- /dev/null +++ b/partiql-test-data/pass/parser/query/select/select-value.ion @@ -0,0 +1,30 @@ +'select-value'::[ + parse::{ + name: "SELECT VALUE with single FROM", + statement: "SELECT VALUE a FROM table1", + assert: { + result: ParseOk + } + }, + parse::{ + name: "SELECT VALUE with single aliased FROM", + statement: "SELECT VALUE v FROM table1 AS v", + assert: { + result: ParseOk + } + }, + parse::{ + name: "SELECT ALL VALUE", + statement: "SELECT ALL VALUE v FROM table1 AS v", + assert: { + result: ParseOk + } + }, + parse::{ + name: "SELECT DISTINCT VALUE", + statement: "SELECT DISTINCT VALUE v FROM table1 AS v", + assert: { + result: ParseOk + } + }, +] diff --git a/partiql-test-data/pass/parser/query/select/select.ion b/partiql-test-data/pass/parser/query/select/select.ion new file mode 100644 index 0000000..8879f7f --- /dev/null +++ b/partiql-test-data/pass/parser/query/select/select.ion @@ -0,0 +1,123 @@ +parse::{ + name: "SELECT with single FROM", + statement: "SELECT a FROM table1", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT star with single FROM", + statement: "SELECT * FROM table1", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT alias dot star", + statement: "SELECT t.* FROM table1 AS t", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT path alias dot star", + statement: "SELECT a.b.* FROM table1 AS t", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT with FROM AT", + statement: "SELECT ord FROM table1 AT ord", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT with FROM AS and AT", + statement: "SELECT ord, val FROM table1 AS val AT ord", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT with FROM id BY", + statement: "SELECT * FROM table1 BY uid", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT with FROM AT id BY", + statement: "SELECT * FROM table1 AT ord BY uid", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT with FROM AS id BY", + statement: "SELECT * FROM table1 AS t BY uid", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT with FROM AS and AT id BY", + statement: "SELECT * FROM table1 AS val AT ord BY uid", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT WHERE MISSING", + statement: "SELECT a FROM stuff WHERE b IS MISSING", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT list with aggregate wildcard function calls", + statement: "SELECT sum(a) + count(*), AVG(b), MIN(c), MAX(d + e) FROM foo", + assert: { + result: ParseOk + } +} + +parse::{ + name: "paths and select", + statement: ''' + SELECT process(t).a[0] AS a, t2.b AS b + FROM t1.a AS t, t2.x.*.b + WHERE test(t2.name, t1.name) AND t1.id = t2.id + ''', + assert: { + result: ParseOk + } +} + +parse::{ + name: "nested SELECT no WHERE", + statement: "SELECT * FROM (SELECT * FROM x).a", + assert: { + result: ParseOk + } +} + +parse::{ + name: "nested SELECT", + statement: "SELECT * FROM (SELECT * FROM x WHERE b).a", + assert: { + result: ParseOk + } +} diff --git a/partiql-test-data/pass/parser/query/select/set-quantifier.ion b/partiql-test-data/pass/parser/query/select/set-quantifier.ion new file mode 100644 index 0000000..754348f --- /dev/null +++ b/partiql-test-data/pass/parser/query/select/set-quantifier.ion @@ -0,0 +1,31 @@ +parse::{ + name: "SELECT ALL with single FROM", + statement: "SELECT ALL a FROM table1", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT ALL star with single FROM", + statement: "SELECT ALL * FROM table1", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT DISTINCT with single FROM", + statement: "SELECT DISTINCT a FROM table1", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT DISTINCT star with single FROM", + statement: "SELECT DISTINCT * FROM table1", + assert: { + result: ParseOk + } +} diff --git a/partiql-test-data/pass/parser/query/select/unpivot.ion b/partiql-test-data/pass/parser/query/select/unpivot.ion new file mode 100644 index 0000000..36e25e5 --- /dev/null +++ b/partiql-test-data/pass/parser/query/select/unpivot.ion @@ -0,0 +1,31 @@ +parse::{ + name: "SELECT with FROM UNPIVOT", + statement: "SELECT * FROM UNPIVOT item", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT with FROM UNPIVOT with AT", + statement: "SELECT ord FROM UNPIVOT item AT name", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT with FROM UNPIVOT with AS", + statement: "SELECT ord FROM UNPIVOT item AS val", + assert: { + result: ParseOk + } +} + +parse::{ + name: "SELECT with FROM UNPIVOT with AS and AT", + statement: "SELECT ord FROM UNPIVOT item AS val AT name", + assert: { + result: ParseOk + } +} diff --git a/partiql-test-data/pass/parser/select/select-from-where.ion b/partiql-test-data/pass/parser/select/select-from-where.ion deleted file mode 100644 index aa025bc..0000000 --- a/partiql-test-data/pass/parser/select/select-from-where.ion +++ /dev/null @@ -1,7 +0,0 @@ -parse::{ - name: "SELECT with single FROM", - statement: "SELECT a FROM table1", - assert: { - result: ParseOk - }, -}