Skip to content

Commit

Permalink
Merge c19931c into 4f783c7
Browse files Browse the repository at this point in the history
  • Loading branch information
alancai98 authored Aug 22, 2024
2 parents 4f783c7 + c19931c commit f6adc8e
Show file tree
Hide file tree
Showing 9 changed files with 2,363 additions and 3,943 deletions.
1,121 changes: 0 additions & 1,121 deletions partiql-ast/api/partiql-ast.api

Large diffs are not rendered by default.

276 changes: 0 additions & 276 deletions partiql-ast/src/main/kotlin/org/partiql/ast/helpers/ToLegacyAst.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@ import org.partiql.ast.GraphMatch
import org.partiql.ast.GroupBy
import org.partiql.ast.Identifier
import org.partiql.ast.Let
import org.partiql.ast.OnConflict
import org.partiql.ast.OrderBy
import org.partiql.ast.Path
import org.partiql.ast.QueryBody
import org.partiql.ast.Returning
import org.partiql.ast.Select
import org.partiql.ast.SetOp
import org.partiql.ast.SetQuantifier
Expand Down Expand Up @@ -102,12 +100,6 @@ private class AstTranslator(val metas: Map<String, MetaContainer>) : AstBaseVisi
query(expr, metas)
}

override fun visitStatementExec(node: Statement.Exec, ctx: Ctx) = translate(node) { metas ->
val procedureName = node.procedure
val args = node.args.translate<PartiqlAst.Expr>(ctx)
exec(procedureName, args, metas)
}

override fun visitStatementExplain(node: Statement.Explain, ctx: Ctx) = translate(node) { metas ->
val target = visitStatementExplainTarget(node.target, ctx)
explain(target, metas)
Expand Down Expand Up @@ -1012,274 +1004,6 @@ private class AstTranslator(val metas: Map<String, MetaContainer>) : AstBaseVisi
graphLabelDisj(lhs, rhs, metas)
}

/**
* DML
*/

override fun visitStatementDML(node: Statement.DML, ctx: Ctx) =
super.visitStatementDML(node, ctx) as PartiqlAst.Statement

override fun visitStatementDMLInsert(node: Statement.DML.Insert, ctx: Ctx) = translate(node) { metas ->
val target = visitIdentifier(node.target, ctx)
val asAlias = node.asAlias?.symbol
val values = visitExpr(node.values, ctx)
val conflictAction = node.onConflict?.let { visitOnConflictAction(it.action, ctx) }
val op = insert(target, asAlias, values, conflictAction)
dml(dmlOpList(op), null, null, null, metas)
}

override fun visitStatementDMLInsertLegacy(
node: Statement.DML.InsertLegacy,
ctx: Ctx,
) = translate(node) { metas ->
val target = visitPathUnpack(node.target, ctx)
val values = visitExpr(node.value, ctx)
val index = node.index?.let { visitExpr(it, ctx) }
val onConflict = node.conflictCondition?.let {
val condition = visitExpr(it, ctx)
onConflict(condition, doNothing())
}
val op = insertValue(target, values, index, onConflict)
dml(dmlOpList(op), null, null, null, metas)
}

override fun visitStatementDMLUpsert(node: Statement.DML.Upsert, ctx: Ctx) = translate(node) { metas ->
val target = visitIdentifier(node.target, ctx)
val asAlias = node.asAlias?.symbol
val values = visitExpr(node.values, ctx)
val conflictAction = doUpdate(excluded())
// UPSERT overloads legacy INSERT
val op = insert(target, asAlias, values, conflictAction)
dml(dmlOpList(op), null, null, null, metas)
}

override fun visitStatementDMLReplace(node: Statement.DML.Replace, ctx: Ctx) = translate(node) { metas ->
val target = visitIdentifier(node.target, ctx)
val asAlias = node.asAlias?.symbol
val values = visitExpr(node.values, ctx)
val conflictAction = doReplace(excluded())
// REPLACE overloads legacy INSERT
val op = insert(target, asAlias, values, conflictAction)
dml(dmlOpList(op), null, null, null, metas)
}

override fun visitStatementDMLUpdate(node: Statement.DML.Update, ctx: Ctx) = translate(node) { metas ->
// Current PartiQL.g4 grammar models a SET with no UPDATE target as valid DML command.
// We don't want the target to be nullable in the AST because it's not in the SQL grammar.
// val target = visitPathUnpack(node.target, ctx)
// val from = scan(target)
// UPDATE becomes multiple sets
val operations = node.assignments.map {
val assignment = visitStatementDMLUpdateAssignment(it, ctx)
set(assignment)
}
dml(dmlOpList(operations), null, null, null, metas)
}

