diff --git a/partiql-ast/src/main/kotlin/org/partiql/ast/sql/SqlDialect.kt b/partiql-ast/src/main/kotlin/org/partiql/ast/sql/SqlDialect.kt index 6a589a0556..c4ad9217fc 100644 --- a/partiql-ast/src/main/kotlin/org/partiql/ast/sql/SqlDialect.kt +++ b/partiql-ast/src/main/kotlin/org/partiql/ast/sql/SqlDialect.kt @@ -64,6 +64,13 @@ public abstract class SqlDialect : AstBaseVisitor() { h = h concat ")" h } + is Expr.BagOp -> { + var h = head + h = h concat "(" + h = visitExprBagOp(node, h) + h = h concat ")" + h + } else -> visitExpr(node, head) } diff --git a/partiql-ast/src/main/kotlin/org/partiql/ast/sql/internal/InternalSqlDialect.kt b/partiql-ast/src/main/kotlin/org/partiql/ast/sql/internal/InternalSqlDialect.kt index 4ecfb9d569..4612feefeb 100644 --- a/partiql-ast/src/main/kotlin/org/partiql/ast/sql/internal/InternalSqlDialect.kt +++ b/partiql-ast/src/main/kotlin/org/partiql/ast/sql/internal/InternalSqlDialect.kt @@ -82,6 +82,13 @@ internal abstract class InternalSqlDialect : AstBaseVisitor { + var t = tail + t = t concat "(" + t = visitExprBagOp(node, t) + t = t concat ")" + t + } else -> visitExpr(node, tail) } diff --git a/partiql-ast/src/test/kotlin/org/partiql/ast/sql/SqlDialectTest.kt b/partiql-ast/src/test/kotlin/org/partiql/ast/sql/SqlDialectTest.kt index 6276adb43d..9520d83519 100644 --- a/partiql-ast/src/test/kotlin/org/partiql/ast/sql/SqlDialectTest.kt +++ b/partiql-ast/src/test/kotlin/org/partiql/ast/sql/SqlDialectTest.kt @@ -986,6 +986,120 @@ class SqlDialectTest { rhs = v("y") } }, + expect("(x UNION y) UNION z") { + exprBagOp { + type = setOp { + type = SetOp.Type.UNION + setq = null + } + outer = false + lhs = exprBagOp { + type = setOp { + type = SetOp.Type.UNION + setq = null + } + outer = false + lhs = v("x") + rhs = v("y") + } + rhs = v("z") + } + }, + expect("x UNION (y UNION z)") { + exprBagOp { + type = setOp { + type = SetOp.Type.UNION + setq = null + } + outer = false + lhs = v("x") + rhs = exprBagOp { + type = setOp { + type = SetOp.Type.UNION + setq = null + } + outer = false + lhs = v("y") + rhs = v("z") + } + } + }, + expect("(x EXCEPT y) EXCEPT z") { + exprBagOp { + type = setOp { + type = SetOp.Type.EXCEPT + setq = null + } + outer = false + lhs = exprBagOp { + type = setOp { + type = SetOp.Type.EXCEPT + setq = null + } + outer = false + lhs = v("x") + rhs = v("y") + } + rhs = v("z") + } + }, + expect("x EXCEPT (y EXCEPT z)") { + exprBagOp { + type = setOp { + type = SetOp.Type.EXCEPT + setq = null + } + outer = false + lhs = v("x") + rhs = exprBagOp { + type = setOp { + type = SetOp.Type.EXCEPT + setq = null + } + outer = false + lhs = v("y") + rhs = v("z") + } + } + }, + expect("(x INTERSECT y) INTERSECT z") { + exprBagOp { + type = setOp { + type = SetOp.Type.INTERSECT + setq = null + } + outer = false + lhs = exprBagOp { + type = setOp { + type = SetOp.Type.INTERSECT + setq = null + } + outer = false + lhs = v("x") + rhs = v("y") + } + rhs = v("z") + } + }, + expect("x INTERSECT (y INTERSECT z)") { + exprBagOp { + type = setOp { + type = SetOp.Type.INTERSECT + setq = null + } + outer = false + lhs = v("x") + rhs = exprBagOp { + type = setOp { + type = SetOp.Type.INTERSECT + setq = null + } + outer = false + lhs = v("y") + rhs = v("z") + } + } + }, ) @JvmStatic