Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v1] Migrate parser to new AST #1626

Merged
merged 3 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions partiql-ast/api/partiql-ast.api
Original file line number Diff line number Diff line change
Expand Up @@ -5593,7 +5593,7 @@ public final class org/partiql/ast/v1/Ast {
public static final fun exprWindowOver (Ljava/util/List;Ljava/util/List;)Lorg/partiql/ast/v1/expr/ExprWindow$Over;
public static final fun from (Ljava/util/List;)Lorg/partiql/ast/v1/From;
public static final fun fromExpr (Lorg/partiql/ast/v1/expr/Expr;Lorg/partiql/ast/v1/FromType;Lorg/partiql/ast/v1/Identifier;Lorg/partiql/ast/v1/Identifier;)Lorg/partiql/ast/v1/FromExpr;
public static final fun fromJoin (Lorg/partiql/ast/v1/From;Lorg/partiql/ast/v1/From;Lorg/partiql/ast/v1/JoinType;Lorg/partiql/ast/v1/expr/Expr;)Lorg/partiql/ast/v1/FromJoin;
public static final fun fromJoin (Lorg/partiql/ast/v1/FromTableRef;Lorg/partiql/ast/v1/FromTableRef;Lorg/partiql/ast/v1/JoinType;Lorg/partiql/ast/v1/expr/Expr;)Lorg/partiql/ast/v1/FromJoin;
public static final fun graphLabelConj (Lorg/partiql/ast/v1/graph/GraphLabel;Lorg/partiql/ast/v1/graph/GraphLabel;)Lorg/partiql/ast/v1/graph/GraphLabel$Conj;
public static final fun graphLabelDisj (Lorg/partiql/ast/v1/graph/GraphLabel;Lorg/partiql/ast/v1/graph/GraphLabel;)Lorg/partiql/ast/v1/graph/GraphLabel$Disj;
public static final fun graphLabelName (Ljava/lang/String;)Lorg/partiql/ast/v1/graph/GraphLabel$Name;
Expand Down Expand Up @@ -6062,9 +6062,9 @@ public class org/partiql/ast/v1/FromExpr$Builder {
public class org/partiql/ast/v1/FromJoin : org/partiql/ast/v1/FromTableRef {
public final field condition Lorg/partiql/ast/v1/expr/Expr;
public final field joinType Lorg/partiql/ast/v1/JoinType;
public final field lhs Lorg/partiql/ast/v1/From;
public final field rhs Lorg/partiql/ast/v1/From;
public fun <init> (Lorg/partiql/ast/v1/From;Lorg/partiql/ast/v1/From;Lorg/partiql/ast/v1/JoinType;Lorg/partiql/ast/v1/expr/Expr;)V
public final field lhs Lorg/partiql/ast/v1/FromTableRef;
public final field rhs Lorg/partiql/ast/v1/FromTableRef;
public fun <init> (Lorg/partiql/ast/v1/FromTableRef;Lorg/partiql/ast/v1/FromTableRef;Lorg/partiql/ast/v1/JoinType;Lorg/partiql/ast/v1/expr/Expr;)V
public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object;
public static fun builder ()Lorg/partiql/ast/v1/FromJoin$Builder;
protected fun canEqual (Ljava/lang/Object;)Z
Expand All @@ -6077,8 +6077,8 @@ public class org/partiql/ast/v1/FromJoin$Builder {
public fun build ()Lorg/partiql/ast/v1/FromJoin;
public fun condition (Lorg/partiql/ast/v1/expr/Expr;)Lorg/partiql/ast/v1/FromJoin$Builder;
public fun joinType (Lorg/partiql/ast/v1/JoinType;)Lorg/partiql/ast/v1/FromJoin$Builder;
public fun lhs (Lorg/partiql/ast/v1/From;)Lorg/partiql/ast/v1/FromJoin$Builder;
public fun rhs (Lorg/partiql/ast/v1/From;)Lorg/partiql/ast/v1/FromJoin$Builder;
public fun lhs (Lorg/partiql/ast/v1/FromTableRef;)Lorg/partiql/ast/v1/FromJoin$Builder;
public fun rhs (Lorg/partiql/ast/v1/FromTableRef;)Lorg/partiql/ast/v1/FromJoin$Builder;
public fun toString ()Ljava/lang/String;
}

Expand Down Expand Up @@ -6204,6 +6204,7 @@ public class org/partiql/ast/v1/JoinType : org/partiql/ast/v1/AstEnum {
public static final field FULL_OUTER I
public static final field INNER I
public static final field LEFT I
public static final field LEFT_CROSS I
public static final field LEFT_OUTER I
public static final field RIGHT I
public static final field RIGHT_OUTER I
Expand All @@ -6213,6 +6214,7 @@ public class org/partiql/ast/v1/JoinType : org/partiql/ast/v1/AstEnum {
public static fun FULL_OUTER ()Lorg/partiql/ast/v1/JoinType;
public static fun INNER ()Lorg/partiql/ast/v1/JoinType;
public static fun LEFT ()Lorg/partiql/ast/v1/JoinType;
public static fun LEFT_CROSS ()Lorg/partiql/ast/v1/JoinType;
public static fun LEFT_OUTER ()Lorg/partiql/ast/v1/JoinType;
public static fun RIGHT ()Lorg/partiql/ast/v1/JoinType;
public static fun RIGHT_OUTER ()Lorg/partiql/ast/v1/JoinType;
Expand Down
2 changes: 1 addition & 1 deletion partiql-ast/src/main/java/org/partiql/ast/v1/Ast.kt
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ public object Ast {
}

@JvmStatic
public fun fromJoin(lhs: From, rhs: From, joinType: JoinType?, condition: Expr?): FromJoin {
public fun fromJoin(lhs: FromTableRef, rhs: FromTableRef, joinType: JoinType?, condition: Expr?): FromJoin {
return FromJoin(lhs, rhs, joinType, condition)
}

Expand Down
6 changes: 3 additions & 3 deletions partiql-ast/src/main/java/org/partiql/ast/v1/FromJoin.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@
@EqualsAndHashCode(callSuper = false)
public class FromJoin extends FromTableRef {
@NotNull
public final From lhs;
public final FromTableRef lhs;

@NotNull
public final From rhs;
public final FromTableRef rhs;
Comment on lines +20 to +23
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was an error in the original PR adding the hand-written ASTs. The lhs and rhs should have been FromTableRefs.


@Nullable
public final JoinType joinType;

@Nullable
public final Expr condition;

public FromJoin(@NotNull From lhs, @NotNull From rhs, @Nullable JoinType joinType, @Nullable Expr condition) {
public FromJoin(@NotNull FromTableRef lhs, @NotNull FromTableRef rhs, @Nullable JoinType joinType, @Nullable Expr condition) {
this.lhs = lhs;
this.rhs = rhs;
this.joinType = joinType;
Expand Down
10 changes: 9 additions & 1 deletion partiql-ast/src/main/java/org/partiql/ast/v1/JoinType.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class JoinType extends AstEnum {
public static final int FULL = 6;
public static final int FULL_OUTER = 7;
public static final int CROSS = 8;
public static final int LEFT_CROSS = 9;

public static JoinType UNKNOWN() {
return new JoinType(UNKNOWN);
Expand Down Expand Up @@ -57,6 +58,10 @@ public static JoinType CROSS() {
return new JoinType(CROSS);
}

public static JoinType LEFT_CROSS() {
return new JoinType(LEFT_CROSS);
}

private final int code;

private JoinType(int code) {
Expand All @@ -80,6 +85,7 @@ public String name() {
case FULL: return "FULL";
case FULL_OUTER: return "FULL_OUTER";
case CROSS: return "CROSS";
case LEFT_CROSS: return "LEFT_CROSS";
default: return "UNKNOWN";
}
}
Expand All @@ -93,7 +99,8 @@ public String name() {
RIGHT_OUTER,
FULL,
FULL_OUTER,
CROSS
CROSS,
LEFT_CROSS
};

@NotNull
Expand All @@ -107,6 +114,7 @@ public static JoinType parse(@NotNull String value) {
case "FULL": return FULL();
case "FULL_OUTER": return FULL_OUTER();
case "CROSS": return CROSS();
case "LEFT_CROSS": return LEFT_CROSS();
default: return UNKNOWN();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import org.jetbrains.annotations.NotNull;
import org.partiql.eval.Mode;
import org.partiql.eval.internal.compiler.StandardCompiler;
import org.partiql.eval.Statement;
import org.partiql.eval.internal.compiler.StandardCompiler;
import org.partiql.plan.Plan;
import org.partiql.spi.Context;

Expand Down
41 changes: 41 additions & 0 deletions partiql-parser/api/partiql-parser.api
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,44 @@ public final class org/partiql/parser/SourceLocations : java/util/Map, kotlin/jv
public final fun values ()Ljava/util/Collection;
}

public abstract interface class org/partiql/parser/V1PartiQLParser {
public static final field Companion Lorg/partiql/parser/V1PartiQLParser$Companion;
public static fun builder ()Lorg/partiql/parser/V1PartiQLParserBuilder;
public abstract fun parse (Ljava/lang/String;)Lorg/partiql/parser/V1PartiQLParser$Result;
public abstract fun parse (Ljava/lang/String;Lorg/partiql/spi/Context;)Lorg/partiql/parser/V1PartiQLParser$Result;
public static fun standard ()Lorg/partiql/parser/V1PartiQLParser;
}

public final class org/partiql/parser/V1PartiQLParser$Companion {
public final fun builder ()Lorg/partiql/parser/V1PartiQLParserBuilder;
public final fun standard ()Lorg/partiql/parser/V1PartiQLParser;
}

public final class org/partiql/parser/V1PartiQLParser$DefaultImpls {
public static fun parse (Lorg/partiql/parser/V1PartiQLParser;Ljava/lang/String;)Lorg/partiql/parser/V1PartiQLParser$Result;
}

public final class org/partiql/parser/V1PartiQLParser$Result {
public static final field Companion Lorg/partiql/parser/V1PartiQLParser$Result$Companion;
public fun <init> (Ljava/lang/String;Lorg/partiql/ast/v1/Statement;Lorg/partiql/parser/SourceLocations;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Lorg/partiql/ast/v1/Statement;
public final fun component3 ()Lorg/partiql/parser/SourceLocations;
public final fun copy (Ljava/lang/String;Lorg/partiql/ast/v1/Statement;Lorg/partiql/parser/SourceLocations;)Lorg/partiql/parser/V1PartiQLParser$Result;
public static synthetic fun copy$default (Lorg/partiql/parser/V1PartiQLParser$Result;Ljava/lang/String;Lorg/partiql/ast/v1/Statement;Lorg/partiql/parser/SourceLocations;ILjava/lang/Object;)Lorg/partiql/parser/V1PartiQLParser$Result;
public fun equals (Ljava/lang/Object;)Z
public final fun getLocations ()Lorg/partiql/parser/SourceLocations;
public final fun getRoot ()Lorg/partiql/ast/v1/Statement;
public final fun getSource ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class org/partiql/parser/V1PartiQLParser$Result$Companion {
}

public final class org/partiql/parser/V1PartiQLParserBuilder {
public fun <init> ()V
public final fun build ()Lorg/partiql/parser/V1PartiQLParser;
}

27 changes: 13 additions & 14 deletions partiql-parser/src/main/antlr/PartiQLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ excludeExprSteps
;

fromClause
: FROM tableReference;
: FROM ( tableReference ( COMMA tableReference)* );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made some ANTLR grammar changes to account for the new modeling of FROM clauses to be better aligned with the SQL1999 BNF definition. See #1579 (comment) for some further context.


whereClauseSelect
: WHERE arg=exprSelect;
Expand Down Expand Up @@ -468,16 +468,16 @@ edgeAbbrev
*/

tableReference
: lhs=tableReference joinType? CROSS JOIN rhs=joinRhs # TableCrossJoin
| lhs=tableReference COMMA rhs=joinRhs # TableCrossJoin
| lhs=tableReference joinType? JOIN rhs=joinRhs joinSpec # TableQualifiedJoin
| tableNonJoin # TableRefBase
| PAREN_LEFT tableReference PAREN_RIGHT # TableWrapped
: tablePrimary # TableRefPrimary
| lhs=tableReference LEFT CROSS JOIN rhs=tablePrimary # TableLeftCrossJoin // PartiQL spec defines LEFT CROSS JOIN; other variants are not defined yet
| lhs=tableReference CROSS JOIN rhs=tablePrimary # TableCrossJoin // SQL99 defines just CROSS JOIN
| lhs=tableReference joinType? JOIN rhs=tableReference joinSpec # TableQualifiedJoin
;

tableNonJoin
tablePrimary
: tableBaseReference
| tableUnpivot
| tableWrapped
;

tableBaseReference
Expand All @@ -487,15 +487,11 @@ tableBaseReference
;

tableUnpivot
: UNPIVOT expr asIdent? atIdent? byIdent?;

joinRhs
: tableNonJoin # JoinRhsBase
| PAREN_LEFT tableReference PAREN_RIGHT # JoinRhsTableJoined
: UNPIVOT expr asIdent? atIdent? byIdent?
;

joinSpec
: ON expr;
tableWrapped
: PAREN_LEFT tableReference PAREN_RIGHT;

joinType
: mod=INNER
Expand All @@ -505,6 +501,9 @@ joinType
| mod=OUTER
;

joinSpec
: ON expr;

/**
*
* EXPRESSIONS & PRECEDENCE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* 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://aws.amazon.com/apache2.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.parser

import org.partiql.ast.v1.Query
import org.partiql.ast.v1.Statement
import org.partiql.ast.v1.expr.ExprLit
import org.partiql.parser.internal.V1PartiQLParserDefault
import org.partiql.spi.Context
import org.partiql.spi.errors.PErrorListenerException
import org.partiql.value.PartiQLValueExperimental
import org.partiql.value.nullValue

// TODO migrate public interfaces and classes to Java https://github.com/partiql/partiql-lang-kotlin/issues/1632
public interface V1PartiQLParser {
alancai98 marked this conversation as resolved.
Show resolved Hide resolved

/**
* Parses the [source] into an AST.
* @param source the user's input
* @param ctx a configuration object for the parser
* @throws PErrorListenerException when the [org.partiql.spi.errors.PErrorListener] defined in the [ctx] throws an
* [PErrorListenerException], this method halts execution and propagates the exception.
*/
@Throws(PErrorListenerException::class)
public fun parse(source: String, ctx: Context): Result

/**
* Parses the [source] into an AST.
* @param source the user's input
* @throws PErrorListenerException when the [org.partiql.spi.errors.PErrorListener] defined in the context throws an
* [PErrorListenerException], this method halts execution and propagates the exception.
*/
@Throws(PErrorListenerException::class)
public fun parse(source: String): Result {
return parse(source, Context.standard())
}

public data class Result(
val source: String,
val root: Statement,
val locations: SourceLocations,
) {
public companion object {
@OptIn(PartiQLValueExperimental::class)
internal fun empty(source: String): Result {
val locations = SourceLocations.Mutable().toMap()
return Result(source, Query(ExprLit(nullValue())), locations)
}
}
}

public companion object {

@JvmStatic
public fun builder(): V1PartiQLParserBuilder = V1PartiQLParserBuilder()

@JvmStatic
public fun standard(): V1PartiQLParser = V1PartiQLParserDefault()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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://aws.amazon.com/apache2.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.parser

import org.partiql.parser.internal.V1PartiQLParserDefault

/**
* A builder class to instantiate a [V1PartiQLParser]. https://github.com/partiql/partiql-lang-kotlin/issues/1632
*
* TODO replace with Lombok builder once [V1PartiQLParser] is migrated to Java.
*/
public class V1PartiQLParserBuilder {

public fun build(): V1PartiQLParser {
return V1PartiQLParserDefault()
}
}
alancai98 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -1221,7 +1221,12 @@ internal class PartiQLParserDefault : PartiQLParser {
*
*/

override fun visitFromClause(ctx: GeneratedParser.FromClauseContext) = visitAs<From>(ctx.tableReference())
override fun visitFromClause(ctx: GeneratedParser.FromClauseContext) = translate(ctx) {
val tableRefs = visitOrEmpty<From>(ctx.tableReference())
tableRefs.drop(1).fold(tableRefs.first()) { acc, tableRef ->
fromJoin(acc, tableRef, From.Join.Type.CROSS, null)
}
}

override fun visitTableBaseRefClauses(ctx: GeneratedParser.TableBaseRefClausesContext) = translate(ctx) {
val expr = visitAs<Expr>(ctx.source)
Expand Down Expand Up @@ -1261,11 +1266,19 @@ internal class PartiQLParserDefault : PartiQLParser {
fromValue(expr, From.Value.Type.UNPIVOT, asAlias, atAlias, byAlias)
}

override fun visitTableLeftCrossJoin(ctx: org.partiql.parser.internal.antlr.PartiQLParser.TableLeftCrossJoinContext) = translate(ctx) {
val lhs = visitAs<From>(ctx.lhs)
val rhs = visitAs<From>(ctx.rhs)
// PartiQL spec defines equivalence of
// l LEFT CROSS JOIN r <=> l LEFT JOIN r ON TRUE
// The other join types combined w/ CROSS JOIN are unspecified -- https://github.com/partiql/partiql-lang-kotlin/issues/1013
fromJoin(lhs, rhs, From.Join.Type.LEFT, null)
}

override fun visitTableCrossJoin(ctx: GeneratedParser.TableCrossJoinContext) = translate(ctx) {
val lhs = visitAs<From>(ctx.lhs)
val rhs = visitAs<From>(ctx.rhs)
val type = convertJoinType(ctx.joinType())
fromJoin(lhs, rhs, type, null)
fromJoin(lhs, rhs, From.Join.Type.CROSS, null)
}

private fun convertJoinType(ctx: GeneratedParser.JoinTypeContext?): From.Join.Type? {
Expand Down Expand Up @@ -1311,9 +1324,6 @@ internal class PartiQLParserDefault : PartiQLParser {

override fun visitJoinSpec(ctx: GeneratedParser.JoinSpecContext) = visitExpr(ctx.expr())

override fun visitJoinRhsTableJoined(ctx: GeneratedParser.JoinRhsTableJoinedContext) =
visitAs<From>(ctx.tableReference())

/**
* SIMPLE EXPRESSIONS
*/
Expand Down
Loading
Loading