override fun visitStatementDMLUpdateAssignment(
node: Statement.DML.Update.Assignment,
ctx: Ctx,
) = translate(node) { metas ->
val target = visitPathUnpack(node.target, ctx)
val value = visitExpr(node.value, ctx)
assignment(target, value, metas)
}

override fun visitStatementDMLRemove(node: Statement.DML.Remove, ctx: Ctx) = translate(node) { metas ->
val target = visitPathUnpack(node.target, ctx)
val op = remove(target)
dml(dmlOpList(op), null, null, null, metas)
}

override fun visitStatementDMLDelete(node: Statement.DML.Delete, ctx: Ctx) = translate(node) { metas ->
val from = visitStatementDMLDeleteTarget(node.target, ctx)
val where = node.where?.let { visitExpr(it, ctx) }
val returning = node.returning?.let { visitReturning(it, ctx) }
val op = delete()
dml(dmlOpList(op), from, where, returning, metas)
}

override fun visitStatementDMLDeleteTarget(node: Statement.DML.Delete.Target, ctx: Ctx) = translate(node) { metas ->
val path = visitPathUnpack(node.path, ctx)
val asAlias = node.asAlias?.symbol
val atAlias = node.atAlias?.symbol
val byAlias = node.byAlias?.symbol
scan(path, asAlias, atAlias, byAlias, metas)
}

override fun visitStatementDMLBatchLegacy(node: Statement.DML.BatchLegacy, ctx: Ctx) = translate(node) { metas ->
val from = node.target?.let { visitFrom(it, ctx) }
val ops = node.ops.translate<PartiqlAst.DmlOpList>(ctx).flatMap { it.ops }
val where = node.where?.let { visitExpr(it, ctx) }
val returning = node.returning?.let { visitReturning(it, ctx) }
dml(dmlOpList(ops), from, where, returning, metas)
}

override fun visitStatementDMLBatchLegacyOp(node: Statement.DML.BatchLegacy.Op, ctx: Ctx) =
super.visitStatementDMLBatchLegacyOp(node, ctx) as PartiqlAst.DmlOpList

override fun visitStatementDMLBatchLegacyOpSet(
node: Statement.DML.BatchLegacy.Op.Set,
ctx: Ctx,
) = translate(node) { metas ->
val ops = node.assignments.map {
val assignment = visitStatementDMLUpdateAssignment(it, ctx)
set(assignment)
}
dmlOpList(ops, metas)
}

override fun visitStatementDMLBatchLegacyOpRemove(
node: Statement.DML.BatchLegacy.Op.Remove,
ctx: Ctx,
) = translate(node) { metas ->
val target = visitPathUnpack(node.target, ctx)
val ops = listOf(remove(target))
dmlOpList(ops, metas)
}

override fun visitStatementDMLBatchLegacyOpDelete(
node: Statement.DML.BatchLegacy.Op.Delete,
ctx: Ctx,
) = translate(node) { metas ->
val ops = listOf(delete())
dmlOpList(ops, metas)
}

override fun visitStatementDMLBatchLegacyOpInsert(
node: Statement.DML.BatchLegacy.Op.Insert,
ctx: Ctx,
) = translate(node) { metas ->
val target = visitIdentifier(node.target, ctx)
val asAlias = node.asAlias?.symbol
val values = visitExpr(node.values, ctx)
val conflictAction = node.onConflict?.let { visitOnConflictAction(it.action, ctx) }
dmlOpList(insert(target, asAlias, values, conflictAction, metas))
}

override fun visitStatementDMLBatchLegacyOpInsertLegacy(
node: Statement.DML.BatchLegacy.Op.InsertLegacy,
ctx: Ctx,
) = translate(node) {
val target = visitPathUnpack(node.target, ctx)
val values = visitExpr(node.value, ctx)
val index = node.index?.let { visitExpr(it, ctx) }
val onConflict = node.conflictCondition?.let {
val condition = visitExpr(it, ctx)
onConflict(condition, doNothing())
}
dmlOpList(insertValue(target, values, index, onConflict))
}

