diff --git a/partiql-tests-data/eval/primitives/operators/bag-operators.ion b/partiql-tests-data/eval/primitives/operators/bag-operators.ion index 29fad6c..56bc0e9 100644 --- a/partiql-tests-data/eval/primitives/operators/bag-operators.ion +++ b/partiql-tests-data/eval/primitives/operators/bag-operators.ion @@ -143,56 +143,205 @@ bagOperators::[ ] } }, + // outer union coercion { name:"outerUnionCoerceScalar", statement:"1 OUTER UNION 2", - assert:{ - evalMode:[EvalModeCoerce, EvalModeError], - result:EvaluationSuccess, - output:$bag::[ - 1, - 2 - ] - } + assert:[ + { + evalMode:EvalModeCoerce, + result:EvaluationSuccess, + output:$bag::[ + 1, + 2 + ] + }, + { + evalMode:EvalModeError, + result:EvaluationFail + }, + ] }, { name:"outerUnionCoerceStruct", statement:"{'a': 1} OUTER UNION {'b': 2}", + assert:[ + { + evalMode:EvalModeCoerce, + result:EvaluationSuccess, + output:$bag::[ + { + a:1 + }, + { + b:2 + } + ] + }, + { + evalMode:EvalModeError, + result:EvaluationFail + }, + ] + }, + { + name:"outerUnionCoerceNullMissing", + statement:"NULL OUTER UNION MISSING", + assert:[ + { + evalMode:EvalModeCoerce, + result:EvaluationSuccess, + output:$bag::[ + null, + ] + }, + { + evalMode: EvalModeError, + result:EvaluationFail + }, + ] + }, + { + name:"outerUnionCoerceList", + statement:"[ 1, 1, 1 ] OUTER UNION ALL [ 1, 2 ]", assert:{ evalMode:[EvalModeCoerce, EvalModeError], result:EvaluationSuccess, output:$bag::[ - { - a:1 - }, - { - b:2 - } + 1, + 1, + 1, + 1, + 2 ] } }, + // outer intersect coercion { - name:"outerUnionCoerceNullMissing", - statement:"NULL OUTER UNION MISSING", + name:"outerIntersectCoerceScalar", + statement:"1 OUTER INTERSECT 1", + assert:[ + { + evalMode:EvalModeCoerce, + result:EvaluationSuccess, + output:$bag::[ + 1 + ] + }, + { + evalMode:EvalModeError, + result:EvaluationFail + }, + ] + }, + { + name:"outerIntersectCoerceStruct", + statement:"{'a': 1} OUTER INTERSECT {'a': 1}", + assert:[ + { + evalMode:EvalModeCoerce, + result:EvaluationSuccess, + output:$bag::[ + { + a:1 + } + ] + }, + { + evalMode:EvalModeError, + result:EvaluationFail + }, + ] + }, + { + name:"outerIntersectCoerceNullMissing", + statement:"NULL OUTER INTERSECT MISSING", + assert:[ + { + evalMode:EvalModeCoerce, + result:EvaluationSuccess, + output:$bag::[ + null + ] + }, + { + evalMode: EvalModeError, + result:EvaluationFail + }, + ] + }, + { + name:"outerIntersectCoerceList", + statement:"[ 1, 1, 1 ] OUTER INTERSECT ALL [ 1, 2 ]", assert:{ evalMode:[EvalModeCoerce, EvalModeError], result:EvaluationSuccess, output:$bag::[ + 1 ] } }, + // outer except coercion { - name:"outerUnionCoerceList", - statement:"[ 1, 1, 1 ] OUTER UNION ALL [ 1, 2 ]", + name:"outerExceptCoerceScalar", + statement:"1 OUTER EXCEPT 2", + assert:[ + { + evalMode:EvalModeCoerce, + result:EvaluationSuccess, + output:$bag::[ + 1 + ] + }, + { + evalMode:EvalModeError, + result:EvaluationFail + }, + ] + }, + { + name:"outerExceptCoerceStruct", + statement:"{'a': 1} OUTER EXCEPT {'b': 2}", + assert:[ + { + evalMode:EvalModeCoerce, + result:EvaluationSuccess, + output:$bag::[ + { + a:1 + } + ] + }, + { + evalMode:EvalModeError, + result:EvaluationFail + }, + ] + }, + { + name:"outerExceptCoerceNullMissing", + statement:"NULL OUTER EXCEPT MISSING", + assert:[ + { + evalMode:EvalModeCoerce, + result:EvaluationSuccess, + output:$bag::[] + }, + { + evalMode: EvalModeError, + result:EvaluationFail + }, + ] + }, + { + name:"outerExceptCoerceList", + statement:"[ 1, 1, 1 ] OUTER EXCEPT ALL [ 1, 2 ]", assert:{ evalMode:[EvalModeCoerce, EvalModeError], result:EvaluationSuccess, output:$bag::[ 1, - 1, - 1, - 1, - 2 + 1 ] } }, @@ -244,7 +393,55 @@ bagOperators::[ } }, { - name:"OUTER UNION with ORDER BY LIMIT on children and bag op", + name:"SQL UNION with ORDER BY LIMIT on children and set op", + statement:"(SELECT a, tbl FROM t1 ORDER BY a LIMIT 2) UNION ALL (SELECT a, tbl FROM t2 ORDER BY a LIMIT 2) ORDER BY a LIMIT 2", + assert:{ + evalMode:[EvalModeCoerce, EvalModeError], + result:EvaluationSuccess, + output:[ + { + a: 1, + tbl: 1, + }, + { + a: 2, + tbl: 1 + } + ] + } + }, + { + name:"SQL INTERSECT with ORDER BY LIMIT on children and set op", + statement:"(SELECT a FROM t1 ORDER BY a LIMIT 4) INTERSECT ALL (SELECT a FROM t2 ORDER BY a LIMIT 4) ORDER BY a LIMIT 2", + assert:{ + evalMode:[EvalModeCoerce, EvalModeError], + result:EvaluationSuccess, + output:[ + { + a: 2, + }, + { + a: 3, + } + ] + } + }, + { + name:"SQL EXCEPT with ORDER BY LIMIT on children and set op", + statement:"(SELECT a FROM t1 ORDER BY a LIMIT 2) EXCEPT ALL (SELECT a FROM t2 ORDER BY a LIMIT 2) ORDER BY a LIMIT 2", + assert:{ + evalMode:[EvalModeCoerce, EvalModeError], + result:EvaluationSuccess, + output:[ + { + a: 1, + }, + ] + } + }, + // following tests are equivalent to above but use the PartiQL outer bag op + { + name:"PartiQL OUTER UNION with ORDER BY LIMIT on children and bag op", statement:"(SELECT a, tbl FROM t1 ORDER BY a LIMIT 2) OUTER UNION ALL (SELECT a, tbl FROM t2 ORDER BY a LIMIT 2) ORDER BY a LIMIT 2", assert:{ evalMode:[EvalModeCoerce, EvalModeError], @@ -262,7 +459,7 @@ bagOperators::[ } }, { - name:"OUTER INTERSECT with ORDER BY LIMIT on children and bag op", + name:"PartiQL OUTER INTERSECT with ORDER BY LIMIT on children and bag op", statement:"(SELECT a FROM t1 ORDER BY a LIMIT 4) OUTER INTERSECT ALL (SELECT a FROM t2 ORDER BY a LIMIT 4) ORDER BY a LIMIT 2", assert:{ evalMode:[EvalModeCoerce, EvalModeError], @@ -278,7 +475,7 @@ bagOperators::[ } }, { - name:"OUTER EXCEPT with ORDER BY LIMIT on children and bag op", + name:"PartiQL OUTER EXCEPT with ORDER BY LIMIT on children and bag op", statement:"(SELECT a FROM t1 ORDER BY a LIMIT 2) OUTER EXCEPT ALL (SELECT a FROM t2 ORDER BY a LIMIT 2) ORDER BY a LIMIT 2", assert:{ evalMode:[EvalModeCoerce, EvalModeError], diff --git a/partiql-tests-data/eval/rfc/0007.ion b/partiql-tests-data/eval/rfc/0007.ion index e708b7f..09243ff 100644 --- a/partiql-tests-data/eval/rfc/0007.ion +++ b/partiql-tests-data/eval/rfc/0007.ion @@ -174,14 +174,22 @@ bag::[ { name: "Example 6 — Value Coercion; Coercion of single value", statement: '''SELECT * FROM << 1 >> OUTER UNION 'A' ''', - assert: { - evalMode: [EvalModeCoerce, EvalModeError], - result: EvaluationSuccess, - output: $bag::[ - { "_1": 1 }, - "A", - ] - } + assert: [ + { + evalMode: EvalModeCoerce, + result: EvaluationSuccess, + output: $bag::[ + { + "_1": 1 + }, + "A", + ] + }, + { + evalMode: EvalModeError, + result: EvaluationFail, + }, + ] }, { name: "Example 6 — Value Coercion", diff --git a/partiql-tests-data/success/syntax/primitives/union-except-intersect.ion b/partiql-tests-data/success/syntax/primitives/union-except-intersect.ion index 985102d..ed789cd 100644 --- a/partiql-tests-data/success/syntax/primitives/union-except-intersect.ion +++ b/partiql-tests-data/success/syntax/primitives/union-except-intersect.ion @@ -158,7 +158,7 @@ 'order-by-limit-offset-bag-ops'::[ { - name: "UNION SFW children with ORDER BY LIMIT OFFSET", + name: "SQL UNION SFW children with ORDER BY LIMIT OFFSET", statement: ''' (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) UNION @@ -169,7 +169,7 @@ } }, { - name: "INTERSECT SFW children with ORDER BY LIMIT OFFSET", + name: "SQL INTERSECT SFW children with ORDER BY LIMIT OFFSET", statement: ''' (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) INTERSECT @@ -180,7 +180,7 @@ } }, { - name: "EXCEPT SFW children with ORDER BY LIMIT OFFSET", + name: "SQL EXCEPT SFW children with ORDER BY LIMIT OFFSET", statement: ''' (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) EXCEPT @@ -191,14 +191,14 @@ } }, { - name: "nested bag op with ORDER BY LIMIT OFFSET", + name: "nested SQL set op with ORDER BY LIMIT OFFSET", statement: ''' ( (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) UNION DISTINCT (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) ) - OUTER UNION ALL + UNION ALL (SELECT a3 FROM b3 ORDER BY c3 LIMIT d3 OFFSET e3) ORDER BY c4 LIMIT d4 OFFSET e4''', assert: { @@ -206,16 +206,124 @@ } }, { - name: "deep nested bag ops with ORDER BY LIMIT OFFSET", + name: "bag ops with ORDER BY LIMIT OFFSET in children", statement: ''' - (a UNION b) - INTERSECT - ( - c EXCEPT - d UNION ALL (e INTERSECT f ORDER BY g LIMIT h OFFSET i) - ) - EXCEPT j - ORDER BY k LIMIT l OFFSET m''', + (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) + OUTER UNION + (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) + OUTER INTERSECT ALL + (SELECT a3 FROM b3 ORDER BY c3 LIMIT d3 OFFSET e3) + OUTER EXCEPT DISTINCT + (SELECT a4 FROM b4 ORDER BY c4 LIMIT d4 OFFSET e4) + ''', + assert: { + result: SyntaxSuccess + } + }, + { + name: "allow outer union with ORDER BY", + statement: ''' + (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) + OUTER UNION + (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) + ORDER BY c3 + ''', + assert: { + result: SyntaxSuccess + } + }, + { + name: "allow outer union with LIMIT", + statement: ''' + (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) + OUTER UNION + (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) + LIMIT d3 + ''', + assert: { + result: SyntaxSuccess + } + }, + { + name: "allow outer union with OFFSET", + statement: ''' + (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) + OUTER UNION + (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) + OFFSET e3 + ''', + assert: { + result: SyntaxSuccess + } + }, + { + name: "allow outer intersect with ORDER BY", + statement: ''' + (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) + OUTER INTERSECT + (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) + ORDER BY c3 + ''', + assert: { + result: SyntaxSuccess + } + }, + { + name: "allow outer intersect with LIMIT", + statement: ''' + (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) + OUTER INTERSECT + (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) + LIMIT d3 + ''', + assert: { + result: SyntaxSuccess + } + }, + { + name: "allow outer intersect with OFFSET", + statement: ''' + (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) + OUTER INTERSECT + (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) + OFFSET e3 + ''', + assert: { + result: SyntaxSuccess + } + }, + { + name: "allow outer except with ORDER BY", + statement: ''' + (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) + OUTER EXCEPT + (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) + ORDER BY c3 + ''', + assert: { + result: SyntaxSuccess + } + }, + { + name: "allow outer except with LIMIT", + statement: ''' + (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) + OUTER EXCEPT + (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) + LIMIT d3 + ''', + assert: { + result: SyntaxSuccess + } + }, + { + name: "allow outer except with OFFSET", + statement: ''' + (SELECT a1 FROM b1 ORDER BY c1 LIMIT d1 OFFSET e1) + OUTER EXCEPT + (SELECT a2 FROM b2 ORDER BY c2 LIMIT d2 OFFSET e2) + OFFSET e3 + ''', assert: { result: SyntaxSuccess }