Skip to content

Commit

Permalink
Adds typing support the V1 logical plans. (#1617)
Browse files Browse the repository at this point in the history
  • Loading branch information
RCHowell authored Oct 9, 2024
1 parent 2fc23c7 commit 9cfbc51
Show file tree
Hide file tree
Showing 109 changed files with 3,133 additions and 6,822 deletions.
10 changes: 5 additions & 5 deletions partiql-cli/src/main/kotlin/org/partiql/cli/pipeline/Pipeline.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import org.partiql.errors.ProblemSeverity
import org.partiql.eval.PartiQLEngine
import org.partiql.eval.PartiQLResult
import org.partiql.parser.PartiQLParser
import org.partiql.plan.v1.PartiQLPlan
import org.partiql.plan.Plan
import org.partiql.planner.PartiQLPlanner
import org.partiql.spi.catalog.Session

Expand All @@ -31,7 +31,7 @@ internal class Pipeline private constructor(
return result.root
}

private fun plan(statement: Statement, session: Session): PartiQLPlan {
private fun plan(statement: Statement, session: Session): Plan {
val callback = ProblemListener()
val result = planner.plan(statement, session, callback)
val errors = callback.problems.filter { it.details.severity == ProblemSeverity.ERROR }
Expand All @@ -41,7 +41,7 @@ internal class Pipeline private constructor(
TODO("Add V1 planner to the CLI")
}

private fun execute(plan: PartiQLPlan, session: Session): PartiQLResult {
private fun execute(plan: Plan, session: Session): PartiQLResult {
// val statement = engine.prepare(plan, session.mode, session.planner())
// return engine.execute(statement)
TODO("Add V1 planner to the CLI")
Expand All @@ -59,14 +59,14 @@ internal class Pipeline private constructor(
companion object {

fun default(): Pipeline {
val parser = PartiQLParser.default()
val parser = PartiQLParser.standard()
val planner = PartiQLPlanner.standard()
val engine = PartiQLEngine.standard()
return Pipeline(parser, planner, engine)
}

fun strict(): Pipeline {
val parser = PartiQLParser.default()
val parser = PartiQLParser.standard()
val planner = PartiQLPlanner.builder().signal().build()
val engine = PartiQLEngine.standard()
return Pipeline(parser, planner, engine)
Expand Down
2 changes: 1 addition & 1 deletion partiql-eval/api/partiql-eval.api
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
public abstract interface class org/partiql/eval/PartiQLEngine {
public static final field Companion Lorg/partiql/eval/PartiQLEngine$Companion;
public static fun builder ()Lorg/partiql/eval/builder/PartiQLEngineBuilder;
public abstract fun prepare (Lorg/partiql/plan/v1/PartiQLPlan;Lorg/partiql/eval/PartiQLEngine$Mode;Lorg/partiql/spi/catalog/Session;)Lorg/partiql/eval/PartiQLStatement;
public abstract fun prepare (Lorg/partiql/plan/Plan;Lorg/partiql/eval/PartiQLEngine$Mode;Lorg/partiql/spi/catalog/Session;)Lorg/partiql/eval/PartiQLStatement;
public static fun standard ()Lorg/partiql/eval/PartiQLEngine;
}

Expand Down
1 change: 0 additions & 1 deletion partiql-eval/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ dependencies {
testImplementation(project(":partiql-parser"))
testImplementation(project(":plugins:partiql-local"))
testImplementation(project(":plugins:partiql-memory"))
testImplementation(testFixtures(project(":partiql-planner")))
testImplementation(Deps.junit4)
testImplementation(Deps.junit4Params)
testImplementation(Deps.junitVintage) // Enables JUnit4
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.partiql.eval

import org.partiql.eval.builder.PartiQLEngineBuilder
import org.partiql.plan.v1.PartiQLPlan
import org.partiql.plan.Plan
import org.partiql.spi.catalog.Session

/**
Expand All @@ -13,7 +13,7 @@ import org.partiql.spi.catalog.Session
*
* This is in contrast to an actual application of PartiQL. Applications of PartiQL should instantiate a
* [org.partiql.planner.PartiQLPlanner] and should pass in a user's session. This engine has no idea what the session is.
* It assumes that the [org.partiql.plan.PartiQLPlan] has been resolved to accommodate session specifics.
* It assumes that the [org.partiql.plan.Plan] has been resolved to accommodate session specifics.
*
* This engine also internalizes the mechanics of the engine itself. Internally, it creates a physical plan to operate on,
* and it executes directly on that plan. The limited number of APIs exposed in this library is intentional to allow for
Expand All @@ -24,7 +24,7 @@ import org.partiql.spi.catalog.Session
*/
public interface PartiQLEngine {

public fun prepare(plan: PartiQLPlan, mode: Mode, session: Session): PartiQLStatement
public fun prepare(plan: Plan, mode: Mode, session: Session): PartiQLStatement

companion object {

Expand Down
161 changes: 57 additions & 104 deletions partiql-eval/src/main/kotlin/org/partiql/eval/internal/SqlCompiler.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package org.partiql.eval.internal

// OLD IMPORTS FOR EXCLUDE
import org.partiql.eval.PartiQLEngine
import org.partiql.eval.internal.operator.Operator
import org.partiql.eval.internal.operator.rel.RelOpAggregate
import org.partiql.eval.internal.operator.rel.RelOpDistinct
import org.partiql.eval.internal.operator.rel.RelOpExceptAll
import org.partiql.eval.internal.operator.rel.RelOpExceptDistinct
import org.partiql.eval.internal.operator.rel.RelOpExcludeOld
import org.partiql.eval.internal.operator.rel.RelOpExclude
import org.partiql.eval.internal.operator.rel.RelOpFilter
import org.partiql.eval.internal.operator.rel.RelOpIntersectAll
import org.partiql.eval.internal.operator.rel.RelOpIntersectDistinct
Expand Down Expand Up @@ -52,72 +51,56 @@ import org.partiql.eval.internal.operator.rex.ExprSubquery
import org.partiql.eval.internal.operator.rex.ExprSubqueryRow
import org.partiql.eval.internal.operator.rex.ExprTable
import org.partiql.eval.internal.operator.rex.ExprVar
import org.partiql.plan.relOpExcludePath
import org.partiql.plan.relOpExcludeStep
import org.partiql.plan.relOpExcludeTypeCollIndex
import org.partiql.plan.relOpExcludeTypeCollWildcard
import org.partiql.plan.relOpExcludeTypeStructKey
import org.partiql.plan.relOpExcludeTypeStructSymbol
import org.partiql.plan.relOpExcludeTypeStructWildcard
import org.partiql.plan.rexOpVar
import org.partiql.plan.v1.operator.rel.Rel
import org.partiql.plan.v1.operator.rel.RelAggregate
import org.partiql.plan.v1.operator.rel.RelCollation
import org.partiql.plan.v1.operator.rel.RelDistinct
import org.partiql.plan.v1.operator.rel.RelError
import org.partiql.plan.v1.operator.rel.RelExcept
import org.partiql.plan.v1.operator.rel.RelExclude
import org.partiql.plan.v1.operator.rel.RelExcludeCollectionWildcard
import org.partiql.plan.v1.operator.rel.RelExcludeIndex
import org.partiql.plan.v1.operator.rel.RelExcludeKey
import org.partiql.plan.v1.operator.rel.RelExcludePath
import org.partiql.plan.v1.operator.rel.RelExcludeStep
import org.partiql.plan.v1.operator.rel.RelExcludeStructWildcard
import org.partiql.plan.v1.operator.rel.RelExcludeSymbol
import org.partiql.plan.v1.operator.rel.RelFilter
import org.partiql.plan.v1.operator.rel.RelIntersect
import org.partiql.plan.v1.operator.rel.RelIterate
import org.partiql.plan.v1.operator.rel.RelJoin
import org.partiql.plan.v1.operator.rel.RelJoinType
import org.partiql.plan.v1.operator.rel.RelLimit
import org.partiql.plan.v1.operator.rel.RelOffset
import org.partiql.plan.v1.operator.rel.RelProject
import org.partiql.plan.v1.operator.rel.RelScan
import org.partiql.plan.v1.operator.rel.RelSort
import org.partiql.plan.v1.operator.rel.RelUnion
import org.partiql.plan.v1.operator.rel.RelUnpivot
import org.partiql.plan.v1.operator.rel.RelVisitor
import org.partiql.plan.v1.operator.rex.Rex
import org.partiql.plan.v1.operator.rex.RexArray
import org.partiql.plan.v1.operator.rex.RexBag
import org.partiql.plan.v1.operator.rex.RexCall
import org.partiql.plan.v1.operator.rex.RexCallDynamic
import org.partiql.plan.v1.operator.rex.RexCase
import org.partiql.plan.v1.operator.rex.RexCast
import org.partiql.plan.v1.operator.rex.RexCoalesce
import org.partiql.plan.v1.operator.rex.RexError
import org.partiql.plan.v1.operator.rex.RexLit
import org.partiql.plan.v1.operator.rex.RexMissing
import org.partiql.plan.v1.operator.rex.RexNullIf
import org.partiql.plan.v1.operator.rex.RexPathIndex
import org.partiql.plan.v1.operator.rex.RexPathKey
import org.partiql.plan.v1.operator.rex.RexPathSymbol
import org.partiql.plan.v1.operator.rex.RexPivot
import org.partiql.plan.v1.operator.rex.RexSelect
import org.partiql.plan.v1.operator.rex.RexSpread
import org.partiql.plan.v1.operator.rex.RexStruct
import org.partiql.plan.v1.operator.rex.RexSubquery
import org.partiql.plan.v1.operator.rex.RexSubqueryComp
import org.partiql.plan.v1.operator.rex.RexSubqueryIn
import org.partiql.plan.v1.operator.rex.RexSubqueryTest
import org.partiql.plan.v1.operator.rex.RexTable
import org.partiql.plan.v1.operator.rex.RexVar
import org.partiql.plan.v1.operator.rex.RexVisitor
import org.partiql.plan.Collation
import org.partiql.plan.JoinType
import org.partiql.plan.rel.Rel
import org.partiql.plan.rel.RelAggregate
import org.partiql.plan.rel.RelDistinct
import org.partiql.plan.rel.RelError
import org.partiql.plan.rel.RelExcept
import org.partiql.plan.rel.RelExclude
import org.partiql.plan.rel.RelFilter
import org.partiql.plan.rel.RelIntersect
import org.partiql.plan.rel.RelIterate
import org.partiql.plan.rel.RelJoin
import org.partiql.plan.rel.RelLimit
import org.partiql.plan.rel.RelOffset
import org.partiql.plan.rel.RelProject
import org.partiql.plan.rel.RelScan
import org.partiql.plan.rel.RelSort
import org.partiql.plan.rel.RelUnion
import org.partiql.plan.rel.RelUnpivot
import org.partiql.plan.rel.RelVisitor
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.RexCase
import org.partiql.plan.rex.RexCast
import org.partiql.plan.rex.RexCoalesce
import org.partiql.plan.rex.RexError
import org.partiql.plan.rex.RexLit
import org.partiql.plan.rex.RexMissing
import org.partiql.plan.rex.RexNullIf
import org.partiql.plan.rex.RexPathIndex
import org.partiql.plan.rex.RexPathKey
import org.partiql.plan.rex.RexPathSymbol
import org.partiql.plan.rex.RexPivot
import org.partiql.plan.rex.RexSelect
import org.partiql.plan.rex.RexSpread
import org.partiql.plan.rex.RexStruct
import org.partiql.plan.rex.RexSubquery
import org.partiql.plan.rex.RexSubqueryComp
import org.partiql.plan.rex.RexSubqueryIn
import org.partiql.plan.rex.RexSubqueryTest
import org.partiql.plan.rex.RexTable
import org.partiql.plan.rex.RexVar
import org.partiql.plan.rex.RexVisitor
import org.partiql.spi.catalog.Session
import org.partiql.spi.function.Aggregation
import org.partiql.spi.value.Datum
import org.partiql.types.PType
import org.partiql.plan.Rel as IRel

/**
* This class is responsible for producing a tree of evaluable operators from a tree of logical operators.
Expand Down Expand Up @@ -190,38 +173,8 @@ internal class SqlCompiler(

override fun visitExclude(rel: RelExclude, ctx: Unit): Operator.Relation {
val input = compile(rel.getInput(), ctx)

// !! TEMPORARY BLOCK !!
//
// TODO REPLACE ME WITH NEW IMPLEMENTATION IN LATER PR
//
fun translate(step: RelExcludeStep): IRel.Op.Exclude.Step {
val type = when (step) {
is RelExcludeKey -> relOpExcludeTypeStructKey(step.getKey())
is RelExcludeIndex -> relOpExcludeTypeCollIndex(step.getIndex())
is RelExcludeSymbol -> relOpExcludeTypeStructSymbol(step.getSymbol())
is RelExcludeCollectionWildcard -> relOpExcludeTypeCollWildcard()
is RelExcludeStructWildcard -> relOpExcludeTypeStructWildcard()
else -> error("Unsupported exclude step: $step")
}
val substeps = step.getSubsteps().map { translate(it) }
return relOpExcludeStep(type, substeps)
}

fun translate(path: RelExcludePath): IRel.Op.Exclude.Path {
val root = path.getRoot()
val steps = path.getSteps().map { translate(it) }
return relOpExcludePath(
root = rexOpVar(root.getDepth(), root.getOffset()),
steps = steps
)
}

val paths = rel.getPaths().map { translate(it) }
//
// !! TEMPORARY BLOCK !!

return RelOpExcludeOld(input, paths)
val paths = rel.getExclusions()
return RelOpExclude(input, paths)
}

override fun visitFilter(rel: RelFilter, ctx: Unit): Operator.Relation {
Expand Down Expand Up @@ -257,10 +210,10 @@ internal class SqlCompiler(
val rhsType = rel.getRightSchema()

return when (rel.getJoinType()) {
RelJoinType.INNER -> RelOpJoinInner(lhs, rhs, condition)
RelJoinType.LEFT -> RelOpJoinOuterLeft(lhs, rhs, condition, rhsType!!)
RelJoinType.RIGHT -> RelOpJoinOuterRight(lhs, rhs, condition, lhsType!!)
RelJoinType.FULL -> RelOpJoinOuterFull(lhs, rhs, condition, lhsType!!, rhsType!!)
JoinType.INNER -> RelOpJoinInner(lhs, rhs, condition)
JoinType.LEFT -> RelOpJoinOuterLeft(lhs, rhs, condition, rhsType!!)
JoinType.RIGHT -> RelOpJoinOuterRight(lhs, rhs, condition, lhsType!!)
JoinType.FULL -> RelOpJoinOuterFull(lhs, rhs, condition, lhsType!!, rhsType!!)
}
}

Expand Down Expand Up @@ -294,8 +247,8 @@ internal class SqlCompiler(
val input = compile(rel.getInput(), ctx)
val collations = rel.getCollations().map {
val expr = compile(it.getRex(), ctx)
val desc = it.getOrder() == RelCollation.Order.DESC
val last = it.getNulls() == RelCollation.Nulls.LAST
val desc = it.getOrder() == Collation.Order.DESC
val last = it.getNulls() == Collation.Nulls.LAST
RelOpSort.Collation(expr, desc, last)
}
return RelOpSort(input, collations)
Expand Down Expand Up @@ -418,8 +371,8 @@ internal class SqlCompiler(
}

override fun visitNullIf(rex: RexNullIf, ctx: Unit): Operator.Expr {
val value = compile(rex.getValue(), ctx)
val nullifier = compile(rex.getNullifier(), ctx)
val value = compile(rex.getV1(), ctx)
val nullifier = compile(rex.getV2(), ctx)
return ExprNullIf(value, nullifier)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ package org.partiql.eval.internal
import org.partiql.eval.PartiQLEngine
import org.partiql.eval.PartiQLStatement
import org.partiql.eval.internal.statement.QueryStatement
import org.partiql.plan.v1.PartiQLPlan
import org.partiql.plan.v1.Statement
import org.partiql.plan.Operation.Query
import org.partiql.plan.Plan
import org.partiql.spi.catalog.Session

internal class SqlEngine : PartiQLEngine {

override fun prepare(plan: PartiQLPlan, mode: PartiQLEngine.Mode, session: Session): PartiQLStatement {
override fun prepare(plan: Plan, mode: PartiQLEngine.Mode, session: Session): PartiQLStatement {
try {
val statement = plan.getStatement()
if (statement !is Statement.Query) {
val operation = plan.getOperation()
if (operation !is Query) {
throw IllegalArgumentException("Only query statements are supported")
}
val compiler = SqlCompiler(mode, session)
val root = compiler.compile(statement.getRoot())
val root = compiler.compile(operation.getRex())
return QueryStatement(root)
} catch (ex: Exception) {
// TODO wrap in some PartiQL Exception
Expand Down
Loading

0 comments on commit 9cfbc51

Please sign in to comment.