override fun visitOnConflict(node: OnConflict, ctx: Ctx) = translate(node) { metas ->
val action = visitOnConflictAction(node.action, ctx)
if (node.target == null) {
// Legacy PartiQLPifVisitor doesn't respect the return type for the OnConflict rule
// - visitOnConflictLegacy returns an OnConflict node
// - visitOnConflict returns an OnConflict.Action
// Essentially, the on_conflict target appears in the grammar but not the PIG model
// Which means you technically can't use the #OnConflict alternative in certain contexts.
// We generally shouldn't have parser rule alternatives which are not variants of the same type.
throw IllegalArgumentException("PIG OnConflict (#OnConflictLegacy grammar rule) requires an expression")
}
val expr = visitOnConflictTarget(node.target!!, ctx)
onConflict(expr, action, metas)
}

override fun visitOnConflictTarget(node: OnConflict.Target, ctx: Ctx) =
super.visitOnConflictTarget(node, ctx) as PartiqlAst.Expr

override fun visitOnConflictTargetSymbols(
node: OnConflict.Target.Symbols,
ctx: Ctx,
) = translate(node) { metas ->
val symbols = node.symbols.map {
if (it !is Identifier.Symbol) {
throw IllegalArgumentException("Legacy AST does not support qualified identifiers as index names")
}
lit(ionSymbol(it.symbol))
}
list(symbols, metas)
}

override fun visitOnConflictTargetConstraint(
node: OnConflict.Target.Constraint,
ctx: Ctx,
) = translate(node) { metas ->
if (node.constraint !is Identifier.Symbol) {
throw IllegalArgumentException("Legacy AST does not support qualified identifiers as a constraint name")
}
val constraint = (node.constraint as Identifier.Symbol).symbol
lit(ionSymbol(constraint), metas)
}

override fun visitOnConflictAction(node: OnConflict.Action, ctx: Ctx) =
super.visitOnConflictAction(node, ctx) as PartiqlAst.ConflictAction

override fun visitOnConflictActionDoReplace(
node: OnConflict.Action.DoReplace,
ctx: Ctx,
) = translate(node) { metas ->
val value = excluded()
val condition = node.condition?.let { visitExpr(it, ctx) }
doReplace(value, condition, metas)
}

override fun visitOnConflictActionDoUpdate(
node: OnConflict.Action.DoUpdate,
ctx: Ctx,
) = translate(node) { metas ->
val value = excluded()
val condition = node.condition?.let { visitExpr(it, ctx) }
doUpdate(value, condition, metas)
}

override fun visitOnConflictActionDoNothing(
node: OnConflict.Action.DoNothing,
ctx: Ctx,
) = translate(node) { metas ->
doNothing(metas)
}

override fun visitReturning(node: Returning, ctx: Ctx) = translate(node) { metas ->
val elems = node.columns.translate<PartiqlAst.ReturningElem>(ctx)
returningExpr(elems, metas)
}

override fun visitReturningColumn(node: Returning.Column, ctx: Ctx) = translate(node) {
// a fine example of `when` is `if`, not pattern matching
val mapping = when (node.status) {
Returning.Column.Status.MODIFIED -> when (node.age) {
Returning.Column.Age.OLD -> modifiedOld()
Returning.Column.Age.NEW -> modifiedNew()
}
Returning.Column.Status.ALL -> when (node.age) {
Returning.Column.Age.OLD -> allOld()
Returning.Column.Age.NEW -> allNew()
}
}
val column = visitReturningColumnValue(node.value, ctx)
returningElem(mapping, column)
}

override fun visitReturningColumnValue(node: Returning.Column.Value, ctx: Ctx) =
super.visitReturningColumnValue(node, ctx) as PartiqlAst.ColumnComponent

override fun visitReturningColumnValueWildcard(
node: Returning.Column.Value.Wildcard,
ctx: Ctx,
) = translate(node) {
returningWildcard()
}

override fun visitReturningColumnValueExpression(
node: Returning.Column.Value.Expression,
ctx: Ctx,
) = translate(node) {
val expr = visitExpr(node.expr, ctx)
returningColumn(expr)
}

/**
* TYPE
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ internal object NormalizeFromSource : AstPass {
// Each SFW starts the ctx count again.
override fun visitQueryBodySFW(node: QueryBody.SFW, ctx: Int): AstNode = super.visitQueryBodySFW(node, 0)

override fun visitStatementDMLBatchLegacy(node: Statement.DML.BatchLegacy, ctx: Int): AstNode =
super.visitStatementDMLBatchLegacy(node, 0)

override fun visitFrom(node: From, ctx: Int) = super.visitFrom(node, ctx) as From

override fun visitFromJoin(node: From.Join, ctx: Int): From {
Expand Down
Loading

0 comments on commit f6adc8e

Please sign in to comment.