Skip to content

Commit

Permalink
Rex abstract base classes
Browse files Browse the repository at this point in the history
  • Loading branch information
RCHowell committed Nov 27, 2024
1 parent 7886f19 commit 7b0857b
Show file tree
Hide file tree
Showing 48 changed files with 1,082 additions and 1,164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -338,7 +338,7 @@ internal class StandardCompiler(strategies: List<Strategy>) : 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()
Expand Down Expand Up @@ -401,7 +401,7 @@ internal class StandardCompiler(strategies: List<Strategy>) : 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 {
Expand Down Expand Up @@ -460,7 +460,7 @@ internal class StandardCompiler(strategies: List<Strategy>) : 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)
Expand Down
32 changes: 32 additions & 0 deletions partiql-plan/README.md
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 2 additions & 2 deletions partiql-plan/src/main/java/org/partiql/plan/Visitor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -101,7 +101,7 @@ public interface Visitor<R, C> {

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)

Expand Down
32 changes: 11 additions & 21 deletions partiql-plan/src/main/java/org/partiql/plan/rel/RelAggregate.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.partiql.plan.rex.Rex;
import org.partiql.spi.function.Aggregation;

import java.util.Collection;
import java.util.List;

/**
Expand All @@ -16,42 +15,33 @@ 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<Operator> children = null;

/**
* @return the input (child 0)
*/
@NotNull
public abstract Rel getInput();

@NotNull
public abstract Collection<Measure> getMeasures();
public abstract List<Measure> getMeasures();

@NotNull
public abstract Collection<Rex> getGroups();
public abstract List<Rex> 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<Operator> getChildren() {
if (children == null) {
Rel c0 = getInput();
children = List.of(c0);
}
return children;
protected final List<Operator> children() {
Rel c0 = getInput();
return List.of(c0);
}

@Override
public <R, C> R accept(Visitor<R, C> visitor, C ctx) {
public <R, C> R accept(@NotNull Visitor<R, C> visitor, C ctx) {
return visitor.visitAggregate(this, ctx);
}

Expand All @@ -61,10 +51,10 @@ public <R, C> R accept(Visitor<R, C> visitor, C ctx) {
public static class Measure {

private final Aggregation agg;
private final Collection<Rex> args;
private final List<Rex> args;
private final Boolean distinct;

public Measure(Aggregation agg, Collection<Rex> args, Boolean distinct) {
public Measure(Aggregation agg, List<Rex> args, Boolean distinct) {
this.agg = agg;
this.args = args;
this.distinct = distinct;
Expand All @@ -76,7 +66,7 @@ public Aggregation getAgg() {
}

@NotNull
public Collection<Rex> getArgs() {
public List<Rex> getArgs() {
return args;
}

Expand Down
40 changes: 38 additions & 2 deletions partiql-plan/src/main/java/org/partiql/plan/rel/RelBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<Operator> children;

@Override
public int getTag() {
Expand All @@ -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<Operator> 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<Operator> children();
}
23 changes: 7 additions & 16 deletions partiql-plan/src/main/java/org/partiql/plan/rel/RelCorrelate.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
*/
public abstract class RelCorrelate extends RelBase {

private final RelType type = null;
private List<Operator> children = null;

/**
* @return the left input (child 0)
*/
Expand All @@ -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<Operator> getChildren() {
if (children == null) {
Rel c0 = getLeft();
Rel c1 = getRight();
children = List.of(c0, c1);
}
return children;
protected final List<Operator> children() {
Rel c0 = getLeft();
Rel c1 = getRight();
return List.of(c0, c1);
}

@Override
public <R, C> R accept(Visitor<R, C> visitor, C ctx) {
public <R, C> R accept(@NotNull Visitor<R, C> visitor, C ctx) {
return visitor.visitCorrelate(this, ctx);
}
}
21 changes: 6 additions & 15 deletions partiql-plan/src/main/java/org/partiql/plan/rel/RelDistinct.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
*/
public abstract class RelDistinct extends RelBase {

private final RelType type = null;
private List<Operator> children = null;

/**
* @return input rel (child 0)
*/
Expand All @@ -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<Operator> getChildren() {
if (children == null) {
Rel c0 = getInput();
children = List.of(c0);
}
return children;
protected final List<Operator> children() {
Rel c0 = getInput();
return List.of(c0);
}

@Override
public <R, C> R accept(Visitor<R, C> visitor, C ctx) {
public <R, C> R accept(@NotNull Visitor<R, C> visitor, C ctx) {
return visitor.visitDistinct(this, ctx);
}
}
23 changes: 7 additions & 16 deletions partiql-plan/src/main/java/org/partiql/plan/rel/RelExcept.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
*/
public abstract class RelExcept extends RelBase {

private final RelType type = null;
private List<Operator> children = null;

/**
* @return true if ALL else DISTINCT.
*/
Expand All @@ -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<Operator> getChildren() {
if (children == null) {
Rel c0 = getLeft();
Rel c1 = getRight();
children = List.of(c0, c1);
}
return children;
protected final List<Operator> children() {
Rel c0 = getLeft();
Rel c1 = getRight();
return List.of(c0, c1);
}

@Override
public <R, C> R accept(Visitor<R, C> visitor, C ctx) {
public <R, C> R accept(@NotNull Visitor<R, C> visitor, C ctx) {
return visitor.visitExcept(this, ctx);
}
}
Loading

0 comments on commit 7b0857b

Please sign in to comment.