Skip to content

Commit

Permalink
[v1] Migrate parser to new AST (#1626)
Browse files Browse the repository at this point in the history
  • Loading branch information
alancai98 authored Oct 28, 2024
1 parent 246b63c commit f0569bd
Show file tree
Hide file tree
Showing 16 changed files with 3,053 additions and 584 deletions.
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;

@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)* );

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 {

/**
* 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()
}
}
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

0 comments on commit f0569bd

Please sign in to comment.