diff --git a/partiql-eval/src/main/kotlin/org/partiql/eval/internal/compiler/StandardCompiler.kt b/partiql-eval/src/main/kotlin/org/partiql/eval/internal/compiler/StandardCompiler.kt index d0ed3ed159..e791764375 100644 --- a/partiql-eval/src/main/kotlin/org/partiql/eval/internal/compiler/StandardCompiler.kt +++ b/partiql-eval/src/main/kotlin/org/partiql/eval/internal/compiler/StandardCompiler.kt @@ -85,7 +85,7 @@ import org.partiql.plan.rex.Rex import org.partiql.plan.rex.RexArray import org.partiql.plan.rex.RexBag import org.partiql.plan.rex.RexCall -import org.partiql.plan.rex.RexCallDynamic +import org.partiql.plan.rex.RexDispatch import org.partiql.plan.rex.RexCase import org.partiql.plan.rex.RexCast import org.partiql.plan.rex.RexCoalesce @@ -338,7 +338,7 @@ internal class StandardCompiler(strategies: List) : PartiQLCompiler { return ExprBag(values) } - override fun visitCallDynamic(rex: RexCallDynamic, ctx: Unit): ExprValue { + override fun visitCallDynamic(rex: RexDispatch, ctx: Unit): ExprValue { // Check candidate arity for uniformity var arity: Int = -1 val name = rex.getName() @@ -401,7 +401,7 @@ internal class StandardCompiler(strategies: List) : PartiQLCompiler { } override fun visitLit(rex: RexLit, ctx: Unit): ExprValue { - return ExprLit(rex.getValue()) + return ExprLit(rex.getDatum()) } override fun visitNullIf(rex: RexNullIf, ctx: Unit): ExprValue { @@ -460,7 +460,7 @@ internal class StandardCompiler(strategies: List) : PartiQLCompiler { } override fun visitSubquery(rex: RexSubquery, ctx: Unit): ExprValue { - val rel = compile(rex.getRel(), ctx) + val rel = compile(rex.getInput(), ctx) val constructor = compile(rex.getConstructor(), ctx) return when (rex.asScalar()) { true -> ExprSubquery(rel, constructor) diff --git a/partiql-plan/README.md b/partiql-plan/README.md new file mode 100644 index 0000000000..f746a8bcd6 --- /dev/null +++ b/partiql-plan/README.md @@ -0,0 +1,32 @@ +# partiql-plan + +## Classes + +* Operator +* Rel +* Rex + +## Visitors + +* Visitor +* Rewriter + +## Design + +For the rule and strategy patterns to work, we need to model classes whose children have a stable ordering; +so we have defined an abstract base class for all operators which holds children and controls the access to them. +We use base implementations for state management and enforcing children ordering; however we use interfaces for the +top-level of each domain. The abstract bases can be extended, and the operator/rel/rex interfaces can be implemented +directly. + +Why interfaces for top-level domain entities and not abstract base classes? + +* We don’t want to force materialization of children (consider wrapping a serde class) +* We don’t want to force holding state (aka having to call super constructors) +* The operator/rel/rex should be flexible for extension and the interface is the most open-ended / non-prescriptive. + +Why abstract base classes for individual operators and not interfaces? + +* Enforce children ordering is the primary reason; also can memoize children. +* Hold state such as mutable tags and computed types. +* We want the standard operators to be prescriptive but not limiting. diff --git a/partiql-plan/src/main/java/org/partiql/plan/Visitor.kt b/partiql-plan/src/main/java/org/partiql/plan/Visitor.kt index 29b5ca0e7f..485e37f848 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/Visitor.kt +++ b/partiql-plan/src/main/java/org/partiql/plan/Visitor.kt @@ -19,7 +19,7 @@ import org.partiql.plan.rel.RelUnpivot import org.partiql.plan.rex.RexArray import org.partiql.plan.rex.RexBag import org.partiql.plan.rex.RexCall -import org.partiql.plan.rex.RexCallDynamic +import org.partiql.plan.rex.RexDispatch import org.partiql.plan.rex.RexCase import org.partiql.plan.rex.RexCast import org.partiql.plan.rex.RexCoalesce @@ -101,7 +101,7 @@ public interface Visitor { public fun visitCall(rex: RexCall, ctx: C): R = defaultVisit(rex, ctx) - public fun visitCallDynamic(rex: RexCallDynamic, ctx: C): R = defaultVisit(rex, ctx) + public fun visitCallDynamic(rex: RexDispatch, ctx: C): R = defaultVisit(rex, ctx) public fun visitCase(rex: RexCase, ctx: C): R = defaultVisit(rex, ctx) diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelAggregate.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelAggregate.java index df12b26bfb..2c6635eeab 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelAggregate.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelAggregate.java @@ -6,7 +6,6 @@ import org.partiql.plan.rex.Rex; import org.partiql.spi.function.Aggregation; -import java.util.Collection; import java.util.List; /** @@ -16,9 +15,6 @@ public abstract class RelAggregate extends RelBase { // TODO GROUP STRATEGY: https://github.com/partiql/partiql-lang-kotlin/issues/1664 - private final RelType type = null; - private List children = null; - /** * @return the input (child 0) */ @@ -26,32 +22,26 @@ public abstract class RelAggregate extends RelBase { public abstract Rel getInput(); @NotNull - public abstract Collection getMeasures(); + public abstract List getMeasures(); @NotNull - public abstract Collection getGroups(); + public abstract List getGroups(); @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getInput(); - children = List.of(c0); - } - return children; + protected final List children() { + Rel c0 = getInput(); + return List.of(c0); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitAggregate(this, ctx); } @@ -61,10 +51,10 @@ public R accept(Visitor visitor, C ctx) { public static class Measure { private final Aggregation agg; - private final Collection args; + private final List args; private final Boolean distinct; - public Measure(Aggregation agg, Collection args, Boolean distinct) { + public Measure(Aggregation agg, List args, Boolean distinct) { this.agg = agg; this.args = args; this.distinct = distinct; @@ -76,7 +66,7 @@ public Aggregation getAgg() { } @NotNull - public Collection getArgs() { + public List getArgs() { return args; } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelBase.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelBase.java index c756d5dea5..8c325e09c3 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelBase.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelBase.java @@ -3,12 +3,16 @@ import org.jetbrains.annotations.NotNull; import org.partiql.plan.Operator; +import java.util.List; + /** * Abstract base class for all relational operators. */ public abstract class RelBase implements Rel { private int tag = 0; + private RelType type; + private List children; @Override public int getTag() { @@ -22,7 +26,39 @@ public void setTag(int tag) { @NotNull @Override - public Operator getChild(int index) { - return getChildren().get(index); + public final RelType getType() { + if (type == null) { + type = type(); + } + return type; + } + + @NotNull + @Override + public final Operator getChild(int index) { + return children.get(index); } + + @NotNull + @Override + public final List getChildren() { + if (children == null) { + children = children(); + } + return children; + } + + /** + * PROTECTED (could also be package private atm). + * + * @return computed type. + */ + protected abstract RelType type(); + + /** + * PROTECTED (could also be package private atm). + * + * @return computed children. + */ + protected abstract List children(); } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelCorrelate.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelCorrelate.java index 7200c27236..364d0caa2f 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelCorrelate.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelCorrelate.java @@ -12,9 +12,6 @@ */ public abstract class RelCorrelate extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return the left input (child 0) */ @@ -32,26 +29,20 @@ public abstract class RelCorrelate extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getLeft(); - Rel c1 = getRight(); - children = List.of(c0, c1); - } - return children; + protected final List children() { + Rel c0 = getLeft(); + Rel c1 = getRight(); + return List.of(c0, c1); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitCorrelate(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelDistinct.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelDistinct.java index cff6d6dc8c..d5119c3401 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelDistinct.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelDistinct.java @@ -11,9 +11,6 @@ */ public abstract class RelDistinct extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return input rel (child 0) */ @@ -22,25 +19,19 @@ public abstract class RelDistinct extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getInput(); - children = List.of(c0); - } - return children; + protected final List children() { + Rel c0 = getInput(); + return List.of(c0); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitDistinct(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelExcept.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelExcept.java index 1e339efa0c..9c22fa30c2 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelExcept.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelExcept.java @@ -11,9 +11,6 @@ */ public abstract class RelExcept extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return true if ALL else DISTINCT. */ @@ -33,26 +30,20 @@ public abstract class RelExcept extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getLeft(); - Rel c1 = getRight(); - children = List.of(c0, c1); - } - return children; + protected final List children() { + Rel c0 = getLeft(); + Rel c1 = getRight(); + return List.of(c0, c1); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitExcept(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelExclude.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelExclude.java index d21e9dd430..9c8a9b0045 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelExclude.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelExclude.java @@ -5,7 +5,6 @@ import org.partiql.plan.Operator; import org.partiql.plan.Visitor; -import java.util.Collection; import java.util.List; /** @@ -13,9 +12,6 @@ */ public abstract class RelExclude extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return input rel (child 0) */ @@ -26,29 +22,23 @@ public abstract class RelExclude extends RelBase { * @return exclusions (not an operator child). */ @NotNull - public abstract Collection getExclusions(); + public abstract List getExclusions(); @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getInput(); - children = List.of(c0); - } - return children; + protected final List children() { + Rel c0 = getInput(); + return List.of(c0); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitExclude(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelFilter.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelFilter.java index 4043147f80..2aa50813b4 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelFilter.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelFilter.java @@ -12,10 +12,6 @@ */ public abstract class RelFilter extends RelBase { - - private List children = null; - private final RelType type = null; - /** * @return input rel (child 0) */ @@ -30,26 +26,20 @@ public abstract class RelFilter extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getInput(); - Rex c1 = getPredicate(); - children = List.of(c0, c1); - } - return children; + protected final List children() { + Rel c0 = getInput(); + Rex c1 = getPredicate(); + return List.of(c0, c1); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitFilter(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelIntersect.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelIntersect.java index 63535692bf..d5b15c4a57 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelIntersect.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelIntersect.java @@ -11,9 +11,6 @@ */ public abstract class RelIntersect extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return true if ALL else DISTINCT. */ @@ -33,26 +30,20 @@ public abstract class RelIntersect extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getLeft(); - Rel c1 = getRight(); - children = List.of(c0, c1); - } - return children; + protected final List children() { + Rel c0 = getLeft(); + Rel c1 = getRight(); + return List.of(c0, c1); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitIntersect(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelIterate.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelIterate.java index c290533a0b..067fc07c72 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelIterate.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelIterate.java @@ -12,9 +12,6 @@ */ public abstract class RelIterate extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return input rex (child 0) */ @@ -23,25 +20,19 @@ public abstract class RelIterate extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rex c0 = getRex(); - children = List.of(c0); - } - return children; + protected final List children() { + Rex c0 = getRex(); + return List.of(c0); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitIterate(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelJoin.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelJoin.java index da5a190d45..5b33845520 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelJoin.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelJoin.java @@ -14,9 +14,6 @@ */ public abstract class RelJoin extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return left input (child 0) */ @@ -43,18 +40,15 @@ public abstract class RelJoin extends RelBase { @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getLeft(); - Rel c1 = getRight(); - Rex c2 = getCondition(); // can be null! - children = List.of(c0, c1, c2); - } - return children; + protected final List children() { + Rel c0 = getLeft(); + Rel c1 = getRight(); + Rex c2 = getCondition(); // can be null! + return List.of(c0, c1, c2); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitJoin(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelLimit.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelLimit.java index 6c364f514e..49d439c960 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelLimit.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelLimit.java @@ -12,9 +12,6 @@ */ public abstract class RelLimit extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return input rel (child 0) */ @@ -29,26 +26,20 @@ public abstract class RelLimit extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getInput(); - Rex c1 = getLimit(); - children = List.of(c0, c1); - } - return children; + protected final List children() { + Rel c0 = getInput(); + Rex c1 = getLimit(); + return List.of(c0, c1); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitLimit(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelOffset.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelOffset.java index fb7a8d8832..4def97fcc8 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelOffset.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelOffset.java @@ -12,9 +12,6 @@ */ public abstract class RelOffset extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return input rel (child 0) */ @@ -29,26 +26,20 @@ public abstract class RelOffset extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getInput(); - Rex c1 = getOffset(); - children = List.of(c0, c1); - } - return children; + protected final List children() { + Rel c0 = getInput(); + Rex c1 = getOffset(); + return List.of(c0, c1); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitOffset(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelProject.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelProject.java index 4a819d9840..9fcba7add4 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelProject.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelProject.java @@ -5,7 +5,6 @@ import org.partiql.plan.Visitor; import org.partiql.plan.rex.Rex; -import java.util.Collection; import java.util.List; /** @@ -13,9 +12,6 @@ */ public abstract class RelProject extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return input rel (child 0) */ @@ -26,29 +22,23 @@ public abstract class RelProject extends RelBase { * @return projection (not a child, it's a list not an operator). */ @NotNull - public abstract Collection getProjections(); + public abstract List getProjections(); @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getInput(); - children = List.of(c0); - } - return children; + protected final List children() { + Rel c0 = getInput(); + return List.of(c0); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitProject(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelScan.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelScan.java index fcecf6eb1f..e5e2474157 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelScan.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelScan.java @@ -12,9 +12,6 @@ */ public abstract class RelScan extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return input rex (child 0) */ @@ -23,25 +20,19 @@ public abstract class RelScan extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rex c0 = getRex(); - children = List.of(c0); - } - return children; + protected final List children() { + Rex c0 = getRex(); + return List.of(c0); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitScan(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelSort.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelSort.java index 92f22e416a..eecc771e26 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelSort.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelSort.java @@ -5,7 +5,6 @@ import org.partiql.plan.Operator; import org.partiql.plan.Visitor; -import java.util.Collection; import java.util.List; /** @@ -13,36 +12,27 @@ */ public abstract class RelSort extends RelBase { - private final RelType type = null; - private List children = null; - @NotNull public abstract Rel getInput(); @NotNull - public abstract Collection getCollations(); + public abstract List getCollations(); @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public List getChildren() { - if (children == null) { - Rel c0 = getInput(); - children = List.of(c0); - } - return children; + protected final List children() { + Rel c0 = getInput(); + return List.of(c0); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitSort(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelUnion.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelUnion.java index 15ae385c2b..6305acab9b 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelUnion.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelUnion.java @@ -11,9 +11,6 @@ */ public abstract class RelUnion extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return true if ALL else DISTINCT. */ @@ -33,26 +30,20 @@ public abstract class RelUnion extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rel c0 = getLeft(); - Rel c1 = getRight(); - children = List.of(c0, c1); - } - return children; + protected final List children() { + Rel c0 = getLeft(); + Rel c1 = getRight(); + return List.of(c0, c1); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitUnion(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rel/RelUnpivot.java b/partiql-plan/src/main/java/org/partiql/plan/rel/RelUnpivot.java index 8ca5cf21cd..5e0ce16b2a 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rel/RelUnpivot.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rel/RelUnpivot.java @@ -12,9 +12,6 @@ */ public abstract class RelUnpivot extends RelBase { - private final RelType type = null; - private List children = null; - /** * @return input rex (child 0) */ @@ -23,25 +20,19 @@ public abstract class RelUnpivot extends RelBase { @NotNull @Override - public final RelType getType() { - if (type == null) { - throw new UnsupportedOperationException("Derive type is not implemented"); - } - return type; + protected final RelType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } @NotNull @Override - public final List getChildren() { - if (children == null) { - Rex c0 = getRex(); - children = List.of(c0); - } - return children; + protected final List children() { + Rex c0 = getRex(); + return List.of(c0); } @Override - public R accept(Visitor visitor, C ctx) { + public R accept(@NotNull Visitor visitor, C ctx) { return visitor.visitUnpivot(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexArray.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexArray.java index b202f717c7..3355c11c35 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexArray.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexArray.java @@ -1,41 +1,38 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.types.PType; -/** - * TODO DOCUMENTATION - */ -public interface RexArray : Rex { - - public fun getValues(): Collection - - - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitArray(this, ctx) -} +import java.util.List; /** - * Default [RexArray] operator for extension. + * Logical array expression abstract base class. */ -internal class RexArrayImpl(values: Collection, type: RexType) : RexArray { +public abstract class RexArray extends RexBase { - // DO NOT USE FINAL - private var _values = values - private var _type = type + /** + * @return the values of the array, also the children. + */ + @NotNull + public abstract List getValues(); - override fun getValues(): Collection = _values - - - - override fun getType(): RexType = _type + @NotNull + @Override + protected final RexType type() { + return new RexType(PType.array()); + } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexArray) return false - if (_values != other.getValues()) return false - return true + @NotNull + @Override + protected final List children() { + List varargs = getValues(); + return List.copyOf(varargs); } - override fun hashCode(): Int = _values.hashCode() + @Override + public R accept(@NotNull Visitor visitor, C ctx) { + return visitor.visitArray(this, ctx); + } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexBag.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexBag.java index 735f865a53..38f3285579 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexBag.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexBag.java @@ -1,41 +1,38 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.types.PType; -/** - * TODO DOCUMENTATION - */ -public interface RexBag : Rex { - - public fun getValues(): Collection - - - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitBag(this, ctx) -} +import java.util.List; /** - * Default [RexBag] operator for extension. + * Logical bag expression abstract base class. */ -internal class RexBagImpl(values: Collection, type: RexType) : RexBag { +public abstract class RexBag extends RexBase { - // DO NOT USE FINAL - private var _values = values - private var _type = type + /** + * @return the values of the array, also the children. + */ + @NotNull + public abstract List getValues(); - override fun getValues(): Collection = _values - - - - override fun getType(): RexType = _type + @NotNull + @Override + protected final RexType type() { + return new RexType(PType.bag()); + } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexBag) return false - if (_values != other.getValues()) return false - return true + @NotNull + @Override + protected final List children() { + List varargs = getValues(); + return List.copyOf(varargs); } - override fun hashCode(): Int = _values.hashCode() + @Override + public R accept(@NotNull Visitor visitor, C ctx) { + return visitor.visitBag(this, ctx); + } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexBase.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexBase.java new file mode 100644 index 0000000000..da5701465b --- /dev/null +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexBase.java @@ -0,0 +1,64 @@ +package org.partiql.plan.rex; + +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; + +import java.util.List; + +/** + * Abstract base class for all scalar expressions. + */ +public abstract class RexBase implements Rex { + + private int tag = 0; + private List children; + private RexType type; + + @Override + public int getTag() { + return tag; + } + + @Override + public void setTag(int tag) { + this.tag = tag; + } + + @NotNull + @Override + public final RexType getType() { + if (type == null) { + type = type(); + } + return type; + } + + @NotNull + @Override + public final Operator getChild(int index) { + return children.get(index); + } + + @NotNull + @Override + public final List getChildren() { + if (children == null) { + children = children(); + } + return children; + } + + /** + * PROTECTED (could also be package private atm). + * + * @return computed type. + */ + protected abstract RexType type(); + + /** + * PROTECTED (could also be package private atm). + * + * @return computed children. + */ + protected abstract List children(); +} diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexCall.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexCall.java index b42ef55654..230a5bd58e 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexCall.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexCall.java @@ -1,44 +1,43 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor -import org.partiql.spi.function.Function +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.spi.function.Function; + +import java.util.List; /** - * Logical operator for a scalar function call. + * Logical scalar function expression abstract base class. */ -public interface RexCall : Rex { +public abstract class RexCall extends RexBase { /** * Returns the function to invoke. */ - public fun getFunction(): Function.Instance + @NotNull + public abstract Function.Instance getFunction(); /** * Returns the list of function arguments. */ - public fun getArgs(): List - - + @NotNull + public abstract List getArgs(); @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitCall(this, ctx) -} - -/** - * Default [RexCall] implementation meant for extension. - */ -internal class RexCallImpl(function: Function.Instance, args: List) : RexCall { + protected RexType type() { + return new RexType(getFunction().returns); + } - // DO NOT USE FINAL - private var _function: Function.Instance = function - private var _args: List = args - private var _type: RexType = RexType(function.returns) - - override fun getFunction(): Function.Instance = _function - - override fun getArgs(): List = _args - - override fun getType(): RexType = _type + @Override + protected List children() { + List varargs = getArgs(); + return List.copyOf(varargs); + } - + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitCall(this, ctx); + } } + diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexCallDynamic.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexCallDynamic.java deleted file mode 100644 index cfe96c5d6e..0000000000 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexCallDynamic.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.partiql.plan.rex - -import org.partiql.plan.Visitor -import org.partiql.spi.function.Function -import org.partiql.types.PType - -/** - * Logical operator for a dynamic dispatch call. - */ -public interface RexCallDynamic : Rex { - - /** - * Dynamic function name. - */ - public fun getName(): String - - /** - * Returns the functions to dispatch to. - */ - public fun getFunctions(): List - - /** - * Returns the list of function arguments. - */ - public fun getArgs(): List - - - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitCallDynamic(this, ctx) -} - -/** - * Default [RexCallDynamic] implementation meant for extension. - */ -internal class RexCallDynamicImpl( - private var name: String, - private var functions: List, - private var args: List, - type: PType = PType.dynamic() -) : RexCallDynamic { - - // DO NOT USE FINAL - private var _type: RexType = RexType(type) - - override fun getName(): String = name - - override fun getFunctions(): List = functions - - override fun getArgs(): List = args - - override fun getType(): RexType = _type - - -} diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexCase.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexCase.java index 697a8b56bf..4d1a8dba81 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexCase.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexCase.java @@ -1,105 +1,77 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; + +import java.util.List; /** - * Representative of the simple CASE-WHEN. + * Logical case (switch) expression abstract base class. */ -public interface RexCase : Rex { - - public fun getMatch(): Rex? - - public fun getBranches(): List - - public fun getDefault(): Rex? - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitCase(this, ctx) - - - val children = mutableListOf() - val match = getMatch() - val branches = getBranches() - val default = getDefault() - if (match != null) { - children.add(match) - } - for (branch in branches) { - children.add(branch.getCondition()) - children.add(branch.getResult()) - } - if (default != null) { - children.add(default) - } - return children - } +public abstract class RexCase extends RexBase { /** - * TODO DOCUMENTATION + * @return the match expression, or {@code null} if none (child 0) */ - public interface Branch { - public fun getCondition(): Rex - public fun getResult(): Rex - } -} - -/** - * Internal implementation of [RexCase]. - */ -internal class RexCaseImpl(match: Rex?, branches: List, default: Rex?, type: RexType) : RexCase { + @Nullable + public abstract Rex getMatch(); - // DO NOT USE FINAL - private var _match = match - private var _branches = branches - private var _default = default - private var _children: Collection? = null - private var _type = type - - override fun getMatch(): Rex? = _match - - override fun getBranches(): List = _branches + /** + * @return the list of branches (not children). + */ + @NotNull + public abstract List getBranches(); - override fun getDefault(): Rex? = _default + /** + * @return the default expression, or {@code null} if none (child 1) + */ + @Nullable + public abstract Rex getDefault(); - - if (_children == null) { - _children = super.getChildren() - } - return _children!! + @NotNull + @Override + protected final RexType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } - override fun getType(): RexType = _type - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexCase) return false - if (_match != other.getMatch()) return false - if (_branches != other.getBranches()) return false - if (_default != other.getDefault()) return false - return true + @Override + protected List children() { + Rex c0 = getMatch(); + Rex c1 = getDefault(); + return List.of(c0, c1); } - override fun hashCode(): Int { - var result = _match.hashCode() - result = 31 * result + _branches.hashCode() - result = 31 * result + _default.hashCode() - return result + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitCase(this, ctx); } /** - * CASE-WHEN branch - * - * @param condition - * @param result + * A branch of a case expression. */ - internal class Branch(condition: Rex, result: Rex) : RexCase.Branch { + public static class Branch { + + @NotNull + private final Rex condition; - // DO NOT USE FINAL - private var _condition = condition - private var _result = result + @NotNull + private final Rex result; - override fun getCondition(): Rex = _condition + public Branch(@NotNull Rex condition, @NotNull Rex result) { + this.condition = condition; + this.result = result; + } + + @NotNull + public Rex getCondition() { + return condition; + } - override fun getResult(): Rex = _result + @NotNull + public Rex getResult() { + return result; + } } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexCast.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexCast.java index ced96be5d9..843b9e217e 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexCast.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexCast.java @@ -1,59 +1,33 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor -import org.partiql.types.PType +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Visitor; +import org.partiql.types.PType; /** - * Logical `CAST` operator — ex: CAST( AS ). + * Logical cast expression abstract base class. */ -public interface RexCast : Rex { - - public fun getOperand(): Rex - - public fun getTarget(): PType - - - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitCast(this, ctx) -} - -/** - * Default [RexCast] implementation meant for extension. - */ -internal class RexCastImpl(operand: Rex, target: PType) : RexCast { - - // DO NOT USE FINAL - private var _operand = operand - private var _target = target - private var _children: List? = null - private var _type = RexType(_target) - - override fun getOperand(): Rex = _operand - - override fun getTarget(): PType = _target - - - if (_children == null) { - _children = listOf(_operand) - } - return _children!! +public abstract class RexCast extends RexBase { + + /** + * @return operand rex (child 0) + */ + @NotNull + public abstract Rex getOperand(); + + /** + * @return target type + */ + @NotNull + public abstract PType getTarget(); + + @NotNull + protected final RexType type() { + return new RexType(getTarget()); } - override fun getType(): RexType = _type - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexCast) return false - if (_operand != other.getOperand()) return false - if (_target != other.getTarget()) return false - return true - } - - override fun hashCode(): Int { - var result = 1 - result = 31 * result + _operand.hashCode() - result = 31 * result + _target.hashCode() - return result + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitCast(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexCoalesce.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexCoalesce.java index af7b0550e7..db5e8e25d0 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexCoalesce.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexCoalesce.java @@ -1,38 +1,35 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; + +import java.util.List; /** - * TODO DOCUMENTATION + * Logical coalesce expression abstract base class. */ -public interface RexCoalesce : Rex { - - public fun getArgs(): List +public abstract class RexCoalesce extends RexBase { - + /** + * @return the list of arguments (also the children). + */ + @NotNull + public abstract List getArgs(); @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitCoalesce(this, ctx) -} - -internal class RexCoalesceImpl(args: List, type: RexType) : RexCoalesce { - - // DO NOT USE FINAL - private var _args = args - private var _type = type - - override fun getArgs(): List = _args - - - - override fun getType(): RexType = _type + protected final RexType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); + } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexCoalesce) return false - if (_args != other.getArgs()) return false - return true + @Override + protected final List children() { + List varargs = getArgs(); + return List.copyOf(varargs); } - override fun hashCode(): Int = _args.hashCode() + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitCoalesce(this, ctx); + } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexDispatch.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexDispatch.java new file mode 100644 index 0000000000..0f37829f0b --- /dev/null +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexDispatch.java @@ -0,0 +1,46 @@ +package org.partiql.plan.rex; + +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.spi.function.Function; + +import java.util.List; + +/** + * Logical operator for a dynamic dispatch. + */ +public abstract class RexDispatch extends RexBase { + + /** + * Dynamic function name. + */ + public abstract String getName(); + + /** + * Returns the functions to dispatch to. + */ + public abstract List getFunctions(); + + /** + * Returns the list of function arguments. + */ + public abstract List getArgs(); + + @NotNull + @Override + protected final RexType type() { + return RexType.dynamic(); + } + + @Override + protected final List children() { + List varargs = getArgs(); + return List.copyOf(varargs); + } + + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitCallDynamic(this, ctx); + } +} diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexError.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexError.java index 7467d72e53..adb28ee8b9 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexError.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexError.java @@ -1,19 +1,29 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; + +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.types.PType; + +import java.util.List; /** * This represents scenarios in which certain operations are statically known to fail in strict mode but return missing * in permissive mode. */ -import org.partiql.plan.Visitor - -public interface RexError : Rex { +public abstract class RexError extends RexBase { - override fun getType(): RexType = RexType.dynamic() + @Override + protected RexType type() { + return new RexType(PType.unknown()); + } - + @Override + protected List children() { + return List.of(); + } @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitError(this, ctx) + public R accept(Visitor visitor, C ctx) { + return visitor.visitError(this, ctx); + } } - -internal class RexErrorImpl : RexError diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexLit.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexLit.java index fb8b0591e1..3af906727a 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexLit.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexLit.java @@ -1,37 +1,33 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor -import org.partiql.spi.value.Datum +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.spi.value.Datum; + +import java.util.List; /** - * TODO DOCUMENTATION + * Literal value expression abstract base class. */ -public interface RexLit : Rex { - - public fun getValue(): Datum +public abstract class RexLit extends RexBase { - + @NotNull + public abstract Datum getDatum(); + @NotNull @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitLit(this, ctx) -} - -internal class RexLitImpl(value: Datum) : RexLit { - - // DO NOT USE FINAL - private var _value = value - private var _type = RexType(_value.type) - - override fun getValue(): Datum = _value - - override fun getType(): RexType = _type + protected final RexType type() { + return new RexType(getDatum().getType()); + } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexLit) return false - if (_value != other.getValue()) return false - return true + @Override + protected List children() { + return List.of(); } - override fun hashCode(): Int = _value.hashCode() + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitLit(this, ctx); + } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexNullIf.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexNullIf.java index a371df6a1b..8ef173582e 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexNullIf.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexNullIf.java @@ -1,50 +1,43 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; -/** - * Logical operator for the SQL NULLIF special form. - */ -public interface RexNullIf : Rex { - - public fun getV1(): Rex - - public fun getV2(): Rex - - - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitNullIf(this, ctx) -} +import java.util.List; /** - * Internal + * Logical nullif expression abstraction base class. */ -internal class RexNullIfImpl(v1: Rex, v2: Rex) : RexNullIf { - - // DO NOT USE FINAL - private var _v1 = v1 - private var _v2 = v2 +public abstract class RexNullIf extends RexBase { - override fun getV1(): Rex = _v1 + /** + * @return v1 rex (child 0) + */ + @NotNull + public abstract Rex getV1(); - override fun getV2(): Rex = _v2 + /** + * @return v2 rex (child 1) + */ + @NotNull + public abstract Rex getV2(); - override fun getType(): RexType = _v1.getType() - - + @NotNull + @Override + protected final RexType type() { + return getV1().getType(); + } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexNullIf) return false - if (_v1 != other.getV1()) return false - if (_v2 != other.getV2()) return false - return true + @Override + protected final List children() { + Rex c0 = getV1(); + Rex c1 = getV2(); + return List.of(c0, c1); } - override fun hashCode(): Int { - var result = _v1.hashCode() - result = 31 * result + _v2.hashCode() - return result + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitNullIf(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathIndex.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathIndex.java index 53d4f80039..67d0eaeea4 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathIndex.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathIndex.java @@ -1,35 +1,42 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; -/** - * Logical path index operator. - */ -public interface RexPathIndex : Rex { - - public fun getOperand(): Rex - - public fun getIndex(): Rex - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitPathIndex(this, ctx) -} +import java.util.List; /** - * Standard internal implementation for [RexPathIndex]. + * Logical path by index expression abstract base class. */ -internal class RexPathIndexImpl(operand: Rex, index: Rex, type: RexType) : RexPathIndex { +public abstract class RexPathIndex extends RexBase { - // DO NOT USE FINAL - private var _operand = operand - private var _index = index - private var _type = type + /** + * @return operand rex (child 0) + */ + @NotNull + public abstract Rex getOperand(); - override fun getOperand() = _operand + /** + * @return index rex (child 1) + */ + public abstract Rex getIndex(); - override fun getIndex() = _index + @Override + @NotNull + protected final RexType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); + } - override fun getType(): RexType = _type + @Override + protected final List children() { + Rex c0 = getOperand(); + Rex c1 = getIndex(); + return List.of(c0, c1); + } - + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitPathIndex(this, ctx); + } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathKey.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathKey.java index b59243a314..03555a7e0f 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathKey.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathKey.java @@ -1,35 +1,43 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; -/** - * Logical operator for path lookup by key. - */ -public interface RexPathKey : Rex { - - public fun getOperand(): Rex - - public fun getKey(): Rex - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitPathKey(this, ctx) -} +import java.util.List; /** - * Standard internal implementation for [RexPathKey]. + * Logical path by key lookup expression abstract base class. */ -internal class RexPathKeyImpl(operand: Rex, key: Rex, type: RexType) : RexPathKey { +public abstract class RexPathKey extends RexBase { - // DO NOT USE FINAL - private var _operand = operand - private var _key = key - private var _type = type + /** + * @return operand rex (child 0) + */ + @NotNull + public abstract Rex getOperand(); - override fun getOperand() = _operand + /** + * @return key rex (child 1) + */ + @NotNull + public abstract Rex getKey(); - override fun getKey() = _key + @Override + @NotNull + protected final RexType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); + } - override fun getType(): RexType = _type + @Override + protected List children() { + Rex c0 = getOperand(); + Rex c1 = getKey(); + return List.of(c0, c1); + } - + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitPathKey(this, ctx); + } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathSymbol.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathSymbol.java index 0b9275568e..0d85219862 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathSymbol.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexPathSymbol.java @@ -1,35 +1,42 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; -/** - * Logical operator for path lookup by symbol. - */ -public interface RexPathSymbol : Rex { - - public fun getOperand(): Rex - - public fun getSymbol(): String - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitPathSymbol(this, ctx) -} +import java.util.List; /** - * Standard internal implementation for [RexPathSymbol]. + * Logical path by symbol lookup expression abstract base class. */ -internal class RexPathSymbolImpl(operand: Rex, symbol: String, type: RexType) : RexPathSymbol { +public abstract class RexPathSymbol extends RexBase { - // DO NOT USE FINAL - private var _operand = operand - private var _symbol = symbol - private var _type = type + /** + * @return operand rex (child 0) + */ + @NotNull + public abstract Rex getOperand(); - override fun getOperand() = _operand + /** + * @return symbol string + */ + @NotNull + public abstract String getSymbol(); - override fun getSymbol() = _symbol + @Override + @NotNull + protected final RexType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); + } - override fun getType(): RexType = _type + @Override + protected final List children() { + Rex c0 = getOperand(); + return List.of(c0); + } - + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitPathSymbol(this, ctx); + } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexPivot.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexPivot.java index b41e85670c..b1eaa24b25 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexPivot.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexPivot.java @@ -1,75 +1,52 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor -import org.partiql.plan.rel.Rel -import org.partiql.types.PType +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.plan.rel.Rel; +import org.partiql.types.PType; -/** - * TODO DOCUMENTATION - */ -public interface RexPivot : Rex { - - public fun getInput(): Rel - - public fun getKey(): Rex - - public fun getValue(): Rex - - - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitPivot(this, ctx) -} +import java.util.List; /** - * Default [RexPivot] operator. + * Logical pivot expression abstract base class. */ -internal class RexPivotImpl(input: Rel, key: Rex, value: Rex) : RexPivot { - - // DO NOT USE FINAL - private var _input = input - private var _key = key - private var _value = value - - private var children: List? = null - private var type: PType? = null - - override fun getInput(): Rel = _input - - override fun getKey(): Rex = _key - - override fun getValue(): Rex = _value - - override fun getType(): RexType { - if (type == null) { - type = PType.struct() - } - return RexType(type!!) - } - - - if (children == null) { - children = listOf(getKey(), getValue()) - } - return children!! +public abstract class RexPivot extends RexBase { + + /** + * @return input rel (child 0) + */ + @NotNull + public abstract Rel getInput(); + + /** + * @return key rex (child 1) + */ + @NotNull + public abstract Rex getKey(); + + /** + * @return value rex (child 2) + */ + @NotNull + public abstract Rex getValue(); + + @NotNull + @Override + protected final RexType type() { + return new RexType(PType.struct()); } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexPivot) return false - - if (_input != other.getInput()) return false - if (_key != other.getKey()) return false - if (_value != other.getValue()) return false - - return true + @Override + protected final List children() { + Rel c0 = getInput(); + Rex c1 = getKey(); + Rex c2 = getValue(); + return List.of(c0, c1, c2); } - override fun hashCode(): Int { - var result = 1 - result = 31 * result + _input.hashCode() - result = 31 * result + _key.hashCode() - result = 31 * result + _value.hashCode() - return result + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitPivot(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSelect.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSelect.java index 4ec74c5eb2..50f529cc12 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSelect.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSelect.java @@ -1,60 +1,45 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor -import org.partiql.plan.rel.Rel -import org.partiql.types.PType +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.plan.rel.Rel; +import org.partiql.types.PType; + +import java.util.List; /** - * TODO DOCUMENTATION + * Logical select expression abstract base class. */ -public interface RexSelect : Rex { - - public fun getInput(): Rel +public abstract class RexSelect extends RexBase { - public fun getConstructor(): Rex + /** + * @return input rel (child 0) + */ + @NotNull + public abstract Rel getInput(); - + /** + * @return constructor rex (child 1) + */ + public abstract Rex getConstructor(); + @NotNull @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitSelect(this, ctx) -} - -internal class RexSelectImpl(input: Rel, constructor: Rex) : RexSelect { - - private var _input = input - private var _constructor = constructor - private var _type: RexType? = null - - override fun getInput(): Rel = _input - - override fun getConstructor(): Rex = _constructor - - override fun getType(): RexType { - // compute type - if (_type == null) { - val e = _constructor.getType().getPType() - _type = if (_input.isOrdered()) { - RexType(PType.array(e)) - } else { - RexType(PType.bag(e)) - } - } - return _type!! + protected final RexType type() { + return new RexType(PType.bag()); } - - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexSelect) return false - if (_input != other.getInput()) return false - if (_constructor != other.getConstructor()) return false - return true + @NotNull + @Override + protected final List children() { + Rel c0 = getInput(); + Rex c1 = getConstructor(); + return List.of(c0, c1); } - override fun hashCode(): Int { - var result = _input.hashCode() - result = 31 * result + _constructor.hashCode() - return result + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitSelect(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSpread.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSpread.java index 4515b99698..547495bb06 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSpread.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSpread.java @@ -1,44 +1,36 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.types.PType; -/** - * TODO DOCUMENTATION - */ -public interface RexSpread : Rex { - - public fun getArgs(): List - - - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitSpread(this, ctx) -} +import java.util.List; /** - * Default [RexSpread] operator intended for extension. + * Logical spread expression abstract base class. */ -internal class RexSpreadImpl(args: List, type: RexType) : RexSpread { - - // DO NOT USE FINAL - private var _args = args - private var _type = type +public abstract class RexSpread extends RexBase { - override fun getArgs(): List = _args + /** + * @return list of spread arguments (the children) + */ + public abstract List getArgs(); - override fun getType(): RexType = _type + @NotNull + @Override + protected final RexType type() { + return new RexType(PType.struct()); + } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexSpreadImpl) return false - if (_args != other._args) return false - if (_type != other._type) return false - return true + @NotNull + @Override + protected final List children() { + List varargs = getArgs().stream().toList(); + return List.copyOf(varargs); } - override fun hashCode(): Int { - var result = _args.hashCode() - result = 31 * result + _type.hashCode() - return result + public R accept(Visitor visitor, C ctx) { + return visitor.visitSpread(this, ctx); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexStruct.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexStruct.java index ec178cac19..1f9ee71574 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexStruct.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexStruct.java @@ -1,65 +1,57 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.types.PType; + +import java.util.List; /** - * TODO DOCUMENTATION + * Logical struct expression abstract base class. */ -public interface RexStruct : Rex { +public abstract class RexStruct extends RexBase { - public fun getFields(): List + /** + * @return list of struct fields (NOT children) + */ + public abstract List getFields(); - - val children = mutableListOf() - for (field in getFields()) { - children.add(field.getKey()) - children.add(field.getValue()) - } - return children + @NotNull + @Override + protected final RexType type() { + return new RexType(PType.struct()); } @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitStruct(this, ctx) - - /** - * TODO DOCUMENTATION - */ - public class Field( - private var key: Rex, - private var value: Rex, - ) { - public fun getKey(): Rex = key - public fun getValue(): Rex = value + protected List children() { + return List.of(); } -} -/** - * Default [RexStruct] implementation intended for extension. - */ -internal class RexStructImpl(fields: List, type: RexType) : RexStruct { + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitStruct(this, ctx); + } - // DO NOT USE FINAL - private var _fields = fields - private var _children: Collection? = null - private var _type = type + /** + * Struct expression field constructor. + */ + public static class Field { - override fun getFields(): List = _fields + private final Rex key; + private final Rex value; - override fun getType(): RexType = _type + public Field(Rex key, Rex value) { + this.key = key; + this.value = value; + } - - if (_children == null) { - _children = super.getChildren() + public Rex getKey() { + return key; } - return _children!! - } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexStruct) return false - if (_fields != other.getFields()) return false - return true + public Rex getValue() { + return value; + } } - - override fun hashCode(): Int = _fields.hashCode() } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubquery.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubquery.java index 3250bc70e2..c91b14865f 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubquery.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubquery.java @@ -1,56 +1,43 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.plan.rel.Rel; + +import java.util.List; /** - * Scalar subquery coercion. + * Logical subquery expression abstract base class. */ -public interface RexSubquery : Rex { +public abstract class RexSubquery extends RexBase { - public fun getRel(): org.partiql.plan.rel.Rel + /** + * @return input rel (child 0) + */ + @NotNull + public abstract Rel getInput(); // TODO REMOVE ME – TEMPORARY UNTIL PLANNER PROPERLY HANDLES SUBQUERIES - public fun getConstructor(): Rex + public abstract Rex getConstructor(); // TODO REMOVE ME – TEMPORARY UNTIL PLANNER PROPERLY HANDLES SUBQUERIES - public fun asScalar(): Boolean + public abstract boolean asScalar(); + @NotNull @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitSubquery(this, ctx) -} - -/** - * Implementation of scalar subquery coercion. - */ -internal class RexSubqueryImpl(rel: org.partiql.plan.rel.Rel, constructor: Rex, asScalar: Boolean) : RexSubquery { - - // DO NOT USE FINAL - private var _rel = rel - private var _constructor = constructor - private var _asScalar = asScalar - - override fun getRel(): org.partiql.plan.rel.Rel = _rel - - override fun getConstructor(): Rex = _constructor - - override fun asScalar(): Boolean = _asScalar - - override fun getType(): RexType { - TODO("Not yet implemented") - } - - - TODO("Not yet implemented") + protected final RexType type() { + throw new UnsupportedOperationException("Derive type is not implemented"); } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexSubquery) return false - if (_rel != other.getRel()) return false - return true + @Override + protected final List children() { + Rel c0 = getInput(); + return List.of(c0); } - override fun hashCode(): Int { - return _rel.hashCode() + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitSubquery(this, ctx); } -} +} \ No newline at end of file diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryComp.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryComp.java index 799b64b13c..8a3a0252af 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryComp.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryComp.java @@ -1,86 +1,129 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor -import org.partiql.plan.rel.Rel -import org.partiql.plan.rex.RexSubqueryComp.Comp -import org.partiql.plan.rex.RexSubqueryComp.Quantifier +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Visitor; +import org.partiql.plan.rel.Rel; +import org.partiql.types.PType; + +import java.util.List; /** - * Logical operator for SQL subquery comparisons. - * - * - for subqueries. - * - . + * Logical subquery comparison expression abstract base class. + *

+ * See SQL-99 and . */ -public interface RexSubqueryComp : Rex { +public abstract class RexSubqueryComp extends RexBase { - public fun getArgs(): List + /** + * @return input rel (child 0) + */ + @NotNull + public abstract Rel getInput(); - public fun getComp(): Comp + /** + * @return collection comparison arguments (not children). + */ + @NotNull + public abstract List getArgs(); - public fun getQuantifier(): Quantifier? + /** + * @return subquery comparison operator + */ + @NotNull + public abstract Comparison getComparison(); - public fun getRel(): Rel + /** + * @return subquery comparison quantifier + */ + @NotNull + public abstract Quantifier getQuantifier(); + + @NotNull + @Override + protected final RexType type() { + return new RexType(PType.bool()); + } @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitSubqueryComp(this, ctx) + public R accept(Visitor visitor, C ctx) { + return visitor.visitSubqueryComp(this, ctx); + } /** * SQL for use in the . - * - * TODO transition to 1.0 enums. */ - public enum class Comp { - EQ, - NE, - LT, - LE, - GT, - GE, - OTHER; + public static class Comparison extends org.partiql.spi.Enum { + + private Comparison(int code) { + super(code); + } + + public static int UNKNOWN = 0; + public static int EQ = 1; + public static int NE = 2; + public static int LT = 3; + public static int LE = 4; + public static int GT = 5; + public static int GE = 6; + + @NotNull + public static Comparison EQ() { + return new Comparison(EQ); + } + + @NotNull + public static Comparison NE() { + return new Comparison(NE); + } + + @NotNull + public static Comparison LT() { + return new Comparison(LT); + } + + @NotNull + public static Comparison LE() { + return new Comparison(LE); + } + + @NotNull + public static Comparison GT() { + return new Comparison(GT); + } + + @NotNull + public static Comparison GE() { + return new Comparison(GE); + } } /** * SQL for use in the . - * - * TODO transition to 1.0 enums. */ - public enum class Quantifier { - ANY, - ALL, - SOME, - OTHER; + public static class Quantifier extends org.partiql.spi.Enum { + + private Quantifier(int code) { + super(code); + } + + public static int UNKNOWN = 0; + public static int ANY = 1; + public static int ALL = 2; + public static int SOME = 3; + + @NotNull + public static Quantifier ANY() { + return new Quantifier(ANY); + } + + @NotNull + public static Quantifier ALL() { + return new Quantifier(ALL); + } + + @NotNull + public static Quantifier SOME() { + return new Quantifier(SOME); + } } } - -/** - * Logical operator for SQL subquery comparisons. - * - * - for subqueries. - * - . - */ -internal class RexSubqueryCompImpl( - args: List, - comp: Comp, - quantifier: Quantifier?, - rel: Rel, -) : RexSubqueryComp { - - private var _args = args - private var _comp = comp - private var _quantifier = quantifier - private var _rel = rel - - override fun getType(): RexType = TODO("Not yet implemented") - - override fun getArgs(): List = _args - - override fun getComp(): Comp = _comp - - override fun getQuantifier(): Quantifier? = _quantifier - - override fun getRel(): Rel = _rel - - - - // TODO hashcode/equals? -} diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryIn.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryIn.java index 7044392748..dd6b8a9474 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryIn.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryIn.java @@ -1,36 +1,44 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor -import org.partiql.plan.rel.Rel +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.plan.rel.Rel; +import org.partiql.types.PType; -public interface RexSubqueryIn : Rex { - - public fun getArgs(): List - - public fun getRel(): Rel - - @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitSubqueryIn(this, ctx) -} +import java.util.List; +import java.util.List; /** - * Logical operator for SQL subquery comparisons. - * - * - for subqueries. - * - . + * Logical subquery in expression abstract base class. */ -internal class RexSubqueryInImpl(args: List, rel: Rel) : RexSubqueryIn { +public abstract class RexSubqueryIn extends RexBase { - private var _args = args - private var _rel = rel + /** + * @return input rel (child 0) + */ + @NotNull + public abstract Rel getInput(); - override fun getType(): RexType = TODO("Not yet implemented") + /** + * @return collection comparison arguments (not children). + */ + @NotNull + public abstract List getArgs(); - override fun getArgs(): List = _args - - override fun getRel(): Rel = _rel + @Override + protected final RexType type() { + return new RexType(PType.bool()); + } - + @Override + protected List children() { + Rel c0 = getInput(); + return List.of(c0); + } - // TODO hashcode/equals? + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitSubqueryIn(this, ctx); + } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryTest.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryTest.java index fb398ac1cd..c408aa4f13 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryTest.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexSubqueryTest.java @@ -1,55 +1,60 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor -import org.partiql.plan.rex.RexSubqueryTest.Test +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.plan.rel.Rel; +import org.partiql.types.PType; + +import java.util.List; /** - * Logical expression for subquery tests EXISTS and UNIQUE. - * + * Logical subquery test expression abstract base class. + *
+ *

  *  -     "Specify a test for a non-empty set."
  *  -     "Specify a test for the absence of duplicate rows."
+ * 
*/ -public interface RexSubqueryTest : Rex { +public abstract class RexSubqueryTest extends RexBase { + + /** + * @return input rel (child 0) + */ + @NotNull + public abstract Rel getInput(); + + /** + * @return subquery test + */ + @NotNull + public abstract Test getTest(); - public fun getTest(): Test + @NotNull + @Override + protected final RexType type() { + return new RexType(PType.bool()); + } - public fun getRel(): org.partiql.plan.rel.Rel + @Override + protected List children() { + Rel c0 = getInput(); + return List.of(c0); + } @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitSubqueryTest(this, ctx) + public R accept(Visitor visitor, C ctx) { + return visitor.visitSubqueryTest(this, ctx); + } /** * EXISTS and UNIQUE are defined by SQL. - * + *

* TODO use 1.0 enum modeling. */ - public enum class Test { + public enum Test { EXISTS, UNIQUE, OTHER; } } - -/** - * Logical operator for SQL subquery comparisons. - * - * - for subqueries. - * - . - */ -internal class RexSubqueryTestImpl(test: Test, rel: org.partiql.plan.rel.Rel) : RexSubqueryTest { - - private var _test = test - private var _rel = rel - - override fun getType(): RexType { - TODO("Not yet implemented") - } - - override fun getTest(): Test = _test - - override fun getRel(): org.partiql.plan.rel.Rel = _rel - - - - // TODO hashcode/equals? -} diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexTable.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexTable.java index b360854812..d28d37d420 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexTable.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexTable.java @@ -1,44 +1,35 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor -import org.partiql.spi.catalog.Table +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; +import org.partiql.spi.catalog.Table; + +import java.util.List; /** * Global variable references e.g. tables and views. */ -public interface RexTable : Rex { - - public fun getTable(): Table +public abstract class RexTable extends RexBase { - + /** + * @return the table implementation. + */ + public abstract Table getTable(); + @NotNull @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitTable(this, ctx) -} - -/** - * Default [RexTable] implementation. - */ -internal class RexTableImpl(table: Table) : RexTable { - - // DO NOT USE FINAL - private var _table = table - private var _type = RexType(table.getSchema()) - - override fun getTable(): Table = _table - - override fun getType(): RexType = _type + protected final RexType type() { + return new RexType(getTable().getSchema()); + } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexTable) return false - if (_table != other.getTable()) return false - return true + @Override + protected final List children() { + return List.of(); } - override fun hashCode(): Int { - var result = 1 - result = 31 * result + _table.hashCode() - return result + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitTable(this, ctx); } -} +} \ No newline at end of file diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexType.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexType.java index b2f2dc9cf9..9c651b34cd 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexType.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexType.java @@ -1,32 +1,53 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.types.PType +import org.partiql.types.PType; /** * [RexType] is a simple wrapper over [PType], but does not necessarily only hold a PType. - * - * + *

+ *

* Developer Note: In later releases, a [RexType] may hold metadata to aid custom planner implementations. */ -public class RexType public constructor(type: PType) { +public class RexType { - // PRIVATE VAR - private var _type: PType = type + private final PType type; - public fun getPType(): PType = _type + public RexType(PType type) { + this.type = type; + } - override fun equals(other: Any?): Boolean = _type == other + public PType getPType() { + return type; + } - override fun hashCode(): Int = _type.hashCode() + @Override + public int hashCode() { + return type.hashCode(); + } - override fun toString(): String = _type.toString() + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof RexType)) { + return false; + } + return type.equals(((RexType) obj).type); + } - public companion object { + @Override + public String toString() { + return type.toString(); + } - /** - * A [RexType] for an "untyped" logical plan node. - */ - @JvmStatic - public fun dynamic(): RexType = RexType(PType.dynamic()) + /** + * A [RexType] for an "untyped" logical plan node. + */ + public static RexType dynamic() { + return new RexType(PType.dynamic()); } } diff --git a/partiql-plan/src/main/java/org/partiql/plan/rex/RexVar.java b/partiql-plan/src/main/java/org/partiql/plan/rex/RexVar.java index 8ddc4309b1..c1d4a77b21 100644 --- a/partiql-plan/src/main/java/org/partiql/plan/rex/RexVar.java +++ b/partiql-plan/src/main/java/org/partiql/plan/rex/RexVar.java @@ -1,57 +1,40 @@ -package org.partiql.plan.rex +package org.partiql.plan.rex; -import org.partiql.plan.Visitor +import org.jetbrains.annotations.NotNull; +import org.partiql.plan.Operator; +import org.partiql.plan.Visitor; + +import java.util.List; /** - * TODO DOCUMENTATION - * TODO NAMING?? + * Logical variable reference expression abstract base class. */ -public interface RexVar : Rex { +public abstract class RexVar extends RexBase { /** - * 0-indexed scope offset. + * @return 0-indexed scope offset. */ - public fun getDepth(): Int + public abstract int getDepth(); /** - * 0-index tuple offset. + * @return 0-index tuple offset. */ - public fun getOffset(): Int - - + public abstract int getOffset(); + @NotNull @Override - default public R accept(Visitor visitor, C ctx) { = visitor.visitVar(this, ctx) -} - -/** - * Default [RexVar] implementation intended for extension. - */ -internal class RexVarImpl(depth: Int, offset: Int, type: RexType) : RexVar { - - // DO NOT USE FINAL - private var _depth = depth - private var _offset = offset - private var _type = type - - override fun getDepth(): Int = _depth - - override fun getOffset(): Int = _offset - - override fun getType(): RexType = _type + protected final RexType type() { + // would need to lookup in context + throw new UnsupportedOperationException("Derive type is not implemented"); + } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is RexVar) return false - if (_depth != other.getDepth()) return false - if (_offset != other.getOffset()) return false - return true + @Override + protected final List children() { + return List.of(); } - override fun hashCode(): Int { - var result = 1 - result = 31 * result + _depth - result = 31 * result + _offset - return result + @Override + public R accept(Visitor visitor, C ctx) { + return visitor.visitVar(this, ctx); } } diff --git a/partiql-plan/src/main/kotlin/org/partiql/plan/builder/PlanFactory.kt b/partiql-plan/src/main/kotlin/org/partiql/plan/builder/PlanFactory.kt index b901d12d27..3fffc7faf6 100644 --- a/partiql-plan/src/main/kotlin/org/partiql/plan/builder/PlanFactory.kt +++ b/partiql-plan/src/main/kotlin/org/partiql/plan/builder/PlanFactory.kt @@ -45,7 +45,7 @@ import org.partiql.plan.rex.RexArrayImpl import org.partiql.plan.rex.RexBag import org.partiql.plan.rex.RexBagImpl import org.partiql.plan.rex.RexCall -import org.partiql.plan.rex.RexCallDynamic +import org.partiql.plan.rex.RexDispatch import org.partiql.plan.rex.RexCallDynamicImpl import org.partiql.plan.rex.RexCallImpl import org.partiql.plan.rex.RexCase @@ -389,14 +389,14 @@ public interface PlanFactory { public fun rexCall(function: Function.Instance, args: List): RexCall = RexCallImpl(function, args) /** - * Create a [RexCallDynamic] instance. + * Create a [RexDispatch] instance. * * @param name TODO * @param functions TODO * @param args TODO * @return TODO */ - public fun rexCallDynamic(name: String, functions: List, args: List): RexCallDynamic = + public fun rexCallDynamic(name: String, functions: List, args: List): RexDispatch = RexCallDynamicImpl(name, functions, args) /** @@ -632,31 +632,31 @@ public interface PlanFactory { * Create a [RexSubqueryComp] instance. * * @param args - * @param comp + * @param comparison * @param rel * @return */ public fun rexSubqueryComp( args: List, - comp: RexSubqueryComp.Comp, + comparison: RexSubqueryComp.Comparison, rel: Rel, - ): RexSubqueryComp = RexSubqueryCompImpl(args, comp, null, rel) + ): RexSubqueryComp = RexSubqueryCompImpl(args, comparison, null, rel) /** * Create a [RexSubqueryComp] instance. * * @param args - * @param comp + * @param comparison * @param quantifier * @param rel * @return */ public fun rexSubqueryComp( args: List, - comp: RexSubqueryComp.Comp, + comparison: RexSubqueryComp.Comparison, quantifier: RexSubqueryComp.Quantifier?, rel: Rel, - ): RexSubqueryComp = RexSubqueryCompImpl(args, comp, quantifier, rel) + ): RexSubqueryComp = RexSubqueryCompImpl(args, comparison, quantifier, rel) /** * Create a [RexSubqueryIn] instance for single argument. diff --git a/partiql-planner/src/test/kotlin/org/partiql/planner/PlanEquivalenceVisitor.kt b/partiql-planner/src/test/kotlin/org/partiql/planner/PlanEquivalenceVisitor.kt index a2013587e5..24419814c5 100644 --- a/partiql-planner/src/test/kotlin/org/partiql/planner/PlanEquivalenceVisitor.kt +++ b/partiql-planner/src/test/kotlin/org/partiql/planner/PlanEquivalenceVisitor.kt @@ -25,7 +25,7 @@ import org.partiql.plan.rel.RelUnpivot import org.partiql.plan.rex.RexArray import org.partiql.plan.rex.RexBag import org.partiql.plan.rex.RexCall -import org.partiql.plan.rex.RexCallDynamic +import org.partiql.plan.rex.RexDispatch import org.partiql.plan.rex.RexCase import org.partiql.plan.rex.RexCast import org.partiql.plan.rex.RexCoalesce @@ -155,7 +155,7 @@ object PlanEquivalenceVisitor : Visitor { return super.visitCall(rex, other) } - override fun visitCallDynamic(rex: RexCallDynamic, other: Any): Boolean { + override fun visitCallDynamic(rex: RexDispatch, other: Any): Boolean { return super.visitCallDynamic(rex, other) }