Skip to content

Commit

Permalink
[v1] Add v1 ast -> plan conversion; hook up w/ existing code (#1631)
Browse files Browse the repository at this point in the history
  • Loading branch information
alancai98 authored and RCHowell committed Nov 1, 2024
1 parent 4016203 commit 2815ba1
Show file tree
Hide file tree
Showing 20 changed files with 1,977 additions and 39 deletions.
1 change: 1 addition & 0 deletions partiql-ast/src/main/java/org/partiql/ast/v1/DataType.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@EqualsAndHashCode(callSuper = false)
public class DataType extends AstEnum {
public static final int UNKNOWN = 0;
// TODO remove `NULL` and `MISSING` variants from DataType
// <absent types>
public static final int NULL = 1;
public static final int MISSING = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

/**
* TODO docs, equals, hashcode
* TODO also support IS NULL, IS MISSING, IS UNKNOWN, IS TRUE, IS FALSE
*/
@Builder(builderClassName = "Builder")
@EqualsAndHashCode(callSuper = false)
Expand Down
11 changes: 5 additions & 6 deletions partiql-cli/src/main/kotlin/org/partiql/cli/pipeline/Pipeline.kt
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package org.partiql.cli.pipeline

import org.partiql.ast.Statement
import org.partiql.ast.v1.Statement
import org.partiql.cli.ErrorCodeString
import org.partiql.eval.Mode
import org.partiql.eval.compiler.PartiQLCompiler
import org.partiql.parser.PartiQLParser
import org.partiql.parser.PartiQLParserBuilder
import org.partiql.parser.V1PartiQLParser
import org.partiql.parser.V1PartiQLParserBuilder
import org.partiql.plan.Plan
import org.partiql.planner.PartiQLPlanner
import org.partiql.spi.Context
import org.partiql.spi.catalog.Session
import org.partiql.spi.errors.PErrorListenerException
import org.partiql.spi.value.Datum
import java.io.PrintStream
import kotlin.jvm.Throws

internal class Pipeline private constructor(
private val parser: PartiQLParser,
private val parser: V1PartiQLParser,
private val planner: PartiQLPlanner,
private val compiler: PartiQLCompiler,
private val ctx: Context,
Expand Down Expand Up @@ -81,7 +80,7 @@ internal class Pipeline private constructor(
private fun create(mode: Mode, out: PrintStream, config: Config): Pipeline {
val listener = config.getErrorListener(out)
val ctx = Context.of(listener)
val parser = PartiQLParserBuilder().build()
val parser = V1PartiQLParserBuilder().build()
val planner = PartiQLPlanner.builder().build()
val compiler = PartiQLCompiler.builder().build()
return Pipeline(parser, planner, compiler, ctx, mode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource
import org.partiql.eval.Mode
import org.partiql.eval.compiler.PartiQLCompiler
import org.partiql.parser.PartiQLParser
import org.partiql.parser.V1PartiQLParser
import org.partiql.plan.Plan
import org.partiql.planner.PartiQLPlanner
import org.partiql.plugins.memory.MemoryCatalog
Expand Down Expand Up @@ -1307,7 +1307,7 @@ class PartiQLEvaluatorTest {
) {

private val compiler = PartiQLCompiler.standard()
private val parser = PartiQLParser.standard()
private val parser = V1PartiQLParser.standard()
private val planner = PartiQLPlanner.standard()

/**
Expand Down Expand Up @@ -1373,7 +1373,7 @@ class PartiQLEvaluatorTest {
) {

private val compiler = PartiQLCompiler.standard()
private val parser = PartiQLParser.standard()
private val parser = V1PartiQLParser.standard()
private val planner = PartiQLPlanner.standard()

internal fun assert() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1509,6 +1509,21 @@ internal class V1PartiQLParserDefault : V1PartiQLParser {
exprPathStepAllFields(null)
}

override fun visitValues(ctx: GeneratedParser.ValuesContext) = translate(ctx) {
val rows = visitOrEmpty<ExprArray>(ctx.valueRow())
exprBag(rows)
}

override fun visitValueRow(ctx: GeneratedParser.ValueRowContext) = translate(ctx) {
val expressions = visitOrEmpty<Expr>(ctx.expr())
exprArray(expressions)
}

override fun visitValueList(ctx: GeneratedParser.ValueListContext) = translate(ctx) {
val expressions = visitOrEmpty<Expr>(ctx.expr())
exprArray(expressions)
}

override fun visitExprGraphMatchMany(ctx: GeneratedParser.ExprGraphMatchManyContext) = translate(ctx) {
val graph = visit(ctx.exprPrimary()) as Expr
val pattern = visitGpmlPatternList(ctx.gpmlPatternList())
Expand Down Expand Up @@ -1617,10 +1632,11 @@ internal class V1PartiQLParserDefault : V1PartiQLParser {
val lhs = visitExpr(ctx.expr(0))
val rhs = visitExpr(ctx.expr(1))
// TODO change to not use PartiQLValue -- https://github.com/partiql/partiql-lang-kotlin/issues/1589
val fieldLit = exprLit(stringValue(ctx.dt.text.uppercase()))
val fieldLit = ctx.dt.text.lowercase()
// TODO error on invalid datetime fields like TIMEZONE_HOUR and TIMEZONE_MINUTE
when {
ctx.DATE_ADD() != null -> exprCall(identifierChain(identifier("DATE_ADD", false), null), listOf(fieldLit, lhs, rhs), null)
ctx.DATE_DIFF() != null -> exprCall(identifierChain(identifier("DATE_DIFF", false), null), listOf(fieldLit, lhs, rhs), null)
ctx.DATE_ADD() != null -> exprCall(identifierChain(identifier("date_add_$fieldLit", false), null), listOf(lhs, rhs), null)
ctx.DATE_DIFF() != null -> exprCall(identifierChain(identifier("date_diff_$fieldLit", false), null), listOf(lhs, rhs), null)
else -> throw error(ctx, "Expected DATE_ADD or DATE_DIFF")
}
}
Expand Down
6 changes: 3 additions & 3 deletions partiql-planner/api/partiql-planner.api
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
public abstract interface class org/partiql/planner/PartiQLPlanner {
public static final field Companion Lorg/partiql/planner/PartiQLPlanner$Companion;
public static fun builder ()Lorg/partiql/planner/builder/PartiQLPlannerBuilder;
public abstract fun plan (Lorg/partiql/ast/Statement;Lorg/partiql/spi/catalog/Session;)Lorg/partiql/planner/PartiQLPlanner$Result;
public abstract fun plan (Lorg/partiql/ast/Statement;Lorg/partiql/spi/catalog/Session;Lorg/partiql/spi/Context;)Lorg/partiql/planner/PartiQLPlanner$Result;
public abstract fun plan (Lorg/partiql/ast/v1/Statement;Lorg/partiql/spi/catalog/Session;)Lorg/partiql/planner/PartiQLPlanner$Result;
public abstract fun plan (Lorg/partiql/ast/v1/Statement;Lorg/partiql/spi/catalog/Session;Lorg/partiql/spi/Context;)Lorg/partiql/planner/PartiQLPlanner$Result;
public static fun standard ()Lorg/partiql/planner/PartiQLPlanner;
}

Expand All @@ -12,7 +12,7 @@ public final class org/partiql/planner/PartiQLPlanner$Companion {
}

public final class org/partiql/planner/PartiQLPlanner$DefaultImpls {
public static fun plan (Lorg/partiql/planner/PartiQLPlanner;Lorg/partiql/ast/Statement;Lorg/partiql/spi/catalog/Session;)Lorg/partiql/planner/PartiQLPlanner$Result;
public static fun plan (Lorg/partiql/planner/PartiQLPlanner;Lorg/partiql/ast/v1/Statement;Lorg/partiql/spi/catalog/Session;)Lorg/partiql/planner/PartiQLPlanner$Result;
}

public final class org/partiql/planner/PartiQLPlanner$Result {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.partiql.planner

import org.partiql.ast.Statement
import org.partiql.ast.v1.Statement
import org.partiql.plan.Plan
import org.partiql.planner.builder.PartiQLPlannerBuilder
import org.partiql.spi.Context
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package org.partiql.planner.internal

import org.partiql.ast.Statement
import org.partiql.ast.normalize.normalize
import org.partiql.ast.v1.Statement
import org.partiql.plan.Operation
import org.partiql.plan.Plan
import org.partiql.plan.builder.PlanFactory
import org.partiql.plan.rex.Rex
import org.partiql.planner.PartiQLPlanner
import org.partiql.planner.PartiQLPlannerPass
import org.partiql.planner.internal.transforms.AstToPlan
import org.partiql.planner.internal.normalize.normalize
import org.partiql.planner.internal.transforms.PlanTransform
import org.partiql.planner.internal.transforms.V1AstToPlan
import org.partiql.planner.internal.typer.PlanTyper
import org.partiql.spi.Context
import org.partiql.spi.catalog.Session
Expand Down Expand Up @@ -39,7 +39,7 @@ internal class SqlPlanner(
val ast = statement.normalize()

// 2. AST to Rel/Rex
val root = AstToPlan.apply(ast, env)
val root = V1AstToPlan.apply(ast, env)

// 3. Resolve variables
val typer = PlanTyper(env, ctx)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*
*/

package org.partiql.planner.internal.transforms

import org.partiql.ast.v1.AstNode
import org.partiql.ast.v1.AstVisitor
import org.partiql.ast.v1.Query
import org.partiql.ast.v1.expr.ExprQuerySet
import org.partiql.planner.internal.Env
import org.partiql.planner.internal.ir.statementQuery
import org.partiql.spi.catalog.Identifier
import org.partiql.ast.v1.Identifier as AstIdentifier
import org.partiql.ast.v1.IdentifierChain as AstIdentifierChain
import org.partiql.ast.v1.Statement as AstStatement
import org.partiql.planner.internal.ir.Statement as PlanStatement

/**
* Simple translation from AST to an unresolved algebraic IR.
*/
internal object V1AstToPlan {

// statement.toPlan()
@JvmStatic
fun apply(statement: AstStatement, env: Env): PlanStatement = statement.accept(ToPlanStatement, env)

@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
private object ToPlanStatement : AstVisitor<PlanStatement, Env>() {

override fun defaultReturn(node: AstNode, env: Env) = throw IllegalArgumentException("Unsupported statement")

override fun visitQuery(node: Query, env: Env): PlanStatement {
val rex = when (val expr = node.expr) {
is ExprQuerySet -> V1RelConverter.apply(expr, env)
else -> V1RexConverter.apply(expr, env)
}
return statementQuery(rex)
}
}

// --- Helpers --------------------

fun convert(identifier: AstIdentifierChain): Identifier {
val parts = mutableListOf<Identifier.Part>()
parts.add(part(identifier.root))
var curStep = identifier.next
while (curStep != null) {
parts.add(part(curStep.root))
curStep = curStep.next
}
return Identifier.of(parts)
}

fun convert(identifier: AstIdentifier): Identifier {
return Identifier.of(part(identifier))
}

fun part(identifier: AstIdentifier): Identifier.Part = when (identifier.isDelimited) {
true -> Identifier.Part.delimited(identifier.symbol)
false -> Identifier.Part.regular(identifier.symbol)
}
}
Loading

0 comments on commit 2815ba1

Please sign in to comment.