From 141364ec6f042c51de1529c19e51490d4b751b7a Mon Sep 17 00:00:00 2001 From: Alan Cai Date: Mon, 6 May 2024 16:43:38 -0700 Subject: [PATCH 1/3] Add to non-reserved keywords; rework functionName and symbolPrimitive parse rules --- .../lang/syntax/impl/PartiQLPigVisitor.kt | 129 +++++++++--------- .../partiql/lang/errors/ParserErrorsTest.kt | 8 ++ partiql-parser/src/main/antlr/PartiQL.g4 | 60 ++++++-- .../parser/internal/PartiQLParserDefault.kt | 127 ++++++++--------- 4 files changed, 180 insertions(+), 144 deletions(-) diff --git a/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt b/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt index 9a21e6d890..60fa7099b9 100644 --- a/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt +++ b/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt @@ -48,6 +48,7 @@ import org.partiql.lang.ast.IsValuesExprMeta import org.partiql.lang.ast.LegacyLogicalNotMeta import org.partiql.lang.ast.SourceLocationMeta import org.partiql.lang.domains.PartiqlAst +import org.partiql.lang.domains.PartiqlAst.PartiqlAstNode import org.partiql.lang.domains.metaContainerOf import org.partiql.lang.eval.EvaluationException import org.partiql.lang.eval.time.MAX_PRECISION_FOR_TIME @@ -192,25 +193,28 @@ internal class PartiQLPigVisitor( * */ - override fun visitAsIdent(ctx: PartiQLParser.AsIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) + override fun visitAsIdent(ctx: PartiQLParser.AsIdentContext) = visitAs (ctx.symbolPrimitive()) - override fun visitAtIdent(ctx: PartiQLParser.AtIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) + override fun visitAtIdent(ctx: PartiQLParser.AtIdentContext) = visitAs (ctx.symbolPrimitive()) - override fun visitByIdent(ctx: PartiQLParser.ByIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) + override fun visitByIdent(ctx: PartiQLParser.ByIdentContext) = visitAs (ctx.symbolPrimitive()) - override fun visitSymbolPrimitive(ctx: PartiQLParser.SymbolPrimitiveContext) = PartiqlAst.build { - val metas = ctx.ident.getSourceMetaContainer() - when (ctx.ident.type) { - PartiQLParser.IDENTIFIER_QUOTED -> id( - ctx.IDENTIFIER_QUOTED().getStringValue(), - caseSensitive(), - unqualified(), - metas - ) + override fun visitQuotedIdentifier(ctx: PartiQLParser.QuotedIdentifierContext): PartiqlAst.Expr.Id = PartiqlAst.build { + id( + ctx.IDENTIFIER_QUOTED().getStringValue(), + caseSensitive(), + unqualified(), + ctx.IDENTIFIER_QUOTED().getSourceMetaContainer() + ) + } - PartiQLParser.IDENTIFIER -> id(ctx.IDENTIFIER().getStringValue(), caseInsensitive(), unqualified(), metas) - else -> throw ParserException("Invalid symbol reference.", ErrorCode.PARSE_INVALID_QUERY) - } + override fun visitUnquotedIdentifier(ctx: PartiQLParser.UnquotedIdentifierContext): PartiqlAst.Expr.Id = PartiqlAst.build { + id( + ctx.text, + caseInsensitive(), + unqualified(), + ctx.IDENTIFIER().getSourceMetaContainer() + ) } /** @@ -226,7 +230,7 @@ internal class PartiQLPigVisitor( override fun visitDropTable(ctx: PartiQLParser.DropTableContext) = PartiqlAst.build { val id = if (ctx.qualifiedName().qualifier.isEmpty()) { - visitSymbolPrimitive(ctx.qualifiedName().name) + visitAs (ctx.qualifiedName().name) } else { throw ParserException("PIG Parser does not support qualified name as table name", ErrorCode.PARSE_UNEXPECTED_TOKEN) } @@ -234,14 +238,14 @@ internal class PartiQLPigVisitor( } override fun visitDropIndex(ctx: PartiQLParser.DropIndexContext) = PartiqlAst.build { - val id = visitSymbolPrimitive(ctx.target) - val key = visitSymbolPrimitive(ctx.on) + val id = visitAs (ctx.target) + val key = visitAs (ctx.on) dropIndex(key.toIdentifier(), id.toIdentifier(), ctx.DROP().getSourceMetaContainer()) } override fun visitCreateTable(ctx: PartiQLParser.CreateTableContext) = PartiqlAst.build { val name = if (ctx.qualifiedName().qualifier.isEmpty()) { - visitSymbolPrimitive(ctx.qualifiedName().name).name + visitAs (ctx.qualifiedName().name).name } else { throw ParserException("PIG Parser does not support qualified name as table name", ErrorCode.PARSE_UNEXPECTED_TOKEN) } @@ -251,7 +255,7 @@ internal class PartiQLPigVisitor( } override fun visitCreateIndex(ctx: PartiQLParser.CreateIndexContext) = PartiqlAst.build { - val id = visitSymbolPrimitive(ctx.symbolPrimitive()) + val id = visitAs (ctx.symbolPrimitive()) val fields = ctx.pathSimple().map { path -> visitPathSimple(path) } createIndex(id.toIdentifier(), fields, ctx.CREATE().getSourceMetaContainer()) } @@ -262,7 +266,7 @@ internal class PartiQLPigVisitor( } override fun visitColumnDeclaration(ctx: PartiQLParser.ColumnDeclarationContext) = PartiqlAst.build { - val name = visitSymbolPrimitive(ctx.columnName().symbolPrimitive()).name.text + val name = visitAs (ctx.columnName().symbolPrimitive()).name.text val type = visit(ctx.type()) as PartiqlAst.Type val constrs = ctx.columnConstraint().map { visitColumnConstraint(it) } if (ctx.OPTIONAL() != null) { @@ -275,7 +279,7 @@ internal class PartiQLPigVisitor( } override fun visitColumnConstraint(ctx: PartiQLParser.ColumnConstraintContext) = PartiqlAst.build { - val name = ctx.constraintName()?.let { visitSymbolPrimitive(it.symbolPrimitive()).name.text } + val name = ctx.constraintName()?.let { visitAs (it.symbolPrimitive()).name.text } val def = visit(ctx.columnConstraintDef()) as PartiqlAst.ColumnConstraintDef columnConstraint(name, def) } @@ -372,7 +376,7 @@ internal class PartiQLPigVisitor( override fun visitInsertStatement(ctx: PartiQLParser.InsertStatementContext) = PartiqlAst.build { insert( - target = visitSymbolPrimitive(ctx.symbolPrimitive()), + target = visitAs (ctx.symbolPrimitive()), asAlias = ctx.asIdent()?.let { visitAsIdent(it).name.text }, values = visitExpr(ctx.value), conflictAction = ctx.onConflict()?.let { visitOnConflict(it) }, @@ -382,7 +386,7 @@ internal class PartiQLPigVisitor( override fun visitReplaceCommand(ctx: PartiQLParser.ReplaceCommandContext) = PartiqlAst.build { insert( - target = visitSymbolPrimitive(ctx.symbolPrimitive()), + target = visitAs (ctx.symbolPrimitive()), asAlias = ctx.asIdent()?.let { visitAsIdent(it).name.text }, values = visitExpr(ctx.value), conflictAction = doReplace(excluded()), @@ -393,7 +397,7 @@ internal class PartiQLPigVisitor( // Based on https://github.com/partiql/partiql-docs/blob/main/RFCs/0011-partiql-insert.md override fun visitUpsertCommand(ctx: PartiQLParser.UpsertCommandContext) = PartiqlAst.build { insert( - target = visitSymbolPrimitive(ctx.symbolPrimitive()), + target = visitAs (ctx.symbolPrimitive()), asAlias = ctx.asIdent()?.let { visitAsIdent(it).name.text }, values = visitExpr(ctx.value), conflictAction = doUpdate(excluded()), @@ -487,7 +491,7 @@ internal class PartiQLPigVisitor( } override fun visitPathSimple(ctx: PartiQLParser.PathSimpleContext) = PartiqlAst.build { - val root = visitSymbolPrimitive(ctx.symbolPrimitive()) + val root = visitAs (ctx.symbolPrimitive()) if (ctx.pathSimpleSteps().isEmpty()) return@build root val steps = ctx.pathSimpleSteps().map { visit(it) as PartiqlAst.PathStep } path(root, steps, root.metas) @@ -498,7 +502,7 @@ internal class PartiQLPigVisitor( } override fun visitPathSimpleSymbol(ctx: PartiQLParser.PathSimpleSymbolContext) = PartiqlAst.build { - pathExpr(visitSymbolPrimitive(ctx.symbolPrimitive()), caseSensitive()) + pathExpr(visitAs (ctx.symbolPrimitive()), caseSensitive()) } override fun visitPathSimpleDotSymbol(ctx: PartiQLParser.PathSimpleDotSymbolContext) = @@ -594,7 +598,7 @@ internal class PartiQLPigVisitor( override fun visitProjectionItem(ctx: PartiQLParser.ProjectionItemContext) = PartiqlAst.build { val expr = visitExpr(ctx.expr()) - val alias = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).name } + val alias = ctx.symbolPrimitive()?.let { visitAs (it).name } if (expr is PartiqlAst.Expr.Path) convertPathToProjectionItem(expr, alias) else projectExpr_(expr, asAlias = alias, expr.metas) } @@ -653,16 +657,16 @@ internal class PartiQLPigVisitor( } override fun visitExcludeExpr(ctx: PartiQLParser.ExcludeExprContext) = PartiqlAst.build { - val root = visitSymbolPrimitive(ctx.symbolPrimitive()).toIdentifier() + val root = visitAs (ctx.symbolPrimitive()).toIdentifier() val steps = ctx.excludeExprSteps().map { visit(it) as PartiqlAst.ExcludeStep } excludeExpr(root, steps) } override fun visitExcludeExprTupleAttr(ctx: PartiQLParser.ExcludeExprTupleAttrContext) = PartiqlAst.build { val attr = ctx.symbolPrimitive().getString() - val caseSensitivity = when (ctx.symbolPrimitive().ident.type) { - PartiQLParser.IDENTIFIER_QUOTED -> caseSensitive() - PartiQLParser.IDENTIFIER -> caseInsensitive() + val caseSensitivity = when (ctx.symbolPrimitive()) { + is PartiQLParser.QuotedIdentifierContext -> caseSensitive() + is PartiQLParser.UnquotedIdentifierContext -> caseInsensitive() else -> throw ParserException("Invalid symbol reference.", ErrorCode.PARSE_INVALID_QUERY) } excludeTupleAttr(identifier(attr, caseSensitivity)) @@ -732,7 +736,7 @@ internal class PartiQLPigVisitor( groupBy_(strategy, keyList = keyList, groupAsAlias = alias, ctx.GROUP().getSourceMetaContainer()) } - override fun visitGroupAlias(ctx: PartiQLParser.GroupAliasContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) + override fun visitGroupAlias(ctx: PartiQLParser.GroupAliasContext) = visitAs (ctx.symbolPrimitive()) /** * Returns a GROUP BY key @@ -755,7 +759,7 @@ internal class PartiQLPigVisitor( ErrorCode.PARSE_UNSUPPORTED_LITERALS_GROUPBY ) } - val alias = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).toPigSymbolPrimitive() } + val alias = ctx.symbolPrimitive()?.let { visitAs (it).toPigSymbolPrimitive() } groupKey_(expr, asAlias = alias, expr.metas) } @@ -824,7 +828,7 @@ internal class PartiQLPigVisitor( } override fun visitPatternPathVariable(ctx: PartiQLParser.PatternPathVariableContext) = - visitSymbolPrimitive(ctx.symbolPrimitive()) + visitAs (ctx.symbolPrimitive()) override fun visitSelectorBasic(ctx: PartiQLParser.SelectorBasicContext) = PartiqlAst.build { val metas = ctx.mod.getSourceMetaContainer() @@ -872,7 +876,7 @@ internal class PartiQLPigVisitor( } override fun visitLabelPrimaryName(ctx: PartiQLParser.LabelPrimaryNameContext) = PartiqlAst.build { - val x = visitSymbolPrimitive(ctx.symbolPrimitive()) + val x = visitAs (ctx.symbolPrimitive()) graphLabelName_(x.name, x.metas) } @@ -914,7 +918,7 @@ internal class PartiQLPigVisitor( override fun visitEdgeSpec(ctx: PartiQLParser.EdgeSpecContext) = PartiqlAst.build { val placeholderDirection = edgeRight() - val variable = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).name } + val variable = ctx.symbolPrimitive()?.let { visitAs (it).name } val prefilter = ctx.whereClause()?.let { visitWhereClause(it) } val label = ctx.labelSpec()?.let { visit(it) as PartiqlAst.GraphLabelSpec } edge_(direction = placeholderDirection, variable = variable, prefilter = prefilter, label = label) @@ -979,7 +983,7 @@ internal class PartiQLPigVisitor( } override fun visitNode(ctx: PartiQLParser.NodeContext) = PartiqlAst.build { - val variable = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).name } + val variable = ctx.symbolPrimitive()?.let { visitAs (it).name } val prefilter = ctx.whereClause()?.let { visitWhereClause(it) } val label = ctx.labelSpec()?.let { visit(it) as PartiqlAst.GraphLabelSpec } node_(variable = variable, prefilter = prefilter, label = label) @@ -1067,13 +1071,13 @@ internal class PartiQLPigVisitor( override fun visitTableBaseRefSymbol(ctx: PartiQLParser.TableBaseRefSymbolContext) = PartiqlAst.build { val expr = visit(ctx.source) as PartiqlAst.Expr - val name = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).toPigSymbolPrimitive() } + val name = ctx.symbolPrimitive()?.let { visitAs (it).toPigSymbolPrimitive() } scan_(expr, name, metas = expr.metas) } override fun visitFromClauseSimpleImplicit(ctx: PartiQLParser.FromClauseSimpleImplicitContext) = PartiqlAst.build { val path = visitPathSimple(ctx.pathSimple()) - val name = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).name } + val name = ctx.symbolPrimitive()?.let { visitAs (it).name } scan_(path, name, metas = path.metas) } @@ -1192,7 +1196,7 @@ internal class PartiQLPigVisitor( override fun visitVariableKeyword(ctx: PartiQLParser.VariableKeywordContext): PartiqlAst.PartiqlAstNode = PartiqlAst.build { - val keyword = ctx.nonReservedKeywords().start.text + val keyword = ctx.nonReserved().start.text val metas = ctx.start.getSourceMetaContainer() val qualifier = ctx.qualifier?.let { localsFirst() } ?: unqualified() id(keyword, caseInsensitive(), qualifier, metas) @@ -1316,16 +1320,11 @@ internal class PartiQLPigVisitor( } override fun visitFunctionCall(ctx: PartiQLParser.FunctionCallContext) = PartiqlAst.build { - val name = when (val nameCtx = ctx.functionName()) { - is PartiQLParser.FunctionNameReservedContext -> { - if (nameCtx.qualifier.isNotEmpty()) error("Legacy AST does not support qualified function names") - nameCtx.name.text.lowercase() - } - is PartiQLParser.FunctionNameSymbolContext -> { - if (nameCtx.qualifier.isNotEmpty()) error("Legacy AST does not support qualified function names") - nameCtx.name.getString().lowercase() - } - else -> error("Expected context FunctionNameReserved or FunctionNameSymbol") + val nameCtx = ctx.functionName() + val name = if (nameCtx.qualifier.isNotEmpty()) { + error("Legacy AST does not support qualified function names") + } else { + nameCtx.name.getString().lowercase() } val args = ctx.expr().map { visitExpr(it) } val metas = ctx.start.getSourceMetaContainer() @@ -1819,9 +1818,9 @@ internal class PartiQLPigVisitor( } } - private fun PartiQLParser.SymbolPrimitiveContext.getSourceMetaContainer() = when (this.ident.type) { - PartiQLParser.IDENTIFIER -> this.IDENTIFIER().getSourceMetaContainer() - PartiQLParser.IDENTIFIER_QUOTED -> this.IDENTIFIER_QUOTED().getSourceMetaContainer() + private fun PartiQLParser.SymbolPrimitiveContext.getSourceMetaContainer() = when (this) { + is PartiQLParser.QuotedIdentifierContext -> this.IDENTIFIER_QUOTED().getSourceMetaContainer() + is PartiQLParser.UnquotedIdentifierContext -> this.start.getSourceMetaContainer() else -> throw ParserException( "Unable to get identifier's source meta-container.", ErrorCode.PARSE_INVALID_QUERY @@ -2125,29 +2124,29 @@ internal class PartiQLPigVisitor( } private fun PartiQLParser.SymbolPrimitiveContext.getString(): String { - return when { - this.IDENTIFIER_QUOTED() != null -> this.IDENTIFIER_QUOTED().getStringValue() - this.IDENTIFIER() != null -> this.IDENTIFIER().text + return when (this) { + is PartiQLParser.QuotedIdentifierContext -> this.IDENTIFIER_QUOTED().getStringValue() + is PartiQLParser.UnquotedIdentifierContext -> this.text else -> throw ParserException("Unable to get symbol's text.", ErrorCode.PARSE_INVALID_QUERY) } } private fun getSymbolPathExpr(ctx: PartiQLParser.SymbolPrimitiveContext) = PartiqlAst.build { - when { - ctx.IDENTIFIER_QUOTED() != null -> pathExpr( + when (ctx) { + is PartiQLParser.QuotedIdentifierContext -> pathExpr( lit(ionString(ctx.IDENTIFIER_QUOTED().getStringValue())), caseSensitive(), - metas = ctx.IDENTIFIER_QUOTED().getSourceMetaContainer() + metas = ctx.getSourceMetaContainer() ) - - ctx.IDENTIFIER() != null -> pathExpr( - lit(ionString(ctx.IDENTIFIER().text)), caseInsensitive(), - metas = ctx.IDENTIFIER().getSourceMetaContainer() + is PartiQLParser.UnquotedIdentifierContext -> pathExpr( + lit(ionString(ctx.text)), caseInsensitive(), + metas = ctx.getSourceMetaContainer() ) - else -> throw ParserException("Unable to get symbol's text.", ErrorCode.PARSE_INVALID_QUERY) } } + private inline fun visitAs(ctx: ParserRuleContext): T = visit(ctx) as T + private fun String.toInteger() = BigInteger(this, 10) private fun Token.toSymbol(): PartiqlAst.Expr.Lit { diff --git a/partiql-lang/src/test/kotlin/org/partiql/lang/errors/ParserErrorsTest.kt b/partiql-lang/src/test/kotlin/org/partiql/lang/errors/ParserErrorsTest.kt index be09bae355..5736186dd2 100644 --- a/partiql-lang/src/test/kotlin/org/partiql/lang/errors/ParserErrorsTest.kt +++ b/partiql-lang/src/test/kotlin/org/partiql/lang/errors/ParserErrorsTest.kt @@ -15,6 +15,7 @@ package org.partiql.lang.errors import com.amazon.ion.Timestamp +import org.junit.Ignore import org.junit.Test import org.partiql.errors.ErrorCode import org.partiql.errors.Property @@ -655,6 +656,7 @@ class ParserErrorsTest : PartiQLParserTestBase() { } @Test + @Ignore("No longer a parser error; evaluation error") fun callTrimNoArgs() { checkInputThrowingParserException( "trim()", @@ -683,6 +685,7 @@ class ParserErrorsTest : PartiQLParserTestBase() { } @Test + @Ignore("No longer a parser error; evaluation error") fun callTrimZeroArguments() { checkInputThrowingParserException( "trim()", @@ -795,6 +798,7 @@ class ParserErrorsTest : PartiQLParserTestBase() { } @Test + @Ignore("No longer a parser error; evaluation error") fun aggregateWithNoArgs() { checkInputThrowingParserException( "SUM()", @@ -809,6 +813,7 @@ class ParserErrorsTest : PartiQLParserTestBase() { } @Test + @Ignore("No longer a parser error; evaluation error") fun aggregateWithTooManyArgs() { checkInputThrowingParserException( "SUM(a, b)", @@ -1672,6 +1677,7 @@ class ParserErrorsTest : PartiQLParserTestBase() { } @Test + @Ignore("No longer a parser error; evaluation error") fun callExtractMissingFromWithComma() { checkInputThrowingParserException( "extract(year, b)", @@ -1717,6 +1723,7 @@ class ParserErrorsTest : PartiQLParserTestBase() { } @Test + @Ignore("No longer a parser error; evaluation error") fun callExtractOnlySecondArgument() { checkInputThrowingParserException( "extract(b)", @@ -1746,6 +1753,7 @@ class ParserErrorsTest : PartiQLParserTestBase() { } @Test + @Ignore("No longer a parser error; evaluation error") fun callExtractOnlyDateTimePart() { checkInputThrowingParserException( "extract(year)", diff --git a/partiql-parser/src/main/antlr/PartiQL.g4 b/partiql-parser/src/main/antlr/PartiQL.g4 index e08b512716..81f0213e9d 100644 --- a/partiql-parser/src/main/antlr/PartiQL.g4 +++ b/partiql-parser/src/main/antlr/PartiQL.g4 @@ -40,7 +40,9 @@ byIdent : BY symbolPrimitive; symbolPrimitive - : ident=( IDENTIFIER | IDENTIFIER_QUOTED ) + : IDENTIFIER # UnquotedIdentifier + | IDENTIFIER_QUOTED # QuotedIdentifier + | nonReserved # UnquotedIdentifier ; /** @@ -653,8 +655,8 @@ exprPrimary | dateFunction # ExprPrimaryBase | aggregate # ExprPrimaryBase | trimFunction # ExprPrimaryBase - | functionCall # ExprPrimaryBase | nullIf # ExprPrimaryBase + | functionCall # ExprPrimaryBase | exprPrimary pathStep+ # ExprPrimaryPath | exprGraphMatchMany # ExprPrimaryBase | caseExpr # ExprPrimaryBase @@ -766,8 +768,7 @@ functionCall // SQL-99 10.4 — ::= [ ] functionName - : (qualifier+=symbolPrimitive PERIOD)* name=( CHAR_LENGTH | CHARACTER_LENGTH | OCTET_LENGTH | BIT_LENGTH | UPPER | LOWER | SIZE | EXISTS | COUNT | MOD ) # FunctionNameReserved - | (qualifier+=symbolPrimitive PERIOD)* name=symbolPrimitive # FunctionNameSymbol + : (qualifier+=symbolPrimitive PERIOD)* name=symbolPrimitive ; pathStep @@ -789,11 +790,52 @@ parameter varRefExpr : qualifier=AT_SIGN? ident=(IDENTIFIER|IDENTIFIER_QUOTED) # VariableIdentifier - | qualifier=AT_SIGN? key=nonReservedKeywords # VariableKeyword - ; - -nonReservedKeywords - : EXCLUDED + | qualifier=AT_SIGN? key=nonReserved # VariableKeyword + ; + +nonReserved + : /* From SQL99 https://ronsavage.github.io/SQL/sql-99.bnf.html#non-reserved%20word */ + ABS | ADA | ADMIN | ASENSITIVE | ASSIGNMENT | ASYMMETRIC | ATOMIC + | ATTRIBUTE | AVG + | BIT_LENGTH + | C | CALLED | CARDINALITY | CATALOG_NAME | CHAIN | CHAR_LENGTH + | CHARACTERISTICS | CHARACTER_LENGTH | CHARACTER_SET_CATALOG + | CHARACTER_SET_NAME | CHARACTER_SET_SCHEMA | CHECKED | CLASS_ORIGIN + | COALESCE | COBOL | COLLATION_CATALOG | COLLATION_NAME | COLLATION_SCHEMA + | COLUMN_NAME | COMMAND_FUNCTION | COMMAND_FUNCTION_CODE | COMMITTED + | CONDITION_IDENTIFIER | CONDITION_NUMBER | CONNECTION_NAME + | CONSTRAINT_CATALOG | CONSTRAINT_NAME | CONSTRAINT_SCHEMA | CONTAINS + | CONVERT | COUNT | CURSOR_NAME + | DATETIME_INTERVAL_CODE | DATETIME_INTERVAL_PRECISION | DEFINED + | DEFINER | DEGREE | DERIVED | DISPATCH + | EVERY | EXTRACT + | FINAL | FORTRAN + | G | GENERATED | GRANTED + | HIERARCHY + | IMPLEMENTATION | INSENSITIVE | INSTANCE | INSTANTIABLE | INVOKER + | K | KEY_MEMBER | KEY_TYPE + | LENGTH | LOWER + | M | MAX | MIN | MESSAGE_LENGTH | MESSAGE_OCTET_LENGTH | MESSAGE_TEXT + | MOD | MORE | MUMPS + | NAME | NULLABLE | NUMBER | NULLIF + | OCTET_LENGTH | ORDERING | OPTIONS | OVERLAY | OVERRIDING + | PASCAL | PARAMETER_MODE | PARAMETER_NAME + | PARAMETER_ORDINAL_POSITION | PARAMETER_SPECIFIC_CATALOG + | PARAMETER_SPECIFIC_NAME | PARAMETER_SPECIFIC_SCHEMA | PLI | POSITION + | REPEATABLE | RETURNED_CARDINALITY | RETURNED_LENGTH + | RETURNED_OCTET_LENGTH | RETURNED_SQLSTATE | ROUTINE_CATALOG + | ROUTINE_NAME | ROUTINE_SCHEMA | ROW_COUNT + | SCALE | SCHEMA_NAME | SCOPE | SECURITY | SELF | SENSITIVE | SERIALIZABLE + | SERVER_NAME | SIMPLE | SOURCE | SPECIFIC_NAME | STATEMENT | STRUCTURE + | STYLE | SUBCLASS_ORIGIN | SUBSTRING | SUM | SYMMETRIC | SYSTEM + | TABLE_NAME | TOP_LEVEL_COUNT | TRANSACTIONS_COMMITTED + | TRANSACTIONS_ROLLED_BACK | TRANSACTION_ACTIVE | TRANSFORM + | TRANSFORMS | TRANSLATE | TRIGGER_CATALOG | TRIGGER_SCHEMA + | TRIGGER_NAME | TRIM | TYPE + | UNCOMMITTED | UNNAMED | UPPER + /* PartiQL */ + | EXCLUDED | EXISTS + | SIZE ; /** diff --git a/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt b/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt index 0f633cf8ae..6c8261aaee 100644 --- a/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt +++ b/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt @@ -557,29 +557,29 @@ internal class PartiQLParserDefault : PartiQLParser { * */ - override fun visitAsIdent(ctx: GeneratedParser.AsIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) + override fun visitAsIdent(ctx: GeneratedParser.AsIdentContext) = visitAs (ctx.symbolPrimitive()) - override fun visitAtIdent(ctx: GeneratedParser.AtIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) + override fun visitAtIdent(ctx: GeneratedParser.AtIdentContext) = visitAs (ctx.symbolPrimitive()) - override fun visitByIdent(ctx: GeneratedParser.ByIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) + override fun visitByIdent(ctx: GeneratedParser.ByIdentContext) = visitAs (ctx.symbolPrimitive()) - override fun visitSymbolPrimitive(ctx: GeneratedParser.SymbolPrimitiveContext) = translate(ctx) { - when (ctx.ident.type) { - GeneratedParser.IDENTIFIER_QUOTED -> identifierSymbol( - ctx.IDENTIFIER_QUOTED().getStringValue(), - Identifier.CaseSensitivity.SENSITIVE, - ) - GeneratedParser.IDENTIFIER -> identifierSymbol( - ctx.IDENTIFIER().getStringValue(), - Identifier.CaseSensitivity.INSENSITIVE, - ) - else -> throw error(ctx, "Invalid symbol reference.") - } + override fun visitQuotedIdentifier(ctx: org.partiql.parser.internal.antlr.PartiQLParser.QuotedIdentifierContext): Identifier.Symbol = translate(ctx) { + identifierSymbol( + ctx.IDENTIFIER_QUOTED().getStringValue(), + Identifier.CaseSensitivity.SENSITIVE + ) + } + + override fun visitUnquotedIdentifier(ctx: org.partiql.parser.internal.antlr.PartiQLParser.UnquotedIdentifierContext): Identifier.Symbol = translate(ctx) { + identifierSymbol( + ctx.text, + Identifier.CaseSensitivity.INSENSITIVE + ) } override fun visitQualifiedName(ctx: GeneratedParser.QualifiedNameContext) = translate(ctx) { - val qualifier = ctx.qualifier.map { visitSymbolPrimitive(it) } - val name = visitSymbolPrimitive(ctx.name) + val qualifier = ctx.qualifier.map { visitAs (it) } + val name = visitAs (ctx.name) if (qualifier.isEmpty()) { name } else { @@ -605,8 +605,8 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitDropIndex(ctx: GeneratedParser.DropIndexContext) = translate(ctx) { - val table = visitSymbolPrimitive(ctx.on) - val index = visitSymbolPrimitive(ctx.target) + val table = visitAs (ctx.on) + val index = visitAs (ctx.target) ddlOpDropIndex(index, table) } @@ -638,7 +638,7 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitCreateIndex(ctx: GeneratedParser.CreateIndexContext) = translate(ctx) { // TODO add index name to ANTLR grammar val name: Identifier? = null - val table = visitSymbolPrimitive(ctx.symbolPrimitive()) + val table = visitAs (ctx.symbolPrimitive()) val fields = ctx.pathSimple().map { path -> visitPathSimple(path) } ddlOpCreateIndex(name, table, fields) } @@ -867,7 +867,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitInsertStatement(ctx: GeneratedParser.InsertStatementContext) = translate(ctx) { - val target = visitSymbolPrimitive(ctx.symbolPrimitive()) + val target = visitAs (ctx.symbolPrimitive()) val values = visitExpr(ctx.value) val asAlias = visitOrNull(ctx.asIdent()) val onConflict = ctx.onConflict()?.let { visitOnConflictClause(it) } @@ -875,14 +875,14 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitReplaceCommand(ctx: GeneratedParser.ReplaceCommandContext) = translate(ctx) { - val target = visitSymbolPrimitive(ctx.symbolPrimitive()) + val target = visitAs (ctx.symbolPrimitive()) val values = visitExpr(ctx.value) val asAlias = visitOrNull(ctx.asIdent()) statementDMLReplace(target, values, asAlias) } override fun visitUpsertCommand(ctx: GeneratedParser.UpsertCommandContext) = translate(ctx) { - val target = visitSymbolPrimitive(ctx.symbolPrimitive()) + val target = visitAs (ctx.symbolPrimitive()) val values = visitExpr(ctx.value) val asAlias = visitOrNull(ctx.asIdent()) statementDMLUpsert(target, values, asAlias) @@ -928,9 +928,9 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitConflictTarget(ctx: GeneratedParser.ConflictTargetContext) = translate(ctx) { if (ctx.constraintName() != null) { - onConflictTargetConstraint(visitSymbolPrimitive(ctx.constraintName().symbolPrimitive())) + onConflictTargetConstraint(visitAs (ctx.constraintName().symbolPrimitive())) } else { - val symbols = ctx.symbolPrimitive().map { visitSymbolPrimitive(it) } + val symbols = ctx.symbolPrimitive().map { visitAs (it) } onConflictTargetSymbols(symbols) } } @@ -953,7 +953,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitPathSimple(ctx: GeneratedParser.PathSimpleContext) = translate(ctx) { - val root = visitSymbolPrimitive(ctx.symbolPrimitive()) + val root = visitAs (ctx.symbolPrimitive()) val steps = visitOrEmpty(ctx.pathSimpleSteps()) path(root, steps) } @@ -975,12 +975,12 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitPathSimpleSymbol(ctx: GeneratedParser.PathSimpleSymbolContext) = translate(ctx) { - val identifier = visitSymbolPrimitive(ctx.symbolPrimitive()) + val identifier = visitAs (ctx.symbolPrimitive()) pathStepSymbol(identifier) } override fun visitPathSimpleDotSymbol(ctx: GeneratedParser.PathSimpleDotSymbolContext) = translate(ctx) { - val identifier = visitSymbolPrimitive(ctx.symbolPrimitive()) + val identifier = visitAs (ctx.symbolPrimitive()) pathStepSymbol(identifier) } @@ -1063,7 +1063,7 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitProjectionItem(ctx: GeneratedParser.ProjectionItemContext) = translate(ctx) { val expr = visitExpr(ctx.expr()) - val alias = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it) } + val alias = ctx.symbolPrimitive()?.let { visitAs (it) } if (expr is Expr.Path) { convertPathToProjectionItem(ctx, expr, alias) } else { @@ -1107,7 +1107,7 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitLetBinding(ctx: GeneratedParser.LetBindingContext) = translate(ctx) { val expr = visitAs(ctx.expr()) - val alias = visitSymbolPrimitive(ctx.symbolPrimitive()) + val alias = visitAs (ctx.symbolPrimitive()) letBinding(expr, alias) } @@ -1148,13 +1148,13 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitGroupClause(ctx: GeneratedParser.GroupClauseContext) = translate(ctx) { val strategy = if (ctx.PARTIAL() != null) GroupBy.Strategy.PARTIAL else GroupBy.Strategy.FULL val keys = visitOrEmpty(ctx.groupKey()) - val alias = ctx.groupAlias()?.symbolPrimitive()?.let { visitSymbolPrimitive(it) } + val alias = ctx.groupAlias()?.symbolPrimitive()?.let { visitAs (it) } groupBy(strategy, keys, alias) } override fun visitGroupKey(ctx: GeneratedParser.GroupKeyContext) = translate(ctx) { val expr = visitAs(ctx.key) - val alias = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it) } + val alias = ctx.symbolPrimitive()?.let { visitAs (it) } groupByKey(expr, alias) } @@ -1169,14 +1169,14 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitExcludeExpr(ctx: GeneratedParser.ExcludeExprContext) = translate(ctx) { - val rootId = visitSymbolPrimitive(ctx.symbolPrimitive()) + val rootId = visitAs (ctx.symbolPrimitive()) val root = exprVar(rootId, Expr.Var.Scope.DEFAULT) val steps = visitOrEmpty(ctx.excludeExprSteps()) excludeItem(root, steps) } override fun visitExcludeExprTupleAttr(ctx: GeneratedParser.ExcludeExprTupleAttrContext) = translate(ctx) { - val identifier = visitSymbolPrimitive(ctx.symbolPrimitive()) + val identifier = visitAs (ctx.symbolPrimitive()) excludeStepStructField(identifier) } @@ -1284,7 +1284,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitPatternPathVariable(ctx: GeneratedParser.PatternPathVariableContext) = - visitSymbolPrimitive(ctx.symbolPrimitive()) + visitAs (ctx.symbolPrimitive()) override fun visitSelectorBasic(ctx: GeneratedParser.SelectorBasicContext) = translate(ctx) { when (ctx.mod.type) { @@ -1327,7 +1327,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitLabelPrimaryName(ctx: GeneratedParser.LabelPrimaryNameContext) = translate(ctx) { - val x = visitSymbolPrimitive(ctx.symbolPrimitive()) + val x = visitAs (ctx.symbolPrimitive()) graphMatchLabelName(x.symbol) } @@ -1457,17 +1457,17 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitTableBaseRefClauses(ctx: GeneratedParser.TableBaseRefClausesContext) = translate(ctx) { val expr = visitAs(ctx.source) - val asAlias = ctx.asIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } - val atAlias = ctx.atIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } - val byAlias = ctx.byIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } + val asAlias = ctx.asIdent()?.let { visitAs (it.symbolPrimitive()) } + val atAlias = ctx.atIdent()?.let { visitAs (it.symbolPrimitive()) } + val byAlias = ctx.byIdent()?.let { visitAs (it.symbolPrimitive()) } fromValue(expr, From.Value.Type.SCAN, asAlias, atAlias, byAlias) } override fun visitTableBaseRefMatch(ctx: GeneratedParser.TableBaseRefMatchContext) = translate(ctx) { val expr = visitAs(ctx.source) - val asAlias = ctx.asIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } - val atAlias = ctx.atIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } - val byAlias = ctx.byIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } + val asAlias = ctx.asIdent()?.let { visitAs (it.symbolPrimitive()) } + val atAlias = ctx.atIdent()?.let { visitAs (it.symbolPrimitive()) } + val byAlias = ctx.byIdent()?.let { visitAs (it.symbolPrimitive()) } fromValue(expr, From.Value.Type.SCAN, asAlias, atAlias, byAlias) } @@ -1489,15 +1489,15 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitFromClauseSimpleImplicit(ctx: GeneratedParser.FromClauseSimpleImplicitContext) = translate(ctx) { val path = visitPathSimple(ctx.pathSimple()) - val asAlias = visitSymbolPrimitive(ctx.symbolPrimitive()) + val asAlias = visitAs (ctx.symbolPrimitive()) statementDMLDeleteTarget(path, asAlias, null, null) } override fun visitTableUnpivot(ctx: GeneratedParser.TableUnpivotContext) = translate(ctx) { val expr = visitAs(ctx.expr()) - val asAlias = ctx.asIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } - val atAlias = ctx.atIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } - val byAlias = ctx.byIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } + val asAlias = ctx.asIdent()?.let { visitAs (it.symbolPrimitive()) } + val atAlias = ctx.atIdent()?.let { visitAs (it.symbolPrimitive()) } + val byAlias = ctx.byIdent()?.let { visitAs (it.symbolPrimitive()) } fromValue(expr, From.Value.Type.UNPIVOT, asAlias, atAlias, byAlias) } @@ -1543,7 +1543,7 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitTableBaseRefSymbol(ctx: GeneratedParser.TableBaseRefSymbolContext) = translate(ctx) { val expr = visitAs(ctx.source) - val asAlias = visitSymbolPrimitive(ctx.symbolPrimitive()) + val asAlias = visitAs (ctx.symbolPrimitive()) fromValue(expr, From.Value.Type.SCAN, asAlias, null, null) } @@ -1753,7 +1753,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitPathStepDotExpr(ctx: GeneratedParser.PathStepDotExprContext) = translate(ctx) { - val symbol = visitSymbolPrimitive(ctx.symbolPrimitive()) + val symbol = visitAs (ctx.symbolPrimitive()) exprPathStepSymbol(symbol) } @@ -1851,8 +1851,8 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitFunctionCall(ctx: GeneratedParser.FunctionCallContext) = translate(ctx) { val args = visitOrEmpty(ctx.expr()) when (val funcName = ctx.functionName()) { - is GeneratedParser.FunctionNameReservedContext -> { - when (funcName.name.type) { + is GeneratedParser.FunctionNameContext -> { + when (funcName.name.start.type) { GeneratedParser.MOD -> exprBinary(Expr.Binary.Op.MODULO, args[0], args[1]) else -> visitNonReservedFunctionCall(ctx, args) } @@ -1865,13 +1865,12 @@ internal class PartiQLParserDefault : PartiQLParser { return exprCall(function, args) } - override fun visitFunctionNameReserved(ctx: GeneratedParser.FunctionNameReservedContext): Identifier { - val path = ctx.qualifier.map { visitSymbolPrimitive(it) } - val name = when (ctx.name.type) { + override fun visitFunctionName(ctx: GeneratedParser.FunctionNameContext): Identifier { + val path = ctx.qualifier.map { visitAs (it) } + val name = when (ctx.name.start.type) { GeneratedParser.CHARACTER_LENGTH, GeneratedParser.CHAR_LENGTH -> identifierSymbol("char_length", Identifier.CaseSensitivity.INSENSITIVE) - else -> - identifierSymbol(ctx.name.text, Identifier.CaseSensitivity.INSENSITIVE) + else -> visitAs (ctx.name) } return if (path.isEmpty()) { name @@ -1882,18 +1881,6 @@ internal class PartiQLParserDefault : PartiQLParser { } } - override fun visitFunctionNameSymbol(ctx: GeneratedParser.FunctionNameSymbolContext): Identifier { - val path = ctx.qualifier.map { visitSymbolPrimitive(it) } - val name = visitSymbolPrimitive(ctx.name) - return if (path.isEmpty()) { - name - } else { - val root = path.first() - val steps = path.drop(1) + listOf(name) - identifierQualified(root, steps) - } - } - /** * * FUNCTIONS WITH SPECIAL FORMS @@ -2313,9 +2300,9 @@ internal class PartiQLParserDefault : PartiQLParser { /** * Visiting a symbol to get a string, skip the wrapping, unwrapping, and location tracking. */ - private fun symbolToString(ctx: GeneratedParser.SymbolPrimitiveContext) = when (ctx.ident.type) { - GeneratedParser.IDENTIFIER_QUOTED -> ctx.IDENTIFIER_QUOTED().getStringValue() - GeneratedParser.IDENTIFIER -> ctx.IDENTIFIER().getStringValue() + private fun symbolToString(ctx: GeneratedParser.SymbolPrimitiveContext) = when (ctx) { + is GeneratedParser.QuotedIdentifierContext -> ctx.IDENTIFIER_QUOTED().getStringValue() + is GeneratedParser.UnquotedIdentifierContext -> ctx.text else -> throw error(ctx, "Invalid symbol reference.") } From 445be01db417657469c8b833b93c6b7b4b63965c Mon Sep 17 00:00:00 2001 From: Alan Cai Date: Tue, 7 May 2024 14:59:34 -0700 Subject: [PATCH 2/3] Rename symbolPrimitive rules; directly call visit fun --- .../lang/syntax/impl/PartiQLPigVisitor.kt | 80 ++++++++------- partiql-parser/src/main/antlr/PartiQL.g4 | 6 +- .../parser/internal/PartiQLParserDefault.kt | 99 ++++++++++--------- 3 files changed, 98 insertions(+), 87 deletions(-) diff --git a/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt b/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt index 60fa7099b9..25a6c19207 100644 --- a/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt +++ b/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt @@ -48,7 +48,6 @@ import org.partiql.lang.ast.IsValuesExprMeta import org.partiql.lang.ast.LegacyLogicalNotMeta import org.partiql.lang.ast.SourceLocationMeta import org.partiql.lang.domains.PartiqlAst -import org.partiql.lang.domains.PartiqlAst.PartiqlAstNode import org.partiql.lang.domains.metaContainerOf import org.partiql.lang.eval.EvaluationException import org.partiql.lang.eval.time.MAX_PRECISION_FOR_TIME @@ -193,13 +192,20 @@ internal class PartiQLPigVisitor( * */ - override fun visitAsIdent(ctx: PartiQLParser.AsIdentContext) = visitAs (ctx.symbolPrimitive()) + override fun visitAsIdent(ctx: PartiQLParser.AsIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) - override fun visitAtIdent(ctx: PartiQLParser.AtIdentContext) = visitAs (ctx.symbolPrimitive()) + override fun visitAtIdent(ctx: PartiQLParser.AtIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) - override fun visitByIdent(ctx: PartiQLParser.ByIdentContext) = visitAs (ctx.symbolPrimitive()) + override fun visitByIdent(ctx: PartiQLParser.ByIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) - override fun visitQuotedIdentifier(ctx: PartiQLParser.QuotedIdentifierContext): PartiqlAst.Expr.Id = PartiqlAst.build { + private fun visitSymbolPrimitive(ctx: PartiQLParser.SymbolPrimitiveContext): PartiqlAst.Expr.Id = + when (ctx) { + is PartiQLParser.IdentifierQuotedContext -> visitIdentifierQuoted(ctx) + is PartiQLParser.IdentifierUnquotedContext -> visitIdentifierUnquoted(ctx) + else -> throw ParserException("Invalid symbol reference.", ErrorCode.PARSE_INVALID_QUERY) + } + + override fun visitIdentifierQuoted(ctx: PartiQLParser.IdentifierQuotedContext): PartiqlAst.Expr.Id = PartiqlAst.build { id( ctx.IDENTIFIER_QUOTED().getStringValue(), caseSensitive(), @@ -208,7 +214,7 @@ internal class PartiQLPigVisitor( ) } - override fun visitUnquotedIdentifier(ctx: PartiQLParser.UnquotedIdentifierContext): PartiqlAst.Expr.Id = PartiqlAst.build { + override fun visitIdentifierUnquoted(ctx: PartiQLParser.IdentifierUnquotedContext): PartiqlAst.Expr.Id = PartiqlAst.build { id( ctx.text, caseInsensitive(), @@ -230,7 +236,7 @@ internal class PartiQLPigVisitor( override fun visitDropTable(ctx: PartiQLParser.DropTableContext) = PartiqlAst.build { val id = if (ctx.qualifiedName().qualifier.isEmpty()) { - visitAs (ctx.qualifiedName().name) + visitSymbolPrimitive(ctx.qualifiedName().name) } else { throw ParserException("PIG Parser does not support qualified name as table name", ErrorCode.PARSE_UNEXPECTED_TOKEN) } @@ -238,14 +244,14 @@ internal class PartiQLPigVisitor( } override fun visitDropIndex(ctx: PartiQLParser.DropIndexContext) = PartiqlAst.build { - val id = visitAs (ctx.target) - val key = visitAs (ctx.on) + val id = visitSymbolPrimitive(ctx.target) + val key = visitSymbolPrimitive(ctx.on) dropIndex(key.toIdentifier(), id.toIdentifier(), ctx.DROP().getSourceMetaContainer()) } override fun visitCreateTable(ctx: PartiQLParser.CreateTableContext) = PartiqlAst.build { val name = if (ctx.qualifiedName().qualifier.isEmpty()) { - visitAs (ctx.qualifiedName().name).name + visitSymbolPrimitive(ctx.qualifiedName().name).name } else { throw ParserException("PIG Parser does not support qualified name as table name", ErrorCode.PARSE_UNEXPECTED_TOKEN) } @@ -255,7 +261,7 @@ internal class PartiQLPigVisitor( } override fun visitCreateIndex(ctx: PartiQLParser.CreateIndexContext) = PartiqlAst.build { - val id = visitAs (ctx.symbolPrimitive()) + val id = visitSymbolPrimitive(ctx.symbolPrimitive()) val fields = ctx.pathSimple().map { path -> visitPathSimple(path) } createIndex(id.toIdentifier(), fields, ctx.CREATE().getSourceMetaContainer()) } @@ -266,7 +272,7 @@ internal class PartiQLPigVisitor( } override fun visitColumnDeclaration(ctx: PartiQLParser.ColumnDeclarationContext) = PartiqlAst.build { - val name = visitAs (ctx.columnName().symbolPrimitive()).name.text + val name = visitSymbolPrimitive(ctx.columnName().symbolPrimitive()).name.text val type = visit(ctx.type()) as PartiqlAst.Type val constrs = ctx.columnConstraint().map { visitColumnConstraint(it) } if (ctx.OPTIONAL() != null) { @@ -279,7 +285,7 @@ internal class PartiQLPigVisitor( } override fun visitColumnConstraint(ctx: PartiQLParser.ColumnConstraintContext) = PartiqlAst.build { - val name = ctx.constraintName()?.let { visitAs (it.symbolPrimitive()).name.text } + val name = ctx.constraintName()?.let { visitSymbolPrimitive(it.symbolPrimitive()).name.text } val def = visit(ctx.columnConstraintDef()) as PartiqlAst.ColumnConstraintDef columnConstraint(name, def) } @@ -376,7 +382,7 @@ internal class PartiQLPigVisitor( override fun visitInsertStatement(ctx: PartiQLParser.InsertStatementContext) = PartiqlAst.build { insert( - target = visitAs (ctx.symbolPrimitive()), + target = visitSymbolPrimitive(ctx.symbolPrimitive()), asAlias = ctx.asIdent()?.let { visitAsIdent(it).name.text }, values = visitExpr(ctx.value), conflictAction = ctx.onConflict()?.let { visitOnConflict(it) }, @@ -386,7 +392,7 @@ internal class PartiQLPigVisitor( override fun visitReplaceCommand(ctx: PartiQLParser.ReplaceCommandContext) = PartiqlAst.build { insert( - target = visitAs (ctx.symbolPrimitive()), + target = visitSymbolPrimitive(ctx.symbolPrimitive()), asAlias = ctx.asIdent()?.let { visitAsIdent(it).name.text }, values = visitExpr(ctx.value), conflictAction = doReplace(excluded()), @@ -397,7 +403,7 @@ internal class PartiQLPigVisitor( // Based on https://github.com/partiql/partiql-docs/blob/main/RFCs/0011-partiql-insert.md override fun visitUpsertCommand(ctx: PartiQLParser.UpsertCommandContext) = PartiqlAst.build { insert( - target = visitAs (ctx.symbolPrimitive()), + target = visitSymbolPrimitive(ctx.symbolPrimitive()), asAlias = ctx.asIdent()?.let { visitAsIdent(it).name.text }, values = visitExpr(ctx.value), conflictAction = doUpdate(excluded()), @@ -491,7 +497,7 @@ internal class PartiQLPigVisitor( } override fun visitPathSimple(ctx: PartiQLParser.PathSimpleContext) = PartiqlAst.build { - val root = visitAs (ctx.symbolPrimitive()) + val root = visitSymbolPrimitive(ctx.symbolPrimitive()) if (ctx.pathSimpleSteps().isEmpty()) return@build root val steps = ctx.pathSimpleSteps().map { visit(it) as PartiqlAst.PathStep } path(root, steps, root.metas) @@ -502,7 +508,7 @@ internal class PartiQLPigVisitor( } override fun visitPathSimpleSymbol(ctx: PartiQLParser.PathSimpleSymbolContext) = PartiqlAst.build { - pathExpr(visitAs (ctx.symbolPrimitive()), caseSensitive()) + pathExpr(visitSymbolPrimitive(ctx.symbolPrimitive()), caseSensitive()) } override fun visitPathSimpleDotSymbol(ctx: PartiQLParser.PathSimpleDotSymbolContext) = @@ -598,7 +604,7 @@ internal class PartiQLPigVisitor( override fun visitProjectionItem(ctx: PartiQLParser.ProjectionItemContext) = PartiqlAst.build { val expr = visitExpr(ctx.expr()) - val alias = ctx.symbolPrimitive()?.let { visitAs (it).name } + val alias = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).name } if (expr is PartiqlAst.Expr.Path) convertPathToProjectionItem(expr, alias) else projectExpr_(expr, asAlias = alias, expr.metas) } @@ -657,7 +663,7 @@ internal class PartiQLPigVisitor( } override fun visitExcludeExpr(ctx: PartiQLParser.ExcludeExprContext) = PartiqlAst.build { - val root = visitAs (ctx.symbolPrimitive()).toIdentifier() + val root = visitSymbolPrimitive(ctx.symbolPrimitive()).toIdentifier() val steps = ctx.excludeExprSteps().map { visit(it) as PartiqlAst.ExcludeStep } excludeExpr(root, steps) } @@ -665,8 +671,8 @@ internal class PartiQLPigVisitor( override fun visitExcludeExprTupleAttr(ctx: PartiQLParser.ExcludeExprTupleAttrContext) = PartiqlAst.build { val attr = ctx.symbolPrimitive().getString() val caseSensitivity = when (ctx.symbolPrimitive()) { - is PartiQLParser.QuotedIdentifierContext -> caseSensitive() - is PartiQLParser.UnquotedIdentifierContext -> caseInsensitive() + is PartiQLParser.IdentifierQuotedContext -> caseSensitive() + is PartiQLParser.IdentifierUnquotedContext -> caseInsensitive() else -> throw ParserException("Invalid symbol reference.", ErrorCode.PARSE_INVALID_QUERY) } excludeTupleAttr(identifier(attr, caseSensitivity)) @@ -736,7 +742,7 @@ internal class PartiQLPigVisitor( groupBy_(strategy, keyList = keyList, groupAsAlias = alias, ctx.GROUP().getSourceMetaContainer()) } - override fun visitGroupAlias(ctx: PartiQLParser.GroupAliasContext) = visitAs (ctx.symbolPrimitive()) + override fun visitGroupAlias(ctx: PartiQLParser.GroupAliasContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) /** * Returns a GROUP BY key @@ -759,7 +765,7 @@ internal class PartiQLPigVisitor( ErrorCode.PARSE_UNSUPPORTED_LITERALS_GROUPBY ) } - val alias = ctx.symbolPrimitive()?.let { visitAs (it).toPigSymbolPrimitive() } + val alias = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).toPigSymbolPrimitive() } groupKey_(expr, asAlias = alias, expr.metas) } @@ -828,7 +834,7 @@ internal class PartiQLPigVisitor( } override fun visitPatternPathVariable(ctx: PartiQLParser.PatternPathVariableContext) = - visitAs (ctx.symbolPrimitive()) + visitSymbolPrimitive(ctx.symbolPrimitive()) override fun visitSelectorBasic(ctx: PartiQLParser.SelectorBasicContext) = PartiqlAst.build { val metas = ctx.mod.getSourceMetaContainer() @@ -876,7 +882,7 @@ internal class PartiQLPigVisitor( } override fun visitLabelPrimaryName(ctx: PartiQLParser.LabelPrimaryNameContext) = PartiqlAst.build { - val x = visitAs (ctx.symbolPrimitive()) + val x = visitSymbolPrimitive(ctx.symbolPrimitive()) graphLabelName_(x.name, x.metas) } @@ -918,7 +924,7 @@ internal class PartiQLPigVisitor( override fun visitEdgeSpec(ctx: PartiQLParser.EdgeSpecContext) = PartiqlAst.build { val placeholderDirection = edgeRight() - val variable = ctx.symbolPrimitive()?.let { visitAs (it).name } + val variable = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).name } val prefilter = ctx.whereClause()?.let { visitWhereClause(it) } val label = ctx.labelSpec()?.let { visit(it) as PartiqlAst.GraphLabelSpec } edge_(direction = placeholderDirection, variable = variable, prefilter = prefilter, label = label) @@ -983,7 +989,7 @@ internal class PartiQLPigVisitor( } override fun visitNode(ctx: PartiQLParser.NodeContext) = PartiqlAst.build { - val variable = ctx.symbolPrimitive()?.let { visitAs (it).name } + val variable = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).name } val prefilter = ctx.whereClause()?.let { visitWhereClause(it) } val label = ctx.labelSpec()?.let { visit(it) as PartiqlAst.GraphLabelSpec } node_(variable = variable, prefilter = prefilter, label = label) @@ -1071,13 +1077,13 @@ internal class PartiQLPigVisitor( override fun visitTableBaseRefSymbol(ctx: PartiQLParser.TableBaseRefSymbolContext) = PartiqlAst.build { val expr = visit(ctx.source) as PartiqlAst.Expr - val name = ctx.symbolPrimitive()?.let { visitAs (it).toPigSymbolPrimitive() } + val name = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).toPigSymbolPrimitive() } scan_(expr, name, metas = expr.metas) } override fun visitFromClauseSimpleImplicit(ctx: PartiQLParser.FromClauseSimpleImplicitContext) = PartiqlAst.build { val path = visitPathSimple(ctx.pathSimple()) - val name = ctx.symbolPrimitive()?.let { visitAs (it).name } + val name = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it).name } scan_(path, name, metas = path.metas) } @@ -1819,8 +1825,8 @@ internal class PartiQLPigVisitor( } private fun PartiQLParser.SymbolPrimitiveContext.getSourceMetaContainer() = when (this) { - is PartiQLParser.QuotedIdentifierContext -> this.IDENTIFIER_QUOTED().getSourceMetaContainer() - is PartiQLParser.UnquotedIdentifierContext -> this.start.getSourceMetaContainer() + is PartiQLParser.IdentifierQuotedContext -> this.IDENTIFIER_QUOTED().getSourceMetaContainer() + is PartiQLParser.IdentifierUnquotedContext -> this.start.getSourceMetaContainer() else -> throw ParserException( "Unable to get identifier's source meta-container.", ErrorCode.PARSE_INVALID_QUERY @@ -2125,19 +2131,19 @@ internal class PartiQLPigVisitor( private fun PartiQLParser.SymbolPrimitiveContext.getString(): String { return when (this) { - is PartiQLParser.QuotedIdentifierContext -> this.IDENTIFIER_QUOTED().getStringValue() - is PartiQLParser.UnquotedIdentifierContext -> this.text + is PartiQLParser.IdentifierQuotedContext -> this.IDENTIFIER_QUOTED().getStringValue() + is PartiQLParser.IdentifierUnquotedContext -> this.text else -> throw ParserException("Unable to get symbol's text.", ErrorCode.PARSE_INVALID_QUERY) } } private fun getSymbolPathExpr(ctx: PartiQLParser.SymbolPrimitiveContext) = PartiqlAst.build { when (ctx) { - is PartiQLParser.QuotedIdentifierContext -> pathExpr( + is PartiQLParser.IdentifierQuotedContext -> pathExpr( lit(ionString(ctx.IDENTIFIER_QUOTED().getStringValue())), caseSensitive(), metas = ctx.getSourceMetaContainer() ) - is PartiQLParser.UnquotedIdentifierContext -> pathExpr( + is PartiQLParser.IdentifierUnquotedContext -> pathExpr( lit(ionString(ctx.text)), caseInsensitive(), metas = ctx.getSourceMetaContainer() ) @@ -2145,8 +2151,6 @@ internal class PartiQLPigVisitor( } } - private inline fun visitAs(ctx: ParserRuleContext): T = visit(ctx) as T - private fun String.toInteger() = BigInteger(this, 10) private fun Token.toSymbol(): PartiqlAst.Expr.Lit { diff --git a/partiql-parser/src/main/antlr/PartiQL.g4 b/partiql-parser/src/main/antlr/PartiQL.g4 index 81f0213e9d..240f82b79b 100644 --- a/partiql-parser/src/main/antlr/PartiQL.g4 +++ b/partiql-parser/src/main/antlr/PartiQL.g4 @@ -40,9 +40,9 @@ byIdent : BY symbolPrimitive; symbolPrimitive - : IDENTIFIER # UnquotedIdentifier - | IDENTIFIER_QUOTED # QuotedIdentifier - | nonReserved # UnquotedIdentifier + : IDENTIFIER # IdentifierUnquoted + | IDENTIFIER_QUOTED # IdentifierQuoted + | nonReserved # IdentifierUnquoted ; /** diff --git a/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt b/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt index 6c8261aaee..628a00b64b 100644 --- a/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt +++ b/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt @@ -557,20 +557,27 @@ internal class PartiQLParserDefault : PartiQLParser { * */ - override fun visitAsIdent(ctx: GeneratedParser.AsIdentContext) = visitAs (ctx.symbolPrimitive()) + override fun visitAsIdent(ctx: GeneratedParser.AsIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) - override fun visitAtIdent(ctx: GeneratedParser.AtIdentContext) = visitAs (ctx.symbolPrimitive()) + override fun visitAtIdent(ctx: GeneratedParser.AtIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) - override fun visitByIdent(ctx: GeneratedParser.ByIdentContext) = visitAs (ctx.symbolPrimitive()) + override fun visitByIdent(ctx: GeneratedParser.ByIdentContext) = visitSymbolPrimitive(ctx.symbolPrimitive()) - override fun visitQuotedIdentifier(ctx: org.partiql.parser.internal.antlr.PartiQLParser.QuotedIdentifierContext): Identifier.Symbol = translate(ctx) { + private fun visitSymbolPrimitive(ctx: GeneratedParser.SymbolPrimitiveContext): Identifier.Symbol = + when (ctx) { + is GeneratedParser.IdentifierQuotedContext -> visitIdentifierQuoted(ctx) + is GeneratedParser.IdentifierUnquotedContext -> visitIdentifierUnquoted(ctx) + else -> throw error(ctx, "Invalid symbol reference.") + } + + override fun visitIdentifierQuoted(ctx: GeneratedParser.IdentifierQuotedContext): Identifier.Symbol = translate(ctx) { identifierSymbol( ctx.IDENTIFIER_QUOTED().getStringValue(), Identifier.CaseSensitivity.SENSITIVE ) } - override fun visitUnquotedIdentifier(ctx: org.partiql.parser.internal.antlr.PartiQLParser.UnquotedIdentifierContext): Identifier.Symbol = translate(ctx) { + override fun visitIdentifierUnquoted(ctx: GeneratedParser.IdentifierUnquotedContext): Identifier.Symbol = translate(ctx) { identifierSymbol( ctx.text, Identifier.CaseSensitivity.INSENSITIVE @@ -578,8 +585,8 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitQualifiedName(ctx: GeneratedParser.QualifiedNameContext) = translate(ctx) { - val qualifier = ctx.qualifier.map { visitAs (it) } - val name = visitAs (ctx.name) + val qualifier = ctx.qualifier.map { visitSymbolPrimitive(it) } + val name = visitSymbolPrimitive(ctx.name) if (qualifier.isEmpty()) { name } else { @@ -605,8 +612,8 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitDropIndex(ctx: GeneratedParser.DropIndexContext) = translate(ctx) { - val table = visitAs (ctx.on) - val index = visitAs (ctx.target) + val table = visitSymbolPrimitive(ctx.on) + val index = visitSymbolPrimitive(ctx.target) ddlOpDropIndex(index, table) } @@ -638,7 +645,7 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitCreateIndex(ctx: GeneratedParser.CreateIndexContext) = translate(ctx) { // TODO add index name to ANTLR grammar val name: Identifier? = null - val table = visitAs (ctx.symbolPrimitive()) + val table = visitSymbolPrimitive(ctx.symbolPrimitive()) val fields = ctx.pathSimple().map { path -> visitPathSimple(path) } ddlOpCreateIndex(name, table, fields) } @@ -657,7 +664,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitColumnDeclaration(ctx: GeneratedParser.ColumnDeclarationContext) = translate(ctx) { - val name = visitAs (ctx.columnName().symbolPrimitive()) + val name = visitSymbolPrimitive(ctx.columnName().symbolPrimitive()) val type = (visit(ctx.type()) as Type).also { isValidTypeDeclarationOrThrow(it, ctx.type()) } @@ -727,7 +734,7 @@ internal class PartiQLParserDefault : PartiQLParser { is GeneratedParser.UniqueContext -> false else -> throw error(ctx, "Expect UNIQUE or PRIMARY KEY") } - val columns = ctx.columnName().map { visitAs (it.symbolPrimitive()) } + val columns = ctx.columnName().map { visitSymbolPrimitive(it.symbolPrimitive()) } constraintDefinitionUnique(columns, isPrimaryKey) } @@ -741,7 +748,7 @@ internal class PartiQLParserDefault : PartiQLParser { ctx.partitionBy().accept(this) as PartitionBy override fun visitPartitionColList(ctx: GeneratedParser.PartitionColListContext) = translate(ctx) { - partitionByAttrList(ctx.columnName().map { visitAs (it.symbolPrimitive()) }) + partitionByAttrList(ctx.columnName().map { visitSymbolPrimitive(it.symbolPrimitive()) }) } /** @@ -867,7 +874,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitInsertStatement(ctx: GeneratedParser.InsertStatementContext) = translate(ctx) { - val target = visitAs (ctx.symbolPrimitive()) + val target = visitSymbolPrimitive(ctx.symbolPrimitive()) val values = visitExpr(ctx.value) val asAlias = visitOrNull(ctx.asIdent()) val onConflict = ctx.onConflict()?.let { visitOnConflictClause(it) } @@ -875,14 +882,14 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitReplaceCommand(ctx: GeneratedParser.ReplaceCommandContext) = translate(ctx) { - val target = visitAs (ctx.symbolPrimitive()) + val target = visitSymbolPrimitive(ctx.symbolPrimitive()) val values = visitExpr(ctx.value) val asAlias = visitOrNull(ctx.asIdent()) statementDMLReplace(target, values, asAlias) } override fun visitUpsertCommand(ctx: GeneratedParser.UpsertCommandContext) = translate(ctx) { - val target = visitAs (ctx.symbolPrimitive()) + val target = visitSymbolPrimitive(ctx.symbolPrimitive()) val values = visitExpr(ctx.value) val asAlias = visitOrNull(ctx.asIdent()) statementDMLUpsert(target, values, asAlias) @@ -928,9 +935,9 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitConflictTarget(ctx: GeneratedParser.ConflictTargetContext) = translate(ctx) { if (ctx.constraintName() != null) { - onConflictTargetConstraint(visitAs (ctx.constraintName().symbolPrimitive())) + onConflictTargetConstraint(visitSymbolPrimitive(ctx.constraintName().symbolPrimitive())) } else { - val symbols = ctx.symbolPrimitive().map { visitAs (it) } + val symbols = ctx.symbolPrimitive().map { visitSymbolPrimitive(it) } onConflictTargetSymbols(symbols) } } @@ -953,7 +960,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitPathSimple(ctx: GeneratedParser.PathSimpleContext) = translate(ctx) { - val root = visitAs (ctx.symbolPrimitive()) + val root = visitSymbolPrimitive(ctx.symbolPrimitive()) val steps = visitOrEmpty(ctx.pathSimpleSteps()) path(root, steps) } @@ -975,12 +982,12 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitPathSimpleSymbol(ctx: GeneratedParser.PathSimpleSymbolContext) = translate(ctx) { - val identifier = visitAs (ctx.symbolPrimitive()) + val identifier = visitSymbolPrimitive(ctx.symbolPrimitive()) pathStepSymbol(identifier) } override fun visitPathSimpleDotSymbol(ctx: GeneratedParser.PathSimpleDotSymbolContext) = translate(ctx) { - val identifier = visitAs (ctx.symbolPrimitive()) + val identifier = visitSymbolPrimitive(ctx.symbolPrimitive()) pathStepSymbol(identifier) } @@ -1063,7 +1070,7 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitProjectionItem(ctx: GeneratedParser.ProjectionItemContext) = translate(ctx) { val expr = visitExpr(ctx.expr()) - val alias = ctx.symbolPrimitive()?.let { visitAs (it) } + val alias = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it) } if (expr is Expr.Path) { convertPathToProjectionItem(ctx, expr, alias) } else { @@ -1107,7 +1114,7 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitLetBinding(ctx: GeneratedParser.LetBindingContext) = translate(ctx) { val expr = visitAs(ctx.expr()) - val alias = visitAs (ctx.symbolPrimitive()) + val alias = visitSymbolPrimitive(ctx.symbolPrimitive()) letBinding(expr, alias) } @@ -1148,13 +1155,13 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitGroupClause(ctx: GeneratedParser.GroupClauseContext) = translate(ctx) { val strategy = if (ctx.PARTIAL() != null) GroupBy.Strategy.PARTIAL else GroupBy.Strategy.FULL val keys = visitOrEmpty(ctx.groupKey()) - val alias = ctx.groupAlias()?.symbolPrimitive()?.let { visitAs (it) } + val alias = ctx.groupAlias()?.symbolPrimitive()?.let { visitSymbolPrimitive(it) } groupBy(strategy, keys, alias) } override fun visitGroupKey(ctx: GeneratedParser.GroupKeyContext) = translate(ctx) { val expr = visitAs(ctx.key) - val alias = ctx.symbolPrimitive()?.let { visitAs (it) } + val alias = ctx.symbolPrimitive()?.let { visitSymbolPrimitive(it) } groupByKey(expr, alias) } @@ -1169,14 +1176,14 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitExcludeExpr(ctx: GeneratedParser.ExcludeExprContext) = translate(ctx) { - val rootId = visitAs (ctx.symbolPrimitive()) + val rootId = visitSymbolPrimitive(ctx.symbolPrimitive()) val root = exprVar(rootId, Expr.Var.Scope.DEFAULT) val steps = visitOrEmpty(ctx.excludeExprSteps()) excludeItem(root, steps) } override fun visitExcludeExprTupleAttr(ctx: GeneratedParser.ExcludeExprTupleAttrContext) = translate(ctx) { - val identifier = visitAs (ctx.symbolPrimitive()) + val identifier = visitSymbolPrimitive(ctx.symbolPrimitive()) excludeStepStructField(identifier) } @@ -1284,7 +1291,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitPatternPathVariable(ctx: GeneratedParser.PatternPathVariableContext) = - visitAs (ctx.symbolPrimitive()) + visitSymbolPrimitive(ctx.symbolPrimitive()) override fun visitSelectorBasic(ctx: GeneratedParser.SelectorBasicContext) = translate(ctx) { when (ctx.mod.type) { @@ -1327,7 +1334,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitLabelPrimaryName(ctx: GeneratedParser.LabelPrimaryNameContext) = translate(ctx) { - val x = visitAs (ctx.symbolPrimitive()) + val x = visitSymbolPrimitive(ctx.symbolPrimitive()) graphMatchLabelName(x.symbol) } @@ -1457,17 +1464,17 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitTableBaseRefClauses(ctx: GeneratedParser.TableBaseRefClausesContext) = translate(ctx) { val expr = visitAs(ctx.source) - val asAlias = ctx.asIdent()?.let { visitAs (it.symbolPrimitive()) } - val atAlias = ctx.atIdent()?.let { visitAs (it.symbolPrimitive()) } - val byAlias = ctx.byIdent()?.let { visitAs (it.symbolPrimitive()) } + val asAlias = ctx.asIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } + val atAlias = ctx.atIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } + val byAlias = ctx.byIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } fromValue(expr, From.Value.Type.SCAN, asAlias, atAlias, byAlias) } override fun visitTableBaseRefMatch(ctx: GeneratedParser.TableBaseRefMatchContext) = translate(ctx) { val expr = visitAs(ctx.source) - val asAlias = ctx.asIdent()?.let { visitAs (it.symbolPrimitive()) } - val atAlias = ctx.atIdent()?.let { visitAs (it.symbolPrimitive()) } - val byAlias = ctx.byIdent()?.let { visitAs (it.symbolPrimitive()) } + val asAlias = ctx.asIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } + val atAlias = ctx.atIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } + val byAlias = ctx.byIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } fromValue(expr, From.Value.Type.SCAN, asAlias, atAlias, byAlias) } @@ -1489,15 +1496,15 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitFromClauseSimpleImplicit(ctx: GeneratedParser.FromClauseSimpleImplicitContext) = translate(ctx) { val path = visitPathSimple(ctx.pathSimple()) - val asAlias = visitAs (ctx.symbolPrimitive()) + val asAlias = visitSymbolPrimitive(ctx.symbolPrimitive()) statementDMLDeleteTarget(path, asAlias, null, null) } override fun visitTableUnpivot(ctx: GeneratedParser.TableUnpivotContext) = translate(ctx) { val expr = visitAs(ctx.expr()) - val asAlias = ctx.asIdent()?.let { visitAs (it.symbolPrimitive()) } - val atAlias = ctx.atIdent()?.let { visitAs (it.symbolPrimitive()) } - val byAlias = ctx.byIdent()?.let { visitAs (it.symbolPrimitive()) } + val asAlias = ctx.asIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } + val atAlias = ctx.atIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } + val byAlias = ctx.byIdent()?.let { visitSymbolPrimitive(it.symbolPrimitive()) } fromValue(expr, From.Value.Type.UNPIVOT, asAlias, atAlias, byAlias) } @@ -1543,7 +1550,7 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitTableBaseRefSymbol(ctx: GeneratedParser.TableBaseRefSymbolContext) = translate(ctx) { val expr = visitAs(ctx.source) - val asAlias = visitAs (ctx.symbolPrimitive()) + val asAlias = visitSymbolPrimitive(ctx.symbolPrimitive()) fromValue(expr, From.Value.Type.SCAN, asAlias, null, null) } @@ -1753,7 +1760,7 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitPathStepDotExpr(ctx: GeneratedParser.PathStepDotExprContext) = translate(ctx) { - val symbol = visitAs (ctx.symbolPrimitive()) + val symbol = visitSymbolPrimitive(ctx.symbolPrimitive()) exprPathStepSymbol(symbol) } @@ -1866,11 +1873,11 @@ internal class PartiQLParserDefault : PartiQLParser { } override fun visitFunctionName(ctx: GeneratedParser.FunctionNameContext): Identifier { - val path = ctx.qualifier.map { visitAs (it) } + val path = ctx.qualifier.map { visitSymbolPrimitive(it) } val name = when (ctx.name.start.type) { GeneratedParser.CHARACTER_LENGTH, GeneratedParser.CHAR_LENGTH -> identifierSymbol("char_length", Identifier.CaseSensitivity.INSENSITIVE) - else -> visitAs (ctx.name) + else -> visitSymbolPrimitive(ctx.name) } return if (path.isEmpty()) { name @@ -2265,7 +2272,7 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitTypeStruct(ctx: GeneratedParser.TypeStructContext) = translate(ctx) { val fields = ctx.structField().map { structFieldCtx -> - val name = visitAs (structFieldCtx.columnName()) + val name = visitSymbolPrimitive(structFieldCtx.columnName().symbolPrimitive()) val type = visitAs(structFieldCtx.type()) .also { isValidTypeDeclarationOrThrow(it, structFieldCtx.type()) } @@ -2301,8 +2308,8 @@ internal class PartiQLParserDefault : PartiQLParser { * Visiting a symbol to get a string, skip the wrapping, unwrapping, and location tracking. */ private fun symbolToString(ctx: GeneratedParser.SymbolPrimitiveContext) = when (ctx) { - is GeneratedParser.QuotedIdentifierContext -> ctx.IDENTIFIER_QUOTED().getStringValue() - is GeneratedParser.UnquotedIdentifierContext -> ctx.text + is GeneratedParser.IdentifierQuotedContext -> ctx.IDENTIFIER_QUOTED().getStringValue() + is GeneratedParser.IdentifierUnquotedContext -> ctx.text else -> throw error(ctx, "Invalid symbol reference.") } From 7b615f893f360636d72e552148a59c0a1a4bb361 Mon Sep 17 00:00:00 2001 From: Alan Cai Date: Thu, 9 May 2024 15:44:05 -0700 Subject: [PATCH 3/3] Remove functionName w/ qualifiedName --- .../lang/syntax/impl/PartiQLPigVisitor.kt | 2 +- partiql-parser/src/main/antlr/PartiQL.g4 | 7 +--- .../parser/internal/PartiQLParserDefault.kt | 33 ++++++++----------- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt b/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt index 25a6c19207..31b588c079 100644 --- a/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt +++ b/partiql-lang/src/main/kotlin/org/partiql/lang/syntax/impl/PartiQLPigVisitor.kt @@ -1326,7 +1326,7 @@ internal class PartiQLPigVisitor( } override fun visitFunctionCall(ctx: PartiQLParser.FunctionCallContext) = PartiqlAst.build { - val nameCtx = ctx.functionName() + val nameCtx = ctx.qualifiedName() val name = if (nameCtx.qualifier.isNotEmpty()) { error("Legacy AST does not support qualified function names") } else { diff --git a/partiql-parser/src/main/antlr/PartiQL.g4 b/partiql-parser/src/main/antlr/PartiQL.g4 index 240f82b79b..0267c8983b 100644 --- a/partiql-parser/src/main/antlr/PartiQL.g4 +++ b/partiql-parser/src/main/antlr/PartiQL.g4 @@ -763,12 +763,7 @@ dateFunction // SQL-99 10.4 — ::= functionCall - : functionName PAREN_LEFT ( expr ( COMMA expr )* )? PAREN_RIGHT - ; - -// SQL-99 10.4 — ::= [ ] -functionName - : (qualifier+=symbolPrimitive PERIOD)* name=symbolPrimitive + : qualifiedName PAREN_LEFT ( expr ( COMMA expr )* )? PAREN_RIGHT ; pathStep diff --git a/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt b/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt index 628a00b64b..27a1b39da4 100644 --- a/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt +++ b/partiql-parser/src/main/kotlin/org/partiql/parser/internal/PartiQLParserDefault.kt @@ -1857,10 +1857,21 @@ internal class PartiQLParserDefault : PartiQLParser { override fun visitFunctionCall(ctx: GeneratedParser.FunctionCallContext) = translate(ctx) { val args = visitOrEmpty(ctx.expr()) - when (val funcName = ctx.functionName()) { - is GeneratedParser.FunctionNameContext -> { + when (val funcName = ctx.qualifiedName()) { + is GeneratedParser.QualifiedNameContext -> { when (funcName.name.start.type) { GeneratedParser.MOD -> exprBinary(Expr.Binary.Op.MODULO, args[0], args[1]) + GeneratedParser.CHARACTER_LENGTH, GeneratedParser.CHAR_LENGTH -> { + val path = ctx.qualifiedName().qualifier.map { visitSymbolPrimitive(it) } + val name = identifierSymbol("char_length", Identifier.CaseSensitivity.INSENSITIVE) + if (path.isEmpty()) { + exprCall(name, args) + } else { + val root = path.first() + val steps = path.drop(1) + listOf(name) + exprCall(identifierQualified(root, steps), args) + } + } else -> visitNonReservedFunctionCall(ctx, args) } } @@ -1868,26 +1879,10 @@ internal class PartiQLParserDefault : PartiQLParser { } } private fun visitNonReservedFunctionCall(ctx: GeneratedParser.FunctionCallContext, args: List): Expr.Call { - val function = visit(ctx.functionName()) as Identifier + val function = visitQualifiedName(ctx.qualifiedName()) return exprCall(function, args) } - override fun visitFunctionName(ctx: GeneratedParser.FunctionNameContext): Identifier { - val path = ctx.qualifier.map { visitSymbolPrimitive(it) } - val name = when (ctx.name.start.type) { - GeneratedParser.CHARACTER_LENGTH, GeneratedParser.CHAR_LENGTH -> - identifierSymbol("char_length", Identifier.CaseSensitivity.INSENSITIVE) - else -> visitSymbolPrimitive(ctx.name) - } - return if (path.isEmpty()) { - name - } else { - val root = path.first() - val steps = path.drop(1) + listOf(name) - identifierQualified(root, steps) - } - } - /** * * FUNCTIONS WITH SPECIAL FORMS