From 1bb9b21d72388a6a91ca08140603c6b435def2ff Mon Sep 17 00:00:00 2001 From: Alan Cai Date: Thu, 31 Oct 2024 11:38:17 -0700 Subject: [PATCH] [v1] Add AstVisitor and AstRewriter; port partiql-ast normalization passes to partiql-planner --- partiql-ast/api/partiql-ast.api | 371 ++++++--- .../java/org/partiql/ast/v1/AstRewriter.kt | 752 ++++++++++++++++++ .../java/org/partiql/ast/v1/AstVisitor.java | 742 ++++++++++++----- .../java/org/partiql/ast/v1/ExcludeStep.java | 5 + .../java/org/partiql/ast/v1/FromTableRef.java | 15 +- .../main/java/org/partiql/ast/v1/Select.java | 19 +- .../java/org/partiql/ast/v1/SelectItem.java | 11 - .../java/org/partiql/ast/v1/Statement.java | 15 +- .../java/org/partiql/ast/v1/expr/Expr.java | 73 +- .../org/partiql/ast/v1/graph/GraphLabel.java | 17 - .../org/partiql/ast/v1/graph/GraphPart.java | 13 - .../partiql/ast/v1/graph/GraphPattern.java | 2 +- .../partiql/ast/v1/graph/GraphSelector.java | 19 - .../org/partiql/ast/helpers/ToBinder.kt | 2 + .../org/partiql/ast/normalize/AstPass.kt | 2 + .../org/partiql/ast/normalize/Normalize.kt | 2 + .../ast/normalize/NormalizeFromSource.kt | 2 + .../partiql/ast/normalize/NormalizeGroupBy.kt | 2 + .../planner/internal/helpers/ToBinder.kt | 82 ++ .../planner/internal/normalize/AstPass.kt | 24 + .../planner/internal/normalize/Normalize.kt | 29 + .../internal/normalize/NormalizeFromSource.kt | 76 ++ .../internal/normalize/NormalizeGroupBy.kt | 55 ++ .../internal/transforms/V1NormalizeSelect.kt | 393 +++++++++ .../transforms/NormalizeSelectTest.kt | 162 ++-- 25 files changed, 2345 insertions(+), 540 deletions(-) create mode 100644 partiql-ast/src/main/java/org/partiql/ast/v1/AstRewriter.kt create mode 100644 partiql-planner/src/main/kotlin/org/partiql/planner/internal/helpers/ToBinder.kt create mode 100644 partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/AstPass.kt create mode 100644 partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/Normalize.kt create mode 100644 partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/NormalizeFromSource.kt create mode 100644 partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/NormalizeGroupBy.kt create mode 100644 partiql-planner/src/main/kotlin/org/partiql/planner/internal/transforms/V1NormalizeSelect.kt diff --git a/partiql-ast/api/partiql-ast.api b/partiql-ast/api/partiql-ast.api index bf750b137c..2d141cfa97 100644 --- a/partiql-ast/api/partiql-ast.api +++ b/partiql-ast/api/partiql-ast.api @@ -5644,103 +5644,260 @@ public abstract class org/partiql/ast/v1/AstNode { public abstract fun children ()Ljava/util/Collection; } -public abstract interface class org/partiql/ast/v1/AstVisitor { - public abstract fun visit (Lorg/partiql/ast/v1/AstNode;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExclude (Lorg/partiql/ast/v1/Exclude;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExcludePath (Lorg/partiql/ast/v1/ExcludePath;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExcludeStep (Lorg/partiql/ast/v1/ExcludeStep;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExcludeStepCollIndex (Lorg/partiql/ast/v1/ExcludeStep$CollIndex;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExcludeStepCollWildcard (Lorg/partiql/ast/v1/ExcludeStep$CollWildcard;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExcludeStepStructField (Lorg/partiql/ast/v1/ExcludeStep$StructField;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExcludeStepStructWildcard (Lorg/partiql/ast/v1/ExcludeStep$StructWildcard;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExplain (Lorg/partiql/ast/v1/Explain;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExpr (Lorg/partiql/ast/v1/expr/Expr;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprAnd (Lorg/partiql/ast/v1/expr/ExprAnd;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprArray (Lorg/partiql/ast/v1/expr/ExprArray;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprBag (Lorg/partiql/ast/v1/expr/ExprBag;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprBetween (Lorg/partiql/ast/v1/expr/ExprBetween;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprCall (Lorg/partiql/ast/v1/expr/ExprCall;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprCase (Lorg/partiql/ast/v1/expr/ExprCase;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprCaseBranch (Lorg/partiql/ast/v1/expr/ExprCase$Branch;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprCast (Lorg/partiql/ast/v1/expr/ExprCast;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprCoalesce (Lorg/partiql/ast/v1/expr/ExprCoalesce;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprExtract (Lorg/partiql/ast/v1/expr/ExprExtract;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprInCollection (Lorg/partiql/ast/v1/expr/ExprInCollection;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprIsType (Lorg/partiql/ast/v1/expr/ExprIsType;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprLike (Lorg/partiql/ast/v1/expr/ExprLike;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprLit (Lorg/partiql/ast/v1/expr/ExprLit;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprMatch (Lorg/partiql/ast/v1/expr/ExprMatch;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprNot (Lorg/partiql/ast/v1/expr/ExprNot;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprNullIf (Lorg/partiql/ast/v1/expr/ExprNullIf;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprOperator (Lorg/partiql/ast/v1/expr/ExprOperator;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprOr (Lorg/partiql/ast/v1/expr/ExprOr;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprOverlay (Lorg/partiql/ast/v1/expr/ExprOverlay;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprParameter (Lorg/partiql/ast/v1/expr/ExprParameter;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprPath (Lorg/partiql/ast/v1/expr/ExprPath;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprPosition (Lorg/partiql/ast/v1/expr/ExprPosition;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprQuerySet (Lorg/partiql/ast/v1/expr/ExprQuerySet;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprSessionAttribute (Lorg/partiql/ast/v1/expr/ExprSessionAttribute;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprStruct (Lorg/partiql/ast/v1/expr/ExprStruct;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprStructField (Lorg/partiql/ast/v1/expr/ExprStruct$Field;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprSubstring (Lorg/partiql/ast/v1/expr/ExprSubstring;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprTrim (Lorg/partiql/ast/v1/expr/ExprTrim;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprValues (Lorg/partiql/ast/v1/expr/ExprValues;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprValuesRow (Lorg/partiql/ast/v1/expr/ExprValues$Row;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprVarRef (Lorg/partiql/ast/v1/expr/ExprVarRef;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprVariant (Lorg/partiql/ast/v1/expr/ExprVariant;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprWindow (Lorg/partiql/ast/v1/expr/ExprWindow;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitExprWindowOver (Lorg/partiql/ast/v1/expr/ExprWindow$Over;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitFrom (Lorg/partiql/ast/v1/From;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitFromExpr (Lorg/partiql/ast/v1/FromExpr;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitFromJoin (Lorg/partiql/ast/v1/FromJoin;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphLabel (Lorg/partiql/ast/v1/graph/GraphLabel;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphLabelConj (Lorg/partiql/ast/v1/graph/GraphLabel$Conj;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphLabelDisj (Lorg/partiql/ast/v1/graph/GraphLabel$Disj;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphLabelName (Lorg/partiql/ast/v1/graph/GraphLabel$Name;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphLabelNegation (Lorg/partiql/ast/v1/graph/GraphLabel$Negation;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphLabelWildcard (Lorg/partiql/ast/v1/graph/GraphLabel$Wildcard;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphMatch (Lorg/partiql/ast/v1/graph/GraphMatch;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphMatchPattern (Lorg/partiql/ast/v1/graph/GraphPattern;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphPart (Lorg/partiql/ast/v1/graph/GraphPart;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphPartEdge (Lorg/partiql/ast/v1/graph/GraphPart$Edge;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphPartNode (Lorg/partiql/ast/v1/graph/GraphPart$Node;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphPartPattern (Lorg/partiql/ast/v1/graph/GraphPart$Pattern;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphQuantifier (Lorg/partiql/ast/v1/graph/GraphQuantifier;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphSelector (Lorg/partiql/ast/v1/graph/GraphSelector;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphSelectorAllShortest (Lorg/partiql/ast/v1/graph/GraphSelector$AllShortest;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphSelectorAny (Lorg/partiql/ast/v1/graph/GraphSelector$Any;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphSelectorAnyK (Lorg/partiql/ast/v1/graph/GraphSelector$AnyK;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphSelectorAnyShortest (Lorg/partiql/ast/v1/graph/GraphSelector$AnyShortest;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphSelectorShortestK (Lorg/partiql/ast/v1/graph/GraphSelector$ShortestK;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGraphSelectorShortestKGroup (Lorg/partiql/ast/v1/graph/GraphSelector$ShortestKGroup;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGroupBy (Lorg/partiql/ast/v1/GroupBy;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitGroupByKey (Lorg/partiql/ast/v1/GroupBy$Key;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitIdentifier (Lorg/partiql/ast/v1/Identifier;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitIdentifierChain (Lorg/partiql/ast/v1/IdentifierChain;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitLet (Lorg/partiql/ast/v1/Let;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitLetBinding (Lorg/partiql/ast/v1/Let$Binding;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitOrderBy (Lorg/partiql/ast/v1/OrderBy;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitPathStep (Lorg/partiql/ast/v1/expr/PathStep;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitPathStepAllElements (Lorg/partiql/ast/v1/expr/PathStep$AllElements;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitPathStepAllFields (Lorg/partiql/ast/v1/expr/PathStep$AllFields;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitPathStepElement (Lorg/partiql/ast/v1/expr/PathStep$Element;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitPathStepField (Lorg/partiql/ast/v1/expr/PathStep$Field;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitQuery (Lorg/partiql/ast/v1/Query;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitQueryBody (Lorg/partiql/ast/v1/QueryBody;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitQueryBodySFW (Lorg/partiql/ast/v1/QueryBody$SFW;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitQueryBodySetOp (Lorg/partiql/ast/v1/QueryBody$SetOp;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitSelect (Lorg/partiql/ast/v1/Select;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitSelectItem (Lorg/partiql/ast/v1/SelectItem;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitSelectItemExpr (Lorg/partiql/ast/v1/SelectItem$Expr;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitSelectItemStar (Lorg/partiql/ast/v1/SelectItem$Star;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitSelectList (Lorg/partiql/ast/v1/SelectList;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitSelectPivot (Lorg/partiql/ast/v1/SelectPivot;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitSelectStar (Lorg/partiql/ast/v1/SelectStar;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitSelectValue (Lorg/partiql/ast/v1/SelectValue;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitSetOp (Lorg/partiql/ast/v1/SetOp;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitSort (Lorg/partiql/ast/v1/Sort;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitStatement (Lorg/partiql/ast/v1/Statement;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun visitTableRef (Lorg/partiql/ast/v1/FromTableRef;Ljava/lang/Object;)Ljava/lang/Object; +public abstract class org/partiql/ast/v1/AstRewriter : org/partiql/ast/v1/AstVisitor { + public fun ()V + public synthetic fun defaultReturn (Lorg/partiql/ast/v1/AstNode;Ljava/lang/Object;)Ljava/lang/Object; + public fun defaultReturn (Lorg/partiql/ast/v1/AstNode;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExclude (Lorg/partiql/ast/v1/Exclude;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExclude (Lorg/partiql/ast/v1/Exclude;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExcludePath (Lorg/partiql/ast/v1/ExcludePath;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludePath (Lorg/partiql/ast/v1/ExcludePath;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExcludeStepCollIndex (Lorg/partiql/ast/v1/ExcludeStep$CollIndex;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludeStepCollIndex (Lorg/partiql/ast/v1/ExcludeStep$CollIndex;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExcludeStepCollWildcard (Lorg/partiql/ast/v1/ExcludeStep$CollWildcard;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludeStepCollWildcard (Lorg/partiql/ast/v1/ExcludeStep$CollWildcard;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExcludeStepStructField (Lorg/partiql/ast/v1/ExcludeStep$StructField;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludeStepStructField (Lorg/partiql/ast/v1/ExcludeStep$StructField;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExcludeStepStructWildcard (Lorg/partiql/ast/v1/ExcludeStep$StructWildcard;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludeStepStructWildcard (Lorg/partiql/ast/v1/ExcludeStep$StructWildcard;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExplain (Lorg/partiql/ast/v1/Explain;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExplain (Lorg/partiql/ast/v1/Explain;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprAnd (Lorg/partiql/ast/v1/expr/ExprAnd;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprAnd (Lorg/partiql/ast/v1/expr/ExprAnd;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprArray (Lorg/partiql/ast/v1/expr/ExprArray;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprArray (Lorg/partiql/ast/v1/expr/ExprArray;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprBag (Lorg/partiql/ast/v1/expr/ExprBag;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprBag (Lorg/partiql/ast/v1/expr/ExprBag;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprBetween (Lorg/partiql/ast/v1/expr/ExprBetween;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprBetween (Lorg/partiql/ast/v1/expr/ExprBetween;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprCall (Lorg/partiql/ast/v1/expr/ExprCall;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprCall (Lorg/partiql/ast/v1/expr/ExprCall;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprCase (Lorg/partiql/ast/v1/expr/ExprCase;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprCase (Lorg/partiql/ast/v1/expr/ExprCase;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprCaseBranch (Lorg/partiql/ast/v1/expr/ExprCase$Branch;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprCaseBranch (Lorg/partiql/ast/v1/expr/ExprCase$Branch;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprCast (Lorg/partiql/ast/v1/expr/ExprCast;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprCast (Lorg/partiql/ast/v1/expr/ExprCast;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprCoalesce (Lorg/partiql/ast/v1/expr/ExprCoalesce;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprCoalesce (Lorg/partiql/ast/v1/expr/ExprCoalesce;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprExtract (Lorg/partiql/ast/v1/expr/ExprExtract;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprExtract (Lorg/partiql/ast/v1/expr/ExprExtract;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprInCollection (Lorg/partiql/ast/v1/expr/ExprInCollection;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprInCollection (Lorg/partiql/ast/v1/expr/ExprInCollection;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprIsType (Lorg/partiql/ast/v1/expr/ExprIsType;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprIsType (Lorg/partiql/ast/v1/expr/ExprIsType;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprLike (Lorg/partiql/ast/v1/expr/ExprLike;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprLike (Lorg/partiql/ast/v1/expr/ExprLike;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprLit (Lorg/partiql/ast/v1/expr/ExprLit;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprLit (Lorg/partiql/ast/v1/expr/ExprLit;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprMatch (Lorg/partiql/ast/v1/expr/ExprMatch;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprMatch (Lorg/partiql/ast/v1/expr/ExprMatch;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprNot (Lorg/partiql/ast/v1/expr/ExprNot;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprNot (Lorg/partiql/ast/v1/expr/ExprNot;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprNullIf (Lorg/partiql/ast/v1/expr/ExprNullIf;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprNullIf (Lorg/partiql/ast/v1/expr/ExprNullIf;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprOperator (Lorg/partiql/ast/v1/expr/ExprOperator;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprOperator (Lorg/partiql/ast/v1/expr/ExprOperator;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprOr (Lorg/partiql/ast/v1/expr/ExprOr;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprOr (Lorg/partiql/ast/v1/expr/ExprOr;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprOverlay (Lorg/partiql/ast/v1/expr/ExprOverlay;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprOverlay (Lorg/partiql/ast/v1/expr/ExprOverlay;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprParameter (Lorg/partiql/ast/v1/expr/ExprParameter;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprParameter (Lorg/partiql/ast/v1/expr/ExprParameter;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprPath (Lorg/partiql/ast/v1/expr/ExprPath;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprPath (Lorg/partiql/ast/v1/expr/ExprPath;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprPosition (Lorg/partiql/ast/v1/expr/ExprPosition;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprPosition (Lorg/partiql/ast/v1/expr/ExprPosition;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprQuerySet (Lorg/partiql/ast/v1/expr/ExprQuerySet;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprQuerySet (Lorg/partiql/ast/v1/expr/ExprQuerySet;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprSessionAttribute (Lorg/partiql/ast/v1/expr/ExprSessionAttribute;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprSessionAttribute (Lorg/partiql/ast/v1/expr/ExprSessionAttribute;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprStruct (Lorg/partiql/ast/v1/expr/ExprStruct;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprStruct (Lorg/partiql/ast/v1/expr/ExprStruct;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprStructField (Lorg/partiql/ast/v1/expr/ExprStruct$Field;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprStructField (Lorg/partiql/ast/v1/expr/ExprStruct$Field;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprSubstring (Lorg/partiql/ast/v1/expr/ExprSubstring;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprSubstring (Lorg/partiql/ast/v1/expr/ExprSubstring;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprTrim (Lorg/partiql/ast/v1/expr/ExprTrim;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprTrim (Lorg/partiql/ast/v1/expr/ExprTrim;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprValues (Lorg/partiql/ast/v1/expr/ExprValues;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprValues (Lorg/partiql/ast/v1/expr/ExprValues;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprValuesRow (Lorg/partiql/ast/v1/expr/ExprValues$Row;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprValuesRow (Lorg/partiql/ast/v1/expr/ExprValues$Row;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprVarRef (Lorg/partiql/ast/v1/expr/ExprVarRef;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprVarRef (Lorg/partiql/ast/v1/expr/ExprVarRef;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprVariant (Lorg/partiql/ast/v1/expr/ExprVariant;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprVariant (Lorg/partiql/ast/v1/expr/ExprVariant;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprWindow (Lorg/partiql/ast/v1/expr/ExprWindow;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprWindow (Lorg/partiql/ast/v1/expr/ExprWindow;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitExprWindowOver (Lorg/partiql/ast/v1/expr/ExprWindow$Over;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprWindowOver (Lorg/partiql/ast/v1/expr/ExprWindow$Over;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitFrom (Lorg/partiql/ast/v1/From;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitFrom (Lorg/partiql/ast/v1/From;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitFromExpr (Lorg/partiql/ast/v1/FromExpr;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitFromExpr (Lorg/partiql/ast/v1/FromExpr;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitFromJoin (Lorg/partiql/ast/v1/FromJoin;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitFromJoin (Lorg/partiql/ast/v1/FromJoin;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGraphMatch (Lorg/partiql/ast/v1/graph/GraphMatch;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphMatch (Lorg/partiql/ast/v1/graph/GraphMatch;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGraphPattern (Lorg/partiql/ast/v1/graph/GraphPattern;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphPattern (Lorg/partiql/ast/v1/graph/GraphPattern;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGraphQuantifier (Lorg/partiql/ast/v1/graph/GraphQuantifier;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphQuantifier (Lorg/partiql/ast/v1/graph/GraphQuantifier;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGraphSelectorAllShortest (Lorg/partiql/ast/v1/graph/GraphSelector$AllShortest;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorAllShortest (Lorg/partiql/ast/v1/graph/GraphSelector$AllShortest;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGraphSelectorAny (Lorg/partiql/ast/v1/graph/GraphSelector$Any;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorAny (Lorg/partiql/ast/v1/graph/GraphSelector$Any;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGraphSelectorAnyK (Lorg/partiql/ast/v1/graph/GraphSelector$AnyK;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorAnyK (Lorg/partiql/ast/v1/graph/GraphSelector$AnyK;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGraphSelectorAnyShortest (Lorg/partiql/ast/v1/graph/GraphSelector$AnyShortest;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorAnyShortest (Lorg/partiql/ast/v1/graph/GraphSelector$AnyShortest;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGraphSelectorShortestK (Lorg/partiql/ast/v1/graph/GraphSelector$ShortestK;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorShortestK (Lorg/partiql/ast/v1/graph/GraphSelector$ShortestK;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGraphSelectorShortestKGroup (Lorg/partiql/ast/v1/graph/GraphSelector$ShortestKGroup;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorShortestKGroup (Lorg/partiql/ast/v1/graph/GraphSelector$ShortestKGroup;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGroupBy (Lorg/partiql/ast/v1/GroupBy;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGroupBy (Lorg/partiql/ast/v1/GroupBy;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitGroupByKey (Lorg/partiql/ast/v1/GroupBy$Key;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGroupByKey (Lorg/partiql/ast/v1/GroupBy$Key;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitIdentifier (Lorg/partiql/ast/v1/Identifier;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitIdentifier (Lorg/partiql/ast/v1/Identifier;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitIdentifierChain (Lorg/partiql/ast/v1/IdentifierChain;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitIdentifierChain (Lorg/partiql/ast/v1/IdentifierChain;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitLet (Lorg/partiql/ast/v1/Let;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitLet (Lorg/partiql/ast/v1/Let;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitLetBinding (Lorg/partiql/ast/v1/Let$Binding;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitLetBinding (Lorg/partiql/ast/v1/Let$Binding;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitPathStepAllElements (Lorg/partiql/ast/v1/expr/PathStep$AllElements;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitPathStepAllElements (Lorg/partiql/ast/v1/expr/PathStep$AllElements;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitPathStepAllFields (Lorg/partiql/ast/v1/expr/PathStep$AllFields;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitPathStepAllFields (Lorg/partiql/ast/v1/expr/PathStep$AllFields;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitPathStepElement (Lorg/partiql/ast/v1/expr/PathStep$Element;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitPathStepElement (Lorg/partiql/ast/v1/expr/PathStep$Element;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitPathStepField (Lorg/partiql/ast/v1/expr/PathStep$Field;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitPathStepField (Lorg/partiql/ast/v1/expr/PathStep$Field;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitQuery (Lorg/partiql/ast/v1/Query;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitQuery (Lorg/partiql/ast/v1/Query;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitQueryBodySFW (Lorg/partiql/ast/v1/QueryBody$SFW;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitQueryBodySFW (Lorg/partiql/ast/v1/QueryBody$SFW;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitQueryBodySetOp (Lorg/partiql/ast/v1/QueryBody$SetOp;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitQueryBodySetOp (Lorg/partiql/ast/v1/QueryBody$SetOp;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitSelectItemExpr (Lorg/partiql/ast/v1/SelectItem$Expr;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectItemExpr (Lorg/partiql/ast/v1/SelectItem$Expr;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitSelectItemStar (Lorg/partiql/ast/v1/SelectItem$Star;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectItemStar (Lorg/partiql/ast/v1/SelectItem$Star;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitSelectList (Lorg/partiql/ast/v1/SelectList;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectList (Lorg/partiql/ast/v1/SelectList;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitSelectPivot (Lorg/partiql/ast/v1/SelectPivot;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectPivot (Lorg/partiql/ast/v1/SelectPivot;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitSelectStar (Lorg/partiql/ast/v1/SelectStar;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectStar (Lorg/partiql/ast/v1/SelectStar;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitSelectValue (Lorg/partiql/ast/v1/SelectValue;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectValue (Lorg/partiql/ast/v1/SelectValue;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; + public synthetic fun visitSetOp (Lorg/partiql/ast/v1/SetOp;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSetOp (Lorg/partiql/ast/v1/SetOp;Ljava/lang/Object;)Lorg/partiql/ast/v1/AstNode; +} + +public abstract class org/partiql/ast/v1/AstVisitor { + public fun ()V + public abstract fun defaultReturn (Lorg/partiql/ast/v1/AstNode;Ljava/lang/Object;)Ljava/lang/Object; + public fun defaultVisit (Lorg/partiql/ast/v1/AstNode;Ljava/lang/Object;)Ljava/lang/Object; + public fun visit (Lorg/partiql/ast/v1/AstNode;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExclude (Lorg/partiql/ast/v1/Exclude;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludePath (Lorg/partiql/ast/v1/ExcludePath;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludeStep (Lorg/partiql/ast/v1/ExcludeStep;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludeStepCollIndex (Lorg/partiql/ast/v1/ExcludeStep$CollIndex;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludeStepCollWildcard (Lorg/partiql/ast/v1/ExcludeStep$CollWildcard;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludeStepStructField (Lorg/partiql/ast/v1/ExcludeStep$StructField;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExcludeStepStructWildcard (Lorg/partiql/ast/v1/ExcludeStep$StructWildcard;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExplain (Lorg/partiql/ast/v1/Explain;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExpr (Lorg/partiql/ast/v1/expr/Expr;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprAnd (Lorg/partiql/ast/v1/expr/ExprAnd;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprArray (Lorg/partiql/ast/v1/expr/ExprArray;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprBag (Lorg/partiql/ast/v1/expr/ExprBag;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprBetween (Lorg/partiql/ast/v1/expr/ExprBetween;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprCall (Lorg/partiql/ast/v1/expr/ExprCall;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprCase (Lorg/partiql/ast/v1/expr/ExprCase;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprCaseBranch (Lorg/partiql/ast/v1/expr/ExprCase$Branch;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprCast (Lorg/partiql/ast/v1/expr/ExprCast;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprCoalesce (Lorg/partiql/ast/v1/expr/ExprCoalesce;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprExtract (Lorg/partiql/ast/v1/expr/ExprExtract;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprInCollection (Lorg/partiql/ast/v1/expr/ExprInCollection;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprIsType (Lorg/partiql/ast/v1/expr/ExprIsType;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprLike (Lorg/partiql/ast/v1/expr/ExprLike;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprLit (Lorg/partiql/ast/v1/expr/ExprLit;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprMatch (Lorg/partiql/ast/v1/expr/ExprMatch;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprNot (Lorg/partiql/ast/v1/expr/ExprNot;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprNullIf (Lorg/partiql/ast/v1/expr/ExprNullIf;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprOperator (Lorg/partiql/ast/v1/expr/ExprOperator;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprOr (Lorg/partiql/ast/v1/expr/ExprOr;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprOverlay (Lorg/partiql/ast/v1/expr/ExprOverlay;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprParameter (Lorg/partiql/ast/v1/expr/ExprParameter;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprPath (Lorg/partiql/ast/v1/expr/ExprPath;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprPosition (Lorg/partiql/ast/v1/expr/ExprPosition;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprQuerySet (Lorg/partiql/ast/v1/expr/ExprQuerySet;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprSessionAttribute (Lorg/partiql/ast/v1/expr/ExprSessionAttribute;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprStruct (Lorg/partiql/ast/v1/expr/ExprStruct;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprStructField (Lorg/partiql/ast/v1/expr/ExprStruct$Field;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprSubstring (Lorg/partiql/ast/v1/expr/ExprSubstring;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprTrim (Lorg/partiql/ast/v1/expr/ExprTrim;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprValues (Lorg/partiql/ast/v1/expr/ExprValues;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprValuesRow (Lorg/partiql/ast/v1/expr/ExprValues$Row;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprVarRef (Lorg/partiql/ast/v1/expr/ExprVarRef;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprVariant (Lorg/partiql/ast/v1/expr/ExprVariant;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprWindow (Lorg/partiql/ast/v1/expr/ExprWindow;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitExprWindowOver (Lorg/partiql/ast/v1/expr/ExprWindow$Over;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitFrom (Lorg/partiql/ast/v1/From;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitFromExpr (Lorg/partiql/ast/v1/FromExpr;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitFromJoin (Lorg/partiql/ast/v1/FromJoin;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitFromTableRef (Lorg/partiql/ast/v1/FromTableRef;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphLabel (Lorg/partiql/ast/v1/graph/GraphLabel;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphLabelConj (Lorg/partiql/ast/v1/graph/GraphLabel$Conj;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphLabelDisj (Lorg/partiql/ast/v1/graph/GraphLabel$Disj;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphLabelName (Lorg/partiql/ast/v1/graph/GraphLabel$Name;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphLabelNegation (Lorg/partiql/ast/v1/graph/GraphLabel$Negation;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphLabelWildcard (Lorg/partiql/ast/v1/graph/GraphLabel$Wildcard;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphMatch (Lorg/partiql/ast/v1/graph/GraphMatch;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphPart (Lorg/partiql/ast/v1/graph/GraphPart;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphPartEdge (Lorg/partiql/ast/v1/graph/GraphPart$Edge;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphPartNode (Lorg/partiql/ast/v1/graph/GraphPart$Node;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphPartPattern (Lorg/partiql/ast/v1/graph/GraphPart$Pattern;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphPattern (Lorg/partiql/ast/v1/graph/GraphPattern;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphQuantifier (Lorg/partiql/ast/v1/graph/GraphQuantifier;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelector (Lorg/partiql/ast/v1/graph/GraphSelector;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorAllShortest (Lorg/partiql/ast/v1/graph/GraphSelector$AllShortest;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorAny (Lorg/partiql/ast/v1/graph/GraphSelector$Any;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorAnyK (Lorg/partiql/ast/v1/graph/GraphSelector$AnyK;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorAnyShortest (Lorg/partiql/ast/v1/graph/GraphSelector$AnyShortest;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorShortestK (Lorg/partiql/ast/v1/graph/GraphSelector$ShortestK;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGraphSelectorShortestKGroup (Lorg/partiql/ast/v1/graph/GraphSelector$ShortestKGroup;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGroupBy (Lorg/partiql/ast/v1/GroupBy;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitGroupByKey (Lorg/partiql/ast/v1/GroupBy$Key;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitIdentifier (Lorg/partiql/ast/v1/Identifier;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitIdentifierChain (Lorg/partiql/ast/v1/IdentifierChain;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitLet (Lorg/partiql/ast/v1/Let;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitLetBinding (Lorg/partiql/ast/v1/Let$Binding;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitOrderBy (Lorg/partiql/ast/v1/OrderBy;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitPathStep (Lorg/partiql/ast/v1/expr/PathStep;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitPathStepAllElements (Lorg/partiql/ast/v1/expr/PathStep$AllElements;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitPathStepAllFields (Lorg/partiql/ast/v1/expr/PathStep$AllFields;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitPathStepElement (Lorg/partiql/ast/v1/expr/PathStep$Element;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitPathStepField (Lorg/partiql/ast/v1/expr/PathStep$Field;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitQuery (Lorg/partiql/ast/v1/Query;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitQueryBody (Lorg/partiql/ast/v1/QueryBody;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitQueryBodySFW (Lorg/partiql/ast/v1/QueryBody$SFW;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitQueryBodySetOp (Lorg/partiql/ast/v1/QueryBody$SetOp;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelect (Lorg/partiql/ast/v1/Select;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectItem (Lorg/partiql/ast/v1/SelectItem;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectItemExpr (Lorg/partiql/ast/v1/SelectItem$Expr;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectItemStar (Lorg/partiql/ast/v1/SelectItem$Star;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectList (Lorg/partiql/ast/v1/SelectList;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectPivot (Lorg/partiql/ast/v1/SelectPivot;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectStar (Lorg/partiql/ast/v1/SelectStar;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSelectValue (Lorg/partiql/ast/v1/SelectValue;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSetOp (Lorg/partiql/ast/v1/SetOp;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitSort (Lorg/partiql/ast/v1/Sort;Ljava/lang/Object;)Ljava/lang/Object; + public fun visitStatement (Lorg/partiql/ast/v1/Statement;Ljava/lang/Object;)Ljava/lang/Object; } public class org/partiql/ast/v1/DataType : org/partiql/ast/v1/AstEnum { @@ -5955,7 +6112,10 @@ public class org/partiql/ast/v1/ExcludeStep$CollIndex : org/partiql/ast/v1/Exclu public fun (I)V public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; public static fun builder ()Lorg/partiql/ast/v1/ExcludeStep$CollIndex$Builder; + protected fun canEqual (Ljava/lang/Object;)Z public fun children ()Ljava/util/Collection; + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I } public class org/partiql/ast/v1/ExcludeStep$CollIndex$Builder { @@ -5967,7 +6127,10 @@ public class org/partiql/ast/v1/ExcludeStep$CollIndex$Builder { public class org/partiql/ast/v1/ExcludeStep$CollWildcard : org/partiql/ast/v1/ExcludeStep { public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; public static fun builder ()Lorg/partiql/ast/v1/ExcludeStep$CollWildcard$Builder; + protected fun canEqual (Ljava/lang/Object;)Z public fun children ()Ljava/util/Collection; + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I } public class org/partiql/ast/v1/ExcludeStep$CollWildcard$Builder { @@ -5980,7 +6143,10 @@ public class org/partiql/ast/v1/ExcludeStep$StructField : org/partiql/ast/v1/Exc public fun (Lorg/partiql/ast/v1/Identifier;)V public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; public static fun builder ()Lorg/partiql/ast/v1/ExcludeStep$StructField$Builder; + protected fun canEqual (Ljava/lang/Object;)Z public fun children ()Ljava/util/Collection; + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I } public class org/partiql/ast/v1/ExcludeStep$StructField$Builder { @@ -5992,7 +6158,10 @@ public class org/partiql/ast/v1/ExcludeStep$StructField$Builder { public class org/partiql/ast/v1/ExcludeStep$StructWildcard : org/partiql/ast/v1/ExcludeStep { public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; public static fun builder ()Lorg/partiql/ast/v1/ExcludeStep$StructWildcard$Builder; + protected fun canEqual (Ljava/lang/Object;)Z public fun children ()Ljava/util/Collection; + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I } public class org/partiql/ast/v1/ExcludeStep$StructWildcard$Builder { @@ -6084,7 +6253,6 @@ public class org/partiql/ast/v1/FromJoin$Builder { public abstract class org/partiql/ast/v1/FromTableRef : org/partiql/ast/v1/AstNode { public fun ()V - public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; } public class org/partiql/ast/v1/FromType : org/partiql/ast/v1/AstEnum { @@ -6391,12 +6559,10 @@ public class org/partiql/ast/v1/QueryBody$SetOp$Builder { public abstract class org/partiql/ast/v1/Select : org/partiql/ast/v1/AstNode { public fun ()V - public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; } public abstract class org/partiql/ast/v1/SelectItem : org/partiql/ast/v1/AstNode { public fun ()V - public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; } public class org/partiql/ast/v1/SelectItem$Expr : org/partiql/ast/v1/SelectItem { @@ -6589,12 +6755,10 @@ public class org/partiql/ast/v1/Sort$Builder { public abstract class org/partiql/ast/v1/Statement : org/partiql/ast/v1/AstNode { public fun ()V - public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; } public abstract class org/partiql/ast/v1/expr/Expr : org/partiql/ast/v1/AstNode { public fun ()V - public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; } public class org/partiql/ast/v1/expr/ExprAnd : org/partiql/ast/v1/expr/Expr { @@ -7428,7 +7592,6 @@ public class org/partiql/ast/v1/graph/GraphDirection : org/partiql/ast/v1/AstEnu public abstract class org/partiql/ast/v1/graph/GraphLabel : org/partiql/ast/v1/AstNode { public fun ()V - public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; } public class org/partiql/ast/v1/graph/GraphLabel$Conj : org/partiql/ast/v1/graph/GraphLabel { @@ -7539,7 +7702,6 @@ public class org/partiql/ast/v1/graph/GraphMatch$Builder { public abstract class org/partiql/ast/v1/graph/GraphPart : org/partiql/ast/v1/AstNode { public fun ()V - public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; } public class org/partiql/ast/v1/graph/GraphPart$Edge : org/partiql/ast/v1/graph/GraphPart { @@ -7671,7 +7833,6 @@ public class org/partiql/ast/v1/graph/GraphRestrictor : org/partiql/ast/v1/AstEn public abstract class org/partiql/ast/v1/graph/GraphSelector : org/partiql/ast/v1/AstNode { public fun ()V - public fun accept (Lorg/partiql/ast/v1/AstVisitor;Ljava/lang/Object;)Ljava/lang/Object; } public class org/partiql/ast/v1/graph/GraphSelector$AllShortest : org/partiql/ast/v1/graph/GraphSelector { diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/AstRewriter.kt b/partiql-ast/src/main/java/org/partiql/ast/v1/AstRewriter.kt new file mode 100644 index 0000000000..6dfc415f15 --- /dev/null +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/AstRewriter.kt @@ -0,0 +1,752 @@ +package org.partiql.ast.v1 + +import org.partiql.ast.v1.Ast.explain +import org.partiql.ast.v1.Ast.exprQuerySet +import org.partiql.ast.v1.Ast.identifier +import org.partiql.ast.v1.Ast.query +import org.partiql.ast.v1.expr.Expr +import org.partiql.ast.v1.expr.ExprAnd +import org.partiql.ast.v1.expr.ExprArray +import org.partiql.ast.v1.expr.ExprBag +import org.partiql.ast.v1.expr.ExprBetween +import org.partiql.ast.v1.expr.ExprCall +import org.partiql.ast.v1.expr.ExprCase +import org.partiql.ast.v1.expr.ExprCast +import org.partiql.ast.v1.expr.ExprCoalesce +import org.partiql.ast.v1.expr.ExprExtract +import org.partiql.ast.v1.expr.ExprInCollection +import org.partiql.ast.v1.expr.ExprIsType +import org.partiql.ast.v1.expr.ExprLike +import org.partiql.ast.v1.expr.ExprLit +import org.partiql.ast.v1.expr.ExprMatch +import org.partiql.ast.v1.expr.ExprNot +import org.partiql.ast.v1.expr.ExprNullIf +import org.partiql.ast.v1.expr.ExprOperator +import org.partiql.ast.v1.expr.ExprOr +import org.partiql.ast.v1.expr.ExprOverlay +import org.partiql.ast.v1.expr.ExprParameter +import org.partiql.ast.v1.expr.ExprPath +import org.partiql.ast.v1.expr.ExprPosition +import org.partiql.ast.v1.expr.ExprQuerySet +import org.partiql.ast.v1.expr.ExprSessionAttribute +import org.partiql.ast.v1.expr.ExprStruct +import org.partiql.ast.v1.expr.ExprSubstring +import org.partiql.ast.v1.expr.ExprTrim +import org.partiql.ast.v1.expr.ExprValues +import org.partiql.ast.v1.expr.ExprVarRef +import org.partiql.ast.v1.expr.ExprVariant +import org.partiql.ast.v1.expr.ExprWindow +import org.partiql.ast.v1.expr.PathStep +import org.partiql.ast.v1.graph.GraphMatch +import org.partiql.ast.v1.graph.GraphPattern +import org.partiql.ast.v1.graph.GraphQuantifier +import org.partiql.ast.v1.graph.GraphSelector +import org.partiql.value.PartiQLValueExperimental + +public abstract class AstRewriter : AstVisitor() { + override fun defaultReturn(node: AstNode, context: C): AstNode = node + + private inline fun _visitList( + nodes: List, + ctx: C, + method: (node: T, ctx: C) -> AstNode, + ): List { + if (nodes.isEmpty()) return nodes + var diff = false + val transformed = ArrayList(nodes.size) + nodes.forEach { + val n = method(it, ctx) as T + if (it !== n) diff = true + transformed.add(n) + } + return if (diff) transformed else nodes + } + + // expr + override fun visitExprAnd(node: ExprAnd, ctx: C): AstNode { + val lhs = visitExpr(node.lhs, ctx) as Expr + val rhs = visitExpr(node.rhs, ctx) as Expr + return if (lhs !== node.lhs || rhs !== node.rhs) { + ExprAnd(lhs, rhs) + } else { + node + } + } + + override fun visitExprArray(node: ExprArray, ctx: C): AstNode { + val values = _visitList(node.values, ctx, ::visitExpr) + return if (values !== node.values) { + ExprArray(values) + } else { + node + } + } + + override fun visitExprBag(node: ExprBag, ctx: C): AstNode { + val values = _visitList(node.values, ctx, ::visitExpr) + return if (values !== node.values) { + ExprBag(values) + } else { + node + } + } + + override fun visitExprBetween(node: ExprBetween, ctx: C): AstNode { + val value = visitExpr(node.value, ctx) as Expr + val from = visitExpr(node.from, ctx) as Expr + val to = visitExpr(node.to, ctx) as Expr + val not = node.not + return if (value !== node.value || from !== node.from || to !== node.to || not != node.not) { + ExprBetween(value, from, to, not) + } else { + node + } + } + + override fun visitExprCall(node: ExprCall, ctx: C): AstNode { + val function = visitIdentifierChain(node.function, ctx) as IdentifierChain + val args = _visitList(node.args, ctx, ::visitExpr) + val setq = node.setq + return if (function !== node.function || args !== node.args || setq !== node.setq) { + ExprCall(function, args, setq) + } else { + node + } + } + + override fun visitExprCase(node: ExprCase, ctx: C): AstNode { + val expr = node.expr?.let { visitExpr(it, ctx) as Expr? } + val branches = _visitList(node.branches, ctx, ::visitExprCaseBranch) + val defaultExpr = node.defaultExpr?.let { visitExpr(it, ctx) as Expr? } + return if (expr !== node.expr || branches !== node.branches || defaultExpr !== node.defaultExpr) { + ExprCase(expr, branches, defaultExpr) + } else { + node + } + } + + override fun visitExprCaseBranch(node: ExprCase.Branch, ctx: C): AstNode { + val condition = visitExpr(node.condition, ctx) as Expr + val expr = visitExpr(node.expr, ctx) as Expr + return if (condition !== node.condition || expr !== node.expr) { + ExprCase.Branch(condition, expr) + } else { + node + } + } + + override fun visitExprCast(node: ExprCast, ctx: C): AstNode { + val value = visitExpr(node.value, ctx) as Expr + val type = node.asType + return if (value !== node.value || type !== node.asType) { + ExprCast(value, type) + } else { + node + } + } + + override fun visitExprCoalesce(node: ExprCoalesce, ctx: C): AstNode { + val args = _visitList(node.args, ctx, ::visitExpr) + return if (args !== node.args) { + ExprCoalesce(args) + } else { + node + } + } + + override fun visitExprExtract(node: ExprExtract, ctx: C): AstNode { + val field = node.field + val source = visitExpr(node.source, ctx) as Expr + return if (field !== node.field || source !== node.source) { + ExprExtract(field, source) + } else { + node + } + } + + override fun visitExprInCollection(node: ExprInCollection, ctx: C): AstNode { + val lhs = visitExpr(node.lhs, ctx) as Expr + val rhs = visitExpr(node.rhs, ctx) as Expr + val not = node.not + return if (lhs !== node.lhs || rhs !== node.rhs || not != node.not) { + ExprInCollection(lhs, rhs, not) + } else { + node + } + } + + override fun visitExprIsType(node: ExprIsType, ctx: C): AstNode { + val value = visitExpr(node.value, ctx) as Expr + val type = node.type + val not = node.not + return if (value !== node.value || type !== node.type || not != node.not) { + ExprIsType(value, type, not) + } else { + node + } + } + + override fun visitExprLike(node: ExprLike, ctx: C): AstNode { + val value = visitExpr(node.value, ctx) as Expr + val pattern = visitExpr(node.pattern, ctx) as Expr + val escape = node.escape?.let { visitExpr(it, ctx) as Expr? } + val not = node.not + return if (value !== node.value || pattern !== node.pattern || escape !== node.escape || not != node.not) { + ExprLike(value, pattern, escape, not) + } else { + node + } + } + + @OptIn(PartiQLValueExperimental::class) + override fun visitExprLit(node: ExprLit, ctx: C): AstNode { + val value = node.value + return node + } + + override fun visitExprMatch(node: ExprMatch, ctx: C): AstNode { + val expr = visitExpr(node.expr, ctx) as Expr + val pattern = visitGraphMatch(node.pattern, ctx) as GraphMatch + return if (expr !== node.expr || pattern !== node.pattern) { + ExprMatch(expr, pattern) + } else { + node + } + } + + override fun visitExprNot(node: ExprNot, ctx: C): AstNode { + val expr = visitExpr(node.value, ctx) as Expr + return if (expr !== node.value) { + ExprNot(expr) + } else { + node + } + } + + override fun visitExprNullIf(node: ExprNullIf, ctx: C): AstNode { + val v1 = visitExpr(node.v1, ctx) as Expr + val v2 = visitExpr(node.v2, ctx) as Expr + return if (v1 !== node.v1 || v2 !== node.v2) { + ExprNullIf(v1, v2) + } else { + node + } + } + + override fun visitExprOperator(node: ExprOperator, ctx: C): AstNode { + val symbol = node.symbol + val lhs = node.lhs?.let { visitExpr(it, ctx) as Expr? } + val rhs = visitExpr(node.rhs, ctx) as Expr + return if (symbol !== node.symbol || lhs !== node.lhs || rhs !== node.rhs) { + ExprOperator(symbol, lhs, rhs) + } else { + node + } + } + + override fun visitExprOr(node: ExprOr, ctx: C): AstNode { + val lhs = visitExpr(node.lhs, ctx) as Expr + val rhs = visitExpr(node.rhs, ctx) as Expr + return if (lhs !== node.lhs || rhs !== node.rhs) { + ExprOr(lhs, rhs) + } else { + node + } + } + + override fun visitExprOverlay(node: ExprOverlay, ctx: C): AstNode { + val value = visitExpr(node.value, ctx) as Expr + val overlay = visitExpr(node.placing, ctx) as Expr + val from = visitExpr(node.from, ctx) as Expr + val forLength = node.forLength?.let { visitExpr(it, ctx) as Expr? } + return if (value !== node.value || overlay !== node.placing || from !== node.from || forLength !== node.forLength) { + ExprOverlay(value, overlay, from, forLength) + } else { + node + } + } + + override fun visitExprParameter(node: ExprParameter, ctx: C): AstNode { + val index = node.index + return node + } + + override fun visitExprPath(node: ExprPath, ctx: C): AstNode { + val root = visitExpr(node.root, ctx) as Expr + val next = node.next?.let { visitPathStep(it, ctx) as PathStep? } + return if (root !== node.root || next !== node.next) { + ExprPath(root, next) + } else { + node + } + } + + override fun visitExprPosition(node: ExprPosition, ctx: C): AstNode { + val lhs = visitExpr(node.lhs, ctx) as Expr + val rhs = visitExpr(node.rhs, ctx) as Expr + return if (lhs !== node.lhs || rhs !== node.rhs) { + ExprPosition(lhs, rhs) + } else { + node + } + } + + override fun visitExprQuerySet(node: ExprQuerySet, ctx: C): AstNode { + val body = node.body.let { visitQueryBody(it, ctx) as QueryBody } + val orderBy = node.orderBy?.let { visitOrderBy(it, ctx) as OrderBy? } + val limit = node.limit?.let { visitExpr(it, ctx) as Expr? } + val offset = node.offset?.let { visitExpr(it, ctx) as Expr? } + return if (body !== node.body || orderBy !== node.orderBy || limit !== node.limit || offset !== + node.offset + ) { + exprQuerySet(body, orderBy, limit, offset) + } else { + node + } + } + + override fun visitExprSessionAttribute(node: ExprSessionAttribute, ctx: C): AstNode { + val sessionAttribute = node.sessionAttribute + return node + } + + override fun visitExprStruct(node: ExprStruct, ctx: C): AstNode { + val fields = _visitList(node.fields, ctx, ::visitExprStructField) + return if (fields !== node.fields) { + ExprStruct(fields) + } else { + node + } + } + + override fun visitExprStructField(node: ExprStruct.Field, ctx: C): AstNode { + val name = visitExpr(node.name, ctx) as Expr + val value = visitExpr(node.value, ctx) as Expr + return if (name !== node.name || value !== node.value) { + ExprStruct.Field(name, value) + } else { + node + } + } + + override fun visitExprSubstring(node: ExprSubstring, ctx: C): AstNode { + val value = visitExpr(node.value, ctx) as Expr + val start = node.start?.let { visitExpr(it, ctx) as Expr? } + val length = node.length?.let { visitExpr(it, ctx) as Expr? } + return if (value !== node.value || start !== node.start || length !== node.length) { + ExprSubstring(value, start, length) + } else { + node + } + } + + override fun visitExprTrim(node: ExprTrim, ctx: C): AstNode { + val value = visitExpr(node.value, ctx) as Expr + val chars = node.chars?.let { visitExpr(it, ctx) as Expr? } + val trimSpec = node.trimSpec + return if (value !== node.value || chars !== node.chars || trimSpec !== node.trimSpec) { + ExprTrim(value, chars, trimSpec) + } else { + node + } + } + + override fun visitExprValues(node: ExprValues, ctx: C): AstNode { + val values = _visitList(node.rows, ctx, ::visitExprValuesRow) + return if (values !== node.rows) { + ExprValues(values) + } else { + node + } + } + + override fun visitExprValuesRow(node: ExprValues.Row, ctx: C): AstNode { + val values = _visitList(node.values, ctx, ::visitExpr) + return if (values !== node.values) { + ExprValues.Row(values) + } else { + node + } + } + + override fun visitExprVariant(node: ExprVariant, ctx: C): AstNode { + val value = node.value + val encoding = node.encoding + return node + } + + override fun visitExprVarRef(node: ExprVarRef, ctx: C): AstNode { + val identifierChain = visitIdentifierChain(node.identifierChain, ctx) as IdentifierChain + val scope = node.scope + return if (identifierChain !== node.identifierChain || scope !== node.scope) { + ExprVarRef(identifierChain, scope) + } else { + node + } + } + + override fun visitExprWindow(node: ExprWindow, ctx: C): AstNode { + val windowFunction = node.windowFunction + val expression = visitExpr(node.expression, ctx) as Expr + val offset = node.offset?.let { visitExpr(it, ctx) as Expr? } + val defaultValue = node.defaultValue?.let { visitExpr(it, ctx) as Expr? } + val over = visitExprWindowOver(node.over, ctx) as ExprWindow.Over + return if (windowFunction !== node.windowFunction || expression !== node.expression || offset !== + node.offset || defaultValue !== node.defaultValue || over !== node.over + ) { + ExprWindow(windowFunction, expression, offset, defaultValue, over) + } else { + node + } + } + + override fun visitExprWindowOver(node: ExprWindow.Over, ctx: C): AstNode { + val partitions = node.partitions?.let { _visitList(it, ctx, ::visitExpr) } + val sorts = node.sorts?.let { _visitList(it, ctx, ::visitSort) } + return if (partitions !== node.partitions || sorts !== node.sorts) { + ExprWindow.Over(partitions, sorts) + } else { + node + } + } + + override fun visitPathStepField(node: PathStep.Field, ctx: C): AstNode { + val field = visitIdentifier(node.field, ctx) as Identifier + val next = node.next?.let { visitPathStep(it, ctx) as PathStep? } + return if (field !== node.field || next !== node.next) { + PathStep.Field(field, next) + } else { + node + } + } + + override fun visitPathStepElement(node: PathStep.Element, ctx: C): AstNode { + val element = visitExpr(node.element, ctx) as Expr + val next = node.next?.let { visitPathStep(it, ctx) as PathStep? } + return if (element !== node.element || next !== node.next) { + PathStep.Element(element, next) + } else { + node + } + } + + override fun visitPathStepAllFields(node: PathStep.AllFields, ctx: C): AstNode { + val next = node.next?.let { visitPathStep(it, ctx) as PathStep? } + return if (next !== node.next) { + PathStep.AllFields(next) + } else { + node + } + } + + override fun visitPathStepAllElements(node: PathStep.AllElements, ctx: C): AstNode { + val next = node.next?.let { visitPathStep(it, ctx) as PathStep? } + return if (next !== node.next) { + PathStep.AllElements(next) + } else { + node + } + } + + // graph + override fun visitGraphMatch(node: GraphMatch, ctx: C): AstNode { + val patterns = _visitList(node.patterns, ctx, ::visitGraphPattern) + val selector = node.selector?.let { visitGraphSelector(it, ctx) as GraphSelector? } + return if (patterns !== node.patterns || selector !== node.selector) { + GraphMatch(patterns, selector) + } else { + node + } + } + + // TODO rename the visitor + override fun visitGraphPattern(node: GraphPattern, ctx: C): AstNode { + val restrictor = node.restrictor + val prefilter = node.prefilter?.let { visitExpr(it, ctx) as Expr? } + val variable = node.variable + val quantifier = node.quantifier?.let { visitGraphQuantifier(it, ctx) as GraphQuantifier? } + val parts = _visitList(node.parts, ctx, ::visitGraphPart) + return if (restrictor !== node.restrictor || prefilter !== node.prefilter || variable !== + node.variable || quantifier !== node.quantifier || parts !== node.parts + ) { + GraphPattern(restrictor, prefilter, variable, quantifier, parts) + } else { + node + } + } + + override fun visitGraphQuantifier(node: GraphQuantifier, ctx: C): AstNode { + val lower = node.lower + val upper = node.upper + return node + } + + override fun visitGraphSelectorAny(node: GraphSelector.Any, ctx: C): AstNode { + return node + } + + override fun visitGraphSelectorAnyK(node: GraphSelector.AnyK, ctx: C): AstNode { + val k = node.k + return node + } + + override fun visitGraphSelectorAllShortest(node: GraphSelector.AllShortest, ctx: C): AstNode { + return node + } + + override fun visitGraphSelectorAnyShortest(node: GraphSelector.AnyShortest, ctx: C): AstNode { + return node + } + + override fun visitGraphSelectorShortestK(node: GraphSelector.ShortestK, ctx: C): AstNode { + val k = node.k + return node + } + + override fun visitGraphSelectorShortestKGroup(node: GraphSelector.ShortestKGroup, ctx: C): AstNode { + val k = node.k + return node + } + + override fun visitExclude(node: Exclude, ctx: C): AstNode { + val excludePaths = _visitList(node.excludePaths, ctx, ::visitExcludePath) + return if (excludePaths !== node.excludePaths) { + Exclude(excludePaths) + } else { + node + } + } + + override fun visitExcludePath(node: ExcludePath, ctx: C): AstNode { + val root = visitExprVarRef(node.root, ctx) as ExprVarRef + val excludeSteps = _visitList(node.excludeSteps, ctx, ::visitExcludeStep) + return if (root !== node.root || excludeSteps !== node.excludeSteps) { + ExcludePath(root, excludeSteps) + } else { + node + } + } + + override fun visitExcludeStepCollIndex(node: ExcludeStep.CollIndex, ctx: C): AstNode { + val index = node.index + return node + } + + override fun visitExcludeStepStructField(node: ExcludeStep.StructField, ctx: C): AstNode { + val symbol = visitIdentifier(node.symbol, ctx) as Identifier + return if (symbol !== node.symbol) { + ExcludeStep.StructField(symbol) + } else { + node + } + } + + override fun visitExcludeStepCollWildcard(node: ExcludeStep.CollWildcard, ctx: C): AstNode { + return node + } + + override fun visitExcludeStepStructWildcard(node: ExcludeStep.StructWildcard, ctx: C): AstNode { + return node + } + + @OptIn(PartiQLValueExperimental::class) + override fun visitExplain(node: Explain, ctx: C): AstNode { + val statement = visitStatement(node.statement, ctx) as Statement + return if (statement !== node.statement) { + explain(node.options, statement) + } else { + node + } + } + + override fun visitFrom(node: From, ctx: C): AstNode { + val tableRefs = _visitList(node.tableRefs, ctx, ::visitFromTableRef) + return if (tableRefs !== node.tableRefs) { + From(tableRefs) + } else { + node + } + } + + override fun visitFromExpr(node: FromExpr, ctx: C): AstNode { + val expr = visitExpr(node.expr, ctx) as Expr + val fromType = node.fromType + val asAlias = node.asAlias?.let { visitIdentifier(it, ctx) as Identifier? } + val atAlias = node.atAlias?.let { visitIdentifier(it, ctx) as Identifier? } + return if (expr !== node.expr || fromType !== node.fromType || asAlias !== node.asAlias || + atAlias !== node.atAlias + ) { + FromExpr(expr, fromType, asAlias, atAlias) + } else { + node + } + } + + override fun visitFromJoin(node: FromJoin, ctx: C): AstNode { + val lhs = visitFromTableRef(node.lhs, ctx) as FromTableRef + val rhs = visitFromTableRef(node.rhs, ctx) as FromTableRef + val joinType = node.joinType + val condition = node.condition?.let { visitExpr(it, ctx) as Expr? } + return if (lhs !== node.lhs || rhs !== node.rhs || joinType !== node.joinType || + condition !== node.condition + ) { + FromJoin(lhs, rhs, joinType, condition) + } else { + node + } + } + + override fun visitGroupBy(node: GroupBy, ctx: C): AstNode { + val strategy = node.strategy + val keys = _visitList(node.keys, ctx, ::visitGroupByKey) + val asAlias = node.asAlias?.let { visitIdentifier(it, ctx) as Identifier? } + return if (strategy !== node.strategy || keys !== node.keys || asAlias !== node.asAlias) { + GroupBy(strategy, keys, asAlias) + } else { + node + } + } + + override fun visitGroupByKey(node: GroupBy.Key, ctx: C): AstNode { + val expr = visitExpr(node.expr, ctx) as Expr + val asAlias = node.asAlias?.let { visitIdentifier(it, ctx) as Identifier? } + return if (expr !== node.expr || asAlias !== node.asAlias) { + GroupBy.Key(expr, asAlias) + } else { + node + } + } + + override fun visitIdentifier(node: Identifier, ctx: C): AstNode { + val symbol = node.symbol + val isDelimited = node.isDelimited + return identifier(symbol, isDelimited) + } + + override fun visitIdentifierChain(node: IdentifierChain, ctx: C): AstNode { + val root = visitIdentifier(node.root, ctx) as Identifier + val next = node.next?.let { visitIdentifierChain(it, ctx) as IdentifierChain? } + return if (root !== node.root || next !== node.next) { + IdentifierChain(root, next) + } else { + node + } + } + + override fun visitLet(node: Let, ctx: C): AstNode { + val bindings = _visitList(node.bindings, ctx, ::visitLetBinding) + return if (bindings !== node.bindings) { + Let(bindings) + } else { + node + } + } + + override fun visitLetBinding(node: Let.Binding, ctx: C): AstNode { + val expr = visitExpr(node.expr, ctx) as Expr + val asAlias = visitIdentifier(node.asAlias, ctx) as Identifier + return if (expr !== node.expr || asAlias !== node.asAlias) { + Let.Binding(expr, asAlias) + } else { + node + } + } + + override fun visitQuery(node: Query, ctx: C): AstNode { + val expr = visitExpr(node.expr, ctx) as Expr + return if (expr !== node.expr) { + query(expr) + } else { + node + } + } + + override fun visitQueryBodySFW(node: QueryBody.SFW, ctx: C): AstNode { + val select = visitSelect(node.select, ctx) as Select + val exclude = node.exclude?.let { visitExclude(it, ctx) as Exclude? } + val from = visitFrom(node.from, ctx) as From + val let = node.let?.let { visitLet(it, ctx) as Let? } + val where = node.where?.let { visitExpr(it, ctx) as Expr? } + val groupBy = node.groupBy?.let { visitGroupBy(it, ctx) as GroupBy? } + val having = node.having?.let { visitExpr(it, ctx) as Expr? } + return if (select !== node.select || exclude !== node.exclude || from !== node.from || let !== + node.let || where !== node.where || groupBy !== node.groupBy || having !== node.having + ) { + QueryBody.SFW(select, exclude, from, let, where, groupBy, having) + } else { + node + } + } + + public override fun visitQueryBodySetOp(node: QueryBody.SetOp, ctx: C): AstNode { + val type = visitSetOp(node.type, ctx) as SetOp + val isOuter = node.isOuter + val lhs = visitExpr(node.lhs, ctx) as Expr + val rhs = visitExpr(node.rhs, ctx) as Expr + return if (type !== node.type || isOuter != node.isOuter || lhs !== node.lhs || rhs !== node.rhs) { + QueryBody.SetOp(type, isOuter, lhs, rhs) + } else { + node + } + } + + public override fun visitSelectItemStar(node: SelectItem.Star, ctx: C): AstNode { + val expr = visitExpr(node.expr, ctx) as Expr + return if (expr !== node.expr) { + SelectItem.Star(expr) + } else { + node + } + } + + public override fun visitSelectItemExpr(node: SelectItem.Expr, ctx: C): AstNode { + val expr = visitExpr(node.expr, ctx) as Expr + val asAlias = node.asAlias?.let { visitIdentifier(it, ctx) as Identifier? } + return if (expr !== node.expr || asAlias !== node.asAlias) { + SelectItem.Expr(expr, asAlias) + } else { + node + } + } + + override fun visitSelectList(node: SelectList, ctx: C): AstNode { + val items = _visitList(node.items, ctx, ::visitSelectItem) + val setq = node.setq + return if (items !== node.items || setq !== node.setq) { + SelectList(items, setq) + } else { + node + } + } + + override fun visitSelectPivot(node: SelectPivot, ctx: C): AstNode { + val key = visitExpr(node.key, ctx) as Expr + val value = visitExpr(node.value, ctx) as Expr + return if (key !== node.key || value !== node.value) { + SelectPivot(key, value) + } else { + node + } + } + + override fun visitSelectStar(node: SelectStar, ctx: C): AstNode { + val setq = node.setq + return node + } + + override fun visitSelectValue(node: SelectValue, ctx: C): AstNode { + val constructor = visitExpr(node.constructor, ctx) as Expr + val setq = node.setq + return if (constructor !== node.constructor || setq !== node.setq) { + SelectValue(constructor, setq) + } else { + node + } + } + + override fun visitSetOp(node: SetOp, ctx: C): AstNode { + val setOpType = node.setOpType + val setq = node.setq + return node + } +} diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/AstVisitor.java b/partiql-ast/src/main/java/org/partiql/ast/v1/AstVisitor.java index 6ac7c5f851..1af6e6ef8f 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/AstVisitor.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/AstVisitor.java @@ -22,7 +22,6 @@ import org.partiql.ast.v1.expr.ExprOverlay; import org.partiql.ast.v1.expr.ExprParameter; import org.partiql.ast.v1.expr.ExprPath; -import org.partiql.ast.v1.expr.PathStep; import org.partiql.ast.v1.expr.ExprPosition; import org.partiql.ast.v1.expr.ExprQuerySet; import org.partiql.ast.v1.expr.ExprSessionAttribute; @@ -33,6 +32,7 @@ import org.partiql.ast.v1.expr.ExprVarRef; import org.partiql.ast.v1.expr.ExprVariant; import org.partiql.ast.v1.expr.ExprWindow; +import org.partiql.ast.v1.expr.PathStep; import org.partiql.ast.v1.graph.GraphLabel; import org.partiql.ast.v1.graph.GraphMatch; import org.partiql.ast.v1.graph.GraphPart; @@ -40,199 +40,549 @@ import org.partiql.ast.v1.graph.GraphQuantifier; import org.partiql.ast.v1.graph.GraphSelector; -public interface AstVisitor { - R visit(AstNode node, C ctx); - - R visitStatement(Statement node, C ctx); - - R visitQuery(Query node, C ctx); - - R visitExplain(Explain node, C ctx); - - R visitIdentifier(Identifier node, C ctx); - - R visitIdentifierChain(IdentifierChain node, C ctx); - - R visitExpr(Expr node, C ctx); - - R visitExprLit(ExprLit node, C ctx); - - R visitExprVariant(ExprVariant node, C ctx); - - R visitExprVarRef(ExprVarRef node, C ctx); - - R visitExprSessionAttribute(ExprSessionAttribute node, C ctx); - - R visitExprPath(ExprPath node, C ctx); - - R visitPathStep(PathStep node, C ctx); - - R visitPathStepField(PathStep.Field node, C ctx); - - R visitPathStepElement(PathStep.Element node, C ctx); - - R visitPathStepAllElements(PathStep.AllElements node, C ctx); - - R visitPathStepAllFields(PathStep.AllFields node, C ctx); - - R visitExprCall(ExprCall node, C ctx); - - R visitExprParameter(ExprParameter node, C ctx); - - R visitExprOperator(ExprOperator node, C ctx); - - R visitExprNot(ExprNot node, C ctx); - - R visitExprAnd(ExprAnd node, C ctx); - - R visitExprOr(ExprOr node, C ctx); - - R visitExprValues(ExprValues node, C ctx); - - R visitExprValuesRow(ExprValues.Row node, C ctx); - - R visitExprArray(ExprArray node, C ctx); - - R visitExprBag(ExprBag node, C ctx); - - R visitExprStruct(ExprStruct node, C ctx); - - R visitExprStructField(ExprStruct.Field node, C ctx); - - R visitExprLike(ExprLike node, C ctx); - - R visitExprBetween(ExprBetween node, C ctx); - - R visitExprInCollection(ExprInCollection node, C ctx); - - R visitExprIsType(ExprIsType node, C ctx); - - R visitExprCase(ExprCase node, C ctx); - - R visitExprCaseBranch(ExprCase.Branch node, C ctx); - - R visitExprCoalesce(ExprCoalesce node, C ctx); - - R visitExprNullIf(ExprNullIf node, C ctx); - - R visitExprSubstring(ExprSubstring node, C ctx); - - R visitExprPosition(ExprPosition node, C ctx); - - R visitExprTrim(ExprTrim node, C ctx); - - R visitExprOverlay(ExprOverlay node, C ctx); - - R visitExprExtract(ExprExtract node, C ctx); - - R visitExprCast(ExprCast node, C ctx); - - R visitExprQuerySet(ExprQuerySet node, C ctx); - - R visitExprMatch(ExprMatch node, C ctx); - - R visitExprWindow(ExprWindow node, C ctx); - - R visitExprWindowOver(ExprWindow.Over node, C ctx); - - R visitQueryBody(QueryBody node, C ctx); - - R visitQueryBodySFW(QueryBody.SFW node, C ctx); - - R visitQueryBodySetOp(QueryBody.SetOp node, C ctx); - - R visitSelect(Select node, C ctx); - - R visitSelectStar(SelectStar node, C ctx); - - R visitSelectList(SelectList node, C ctx); - - R visitSelectItem(SelectItem node, C ctx); - - R visitSelectItemStar(SelectItem.Star node, C ctx); - - R visitSelectItemExpr(SelectItem.Expr node, C ctx); - - R visitSelectPivot(SelectPivot node, C ctx); - - R visitSelectValue(SelectValue node, C ctx); - - R visitExclude(Exclude node, C ctx); - - R visitExcludePath(ExcludePath node, C ctx); - - R visitExcludeStep(ExcludeStep node, C ctx); - - R visitExcludeStepStructField(ExcludeStep.StructField node, C ctx); - - R visitExcludeStepCollIndex(ExcludeStep.CollIndex node, C ctx); - - R visitExcludeStepStructWildcard(ExcludeStep.StructWildcard node, C ctx); - - R visitExcludeStepCollWildcard(ExcludeStep.CollWildcard node, C ctx); - - R visitFrom(From node, C ctx); - - R visitTableRef(FromTableRef node, C ctx); - - R visitFromExpr(FromExpr node, C ctx); - - R visitFromJoin(FromJoin node, C ctx); - - R visitLet(Let node, C ctx); - - R visitLetBinding(Let.Binding node, C ctx); - - R visitGroupBy(GroupBy node, C ctx); - - R visitGroupByKey(GroupBy.Key node, C ctx); - - R visitOrderBy(OrderBy node, C ctx); - - R visitSort(Sort node, C ctx); - - R visitSetOp(SetOp node, C ctx); - - R visitGraphMatch(GraphMatch node, C ctx); - - R visitGraphMatchPattern(GraphPattern node, C ctx); - - R visitGraphPart(GraphPart node, C ctx); - - R visitGraphPartNode(GraphPart.Node node, C ctx); - - R visitGraphPartEdge(GraphPart.Edge node, C ctx); - - R visitGraphPartPattern(GraphPart.Pattern node, C ctx); - - R visitGraphQuantifier(GraphQuantifier node, C ctx); - - R visitGraphSelector(GraphSelector node, C ctx); - - R visitGraphSelectorAnyShortest(GraphSelector.AnyShortest node, C ctx); - - R visitGraphSelectorAllShortest(GraphSelector.AllShortest node, C ctx); - - R visitGraphSelectorAny(GraphSelector.Any node, C ctx); - - R visitGraphSelectorAnyK(GraphSelector.AnyK node, C ctx); - - R visitGraphSelectorShortestK(GraphSelector.ShortestK node, C ctx); - - R visitGraphSelectorShortestKGroup( - GraphSelector.ShortestKGroup node, - C ctx - ); - - R visitGraphLabel(GraphLabel node, C ctx); - - R visitGraphLabelName(GraphLabel.Name node, C ctx); - - R visitGraphLabelWildcard(GraphLabel.Wildcard node, C ctx); - - R visitGraphLabelNegation(GraphLabel.Negation node, C ctx); - - R visitGraphLabelConj(GraphLabel.Conj node, C ctx); - - R visitGraphLabelDisj(GraphLabel.Disj node, C ctx); +public abstract class AstVisitor { + public R defaultVisit(AstNode node, C ctx) { + for (AstNode child : node.children()) { + child.accept(this, ctx); + } + return defaultReturn(node, ctx); + } + + public abstract R defaultReturn(AstNode node, C ctx); + + public R visit(AstNode node, C ctx) { + return node.accept(this, ctx); + } + + public R visitStatement(Statement node, C ctx) { + if (node instanceof Query) { + return visitQuery((Query) node, ctx); + } else if (node instanceof Explain) { + return visitExplain((Explain) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitQuery(Query node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExplain(Explain node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitIdentifier(Identifier node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitIdentifierChain(IdentifierChain node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExpr(Expr node, C ctx) { + if (node instanceof ExprLit) { + return visitExprLit((ExprLit) node, ctx); + } else if (node instanceof ExprVariant) { + return visitExprVariant((ExprVariant) node, ctx); + } else if (node instanceof ExprVarRef) { + return visitExprVarRef((ExprVarRef) node, ctx); + } else if (node instanceof ExprSessionAttribute) { + return visitExprSessionAttribute((ExprSessionAttribute) node, ctx); + } else if (node instanceof ExprPath) { + return visitExprPath((ExprPath) node, ctx); + } else if (node instanceof ExprCall) { + return visitExprCall((ExprCall) node, ctx); + } else if (node instanceof ExprParameter) { + return visitExprParameter((ExprParameter) node, ctx); + } else if (node instanceof ExprOperator) { + return visitExprOperator((ExprOperator) node, ctx); + } else if (node instanceof ExprNot) { + return visitExprNot((ExprNot) node, ctx); + } else if (node instanceof ExprAnd) { + return visitExprAnd((ExprAnd) node, ctx); + } else if (node instanceof ExprOr) { + return visitExprOr((ExprOr) node, ctx); + } else if (node instanceof ExprValues) { + return visitExprValues((ExprValues) node, ctx); + } else if (node instanceof ExprArray) { + return visitExprArray((ExprArray) node, ctx); + } else if (node instanceof ExprBag) { + return visitExprBag((ExprBag) node, ctx); + } else if (node instanceof ExprStruct) { + return visitExprStruct((ExprStruct) node, ctx); + } else if (node instanceof ExprLike) { + return visitExprLike((ExprLike) node, ctx); + } else if (node instanceof ExprBetween) { + return visitExprBetween((ExprBetween) node, ctx); + } else if (node instanceof ExprInCollection) { + return visitExprInCollection((ExprInCollection) node, ctx); + } else if (node instanceof ExprIsType) { + return visitExprIsType((ExprIsType) node, ctx); + } else if (node instanceof ExprCase) { + return visitExprCase((ExprCase) node, ctx); + } else if (node instanceof ExprCoalesce) { + return visitExprCoalesce((ExprCoalesce) node, ctx); + } else if (node instanceof ExprNullIf) { + return visitExprNullIf((ExprNullIf) node, ctx); + } else if (node instanceof ExprSubstring) { + return visitExprSubstring((ExprSubstring) node, ctx); + } else if (node instanceof ExprPosition) { + return visitExprPosition((ExprPosition) node, ctx); + } else if (node instanceof ExprTrim) { + return visitExprTrim((ExprTrim) node, ctx); + } else if (node instanceof ExprOverlay) { + return visitExprOverlay((ExprOverlay) node, ctx); + } else if (node instanceof ExprExtract) { + return visitExprExtract((ExprExtract) node, ctx); + } else if (node instanceof ExprCast) { + return visitExprCast((ExprCast) node, ctx); + } else if (node instanceof ExprQuerySet) { + return visitExprQuerySet((ExprQuerySet) node, ctx); + } else if (node instanceof ExprMatch) { + return visitExprMatch((ExprMatch) node, ctx); + } else if (node instanceof ExprWindow) { + return visitExprWindow((ExprWindow) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitExprLit(ExprLit node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprVariant(ExprVariant node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprVarRef(ExprVarRef node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprSessionAttribute(ExprSessionAttribute node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprPath(ExprPath node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitPathStep(PathStep node, C ctx) { + if (node instanceof PathStep.Field) { + return visitPathStepField((PathStep.Field) node, ctx); + } else if (node instanceof PathStep.Element) { + return visitPathStepElement((PathStep.Element) node, ctx); + } else if (node instanceof PathStep.AllElements) { + return visitPathStepAllElements((PathStep.AllElements) node, ctx); + } else if (node instanceof PathStep.AllFields) { + return visitPathStepAllFields((PathStep.AllFields) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitPathStepField(PathStep.Field node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitPathStepElement(PathStep.Element node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitPathStepAllElements(PathStep.AllElements node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitPathStepAllFields(PathStep.AllFields node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprCall(ExprCall node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprParameter(ExprParameter node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprOperator(ExprOperator node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprNot(ExprNot node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprAnd(ExprAnd node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprOr(ExprOr node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprValues(ExprValues node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprValuesRow(ExprValues.Row node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprArray(ExprArray node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprBag(ExprBag node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprStruct(ExprStruct node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprStructField(ExprStruct.Field node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprLike(ExprLike node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprBetween(ExprBetween node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprInCollection(ExprInCollection node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprIsType(ExprIsType node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprCase(ExprCase node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprCaseBranch(ExprCase.Branch node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprCoalesce(ExprCoalesce node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprNullIf(ExprNullIf node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprSubstring(ExprSubstring node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprPosition(ExprPosition node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprTrim(ExprTrim node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprOverlay(ExprOverlay node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprExtract(ExprExtract node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprCast(ExprCast node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprQuerySet(ExprQuerySet node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprMatch(ExprMatch node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprWindow(ExprWindow node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExprWindowOver(ExprWindow.Over node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitQueryBody(QueryBody node, C ctx) { + if (node instanceof QueryBody.SFW) { + return visitQueryBodySFW((QueryBody.SFW) node, ctx); + } else if (node instanceof QueryBody.SetOp) { + return visitQueryBodySetOp((QueryBody.SetOp) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitQueryBodySFW(QueryBody.SFW node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitQueryBodySetOp(QueryBody.SetOp node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitSelect(Select node, C ctx) { + if (node instanceof SelectStar) { + return visitSelectStar((SelectStar) node, ctx); + } else if (node instanceof SelectList) { + return visitSelectList((SelectList) node, ctx); + } else if (node instanceof SelectPivot) { + return visitSelectPivot((SelectPivot) node, ctx); + } else if (node instanceof SelectValue) { + return visitSelectValue((SelectValue) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitSelectStar(SelectStar node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitSelectList(SelectList node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitSelectItem(SelectItem node, C ctx) { + if (node instanceof SelectItem.Star) { + return visitSelectItemStar((SelectItem.Star) node, ctx); + } else if (node instanceof SelectItem.Expr) { + return visitSelectItemExpr((SelectItem.Expr) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitSelectItemStar(SelectItem.Star node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitSelectItemExpr(SelectItem.Expr node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitSelectPivot(SelectPivot node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitSelectValue(SelectValue node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExclude(Exclude node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExcludePath(ExcludePath node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExcludeStep(ExcludeStep node, C ctx) { + if (node instanceof ExcludeStep.StructField) { + return visitExcludeStepStructField((ExcludeStep.StructField) node, ctx); + } else if (node instanceof ExcludeStep.CollIndex) { + return visitExcludeStepCollIndex((ExcludeStep.CollIndex) node, ctx); + } else if (node instanceof ExcludeStep.StructWildcard) { + return visitExcludeStepStructWildcard((ExcludeStep.StructWildcard) node, ctx); + } else if (node instanceof ExcludeStep.CollWildcard) { + return visitExcludeStepCollWildcard((ExcludeStep.CollWildcard) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitExcludeStepStructField(ExcludeStep.StructField node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExcludeStepCollIndex(ExcludeStep.CollIndex node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExcludeStepStructWildcard(ExcludeStep.StructWildcard node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitExcludeStepCollWildcard(ExcludeStep.CollWildcard node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitFrom(From node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitFromTableRef(FromTableRef node, C ctx) { + if (node instanceof FromExpr) { + return visitFromExpr((FromExpr) node, ctx); + } else if (node instanceof FromJoin) { + return visitFromJoin((FromJoin) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitFromExpr(FromExpr node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitFromJoin(FromJoin node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitLet(Let node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitLetBinding(Let.Binding node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGroupBy(GroupBy node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGroupByKey(GroupBy.Key node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitOrderBy(OrderBy node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitSort(Sort node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitSetOp(SetOp node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphMatch(GraphMatch node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphPattern(GraphPattern node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphPart(GraphPart node, C ctx) { + if (node instanceof GraphPart.Node) { + return visitGraphPartNode((GraphPart.Node) node, ctx); + } else if (node instanceof GraphPart.Edge) { + return visitGraphPartEdge((GraphPart.Edge) node, ctx); + } else if (node instanceof GraphPart.Pattern) { + return visitGraphPartPattern((GraphPart.Pattern) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitGraphPartNode(GraphPart.Node node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphPartEdge(GraphPart.Edge node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphPartPattern(GraphPart.Pattern node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphQuantifier(GraphQuantifier node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphSelector(GraphSelector node, C ctx) { + if (node instanceof GraphSelector.AnyShortest) { + return visitGraphSelectorAnyShortest((GraphSelector.AnyShortest) node, ctx); + } else if (node instanceof GraphSelector.AllShortest) { + return visitGraphSelectorAllShortest((GraphSelector.AllShortest) node, ctx); + } else if (node instanceof GraphSelector.Any) { + return visitGraphSelectorAny((GraphSelector.Any) node, ctx); + } else if (node instanceof GraphSelector.AnyK) { + return visitGraphSelectorAnyK((GraphSelector.AnyK) node, ctx); + } else if (node instanceof GraphSelector.ShortestK) { + return visitGraphSelectorShortestK((GraphSelector.ShortestK) node, ctx); + } else if (node instanceof GraphSelector.ShortestKGroup) { + return visitGraphSelectorShortestKGroup((GraphSelector.ShortestKGroup) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitGraphSelectorAnyShortest(GraphSelector.AnyShortest node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphSelectorAllShortest(GraphSelector.AllShortest node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphSelectorAny(GraphSelector.Any node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphSelectorAnyK(GraphSelector.AnyK node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphSelectorShortestK(GraphSelector.ShortestK node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphSelectorShortestKGroup(GraphSelector.ShortestKGroup node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphLabel(GraphLabel node, C ctx) { + if (node instanceof GraphLabel.Name) { + return visitGraphLabelName((GraphLabel.Name) node, ctx); + } else if (node instanceof GraphLabel.Wildcard) { + return visitGraphLabelWildcard((GraphLabel.Wildcard) node, ctx); + } else if (node instanceof GraphLabel.Negation) { + return visitGraphLabelNegation((GraphLabel.Negation) node, ctx); + } else if (node instanceof GraphLabel.Conj) { + return visitGraphLabelConj((GraphLabel.Conj) node, ctx); + } else if (node instanceof GraphLabel.Disj) { + return visitGraphLabelDisj((GraphLabel.Disj) node, ctx); + } else { + throw new IllegalStateException("Unexpected value: " + node); + } + } + + public R visitGraphLabelName(GraphLabel.Name node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphLabelWildcard(GraphLabel.Wildcard node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphLabelNegation(GraphLabel.Negation node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphLabelConj(GraphLabel.Conj node, C ctx) { + return defaultVisit(node, ctx); + } + + public R visitGraphLabelDisj(GraphLabel.Disj node, C ctx) { + return defaultVisit(node, ctx); + } } diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/ExcludeStep.java b/partiql-ast/src/main/java/org/partiql/ast/v1/ExcludeStep.java index 0b769edb08..13cf54eb60 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/ExcludeStep.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/ExcludeStep.java @@ -1,6 +1,7 @@ package org.partiql.ast.v1; import lombok.Builder; +import lombok.EqualsAndHashCode; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -15,6 +16,7 @@ public abstract class ExcludeStep extends AstNode { * TODO docs, equals, hashcode */ @Builder(builderClassName = "Builder") + @EqualsAndHashCode(callSuper = false) public static class StructField extends ExcludeStep { @NotNull public final Identifier symbol; @@ -41,6 +43,7 @@ public R accept(@NotNull AstVisitor visitor, C ctx) { * TODO docs, equals, hashcode */ @Builder(builderClassName = "Builder") + @EqualsAndHashCode(callSuper = false) public static class CollIndex extends ExcludeStep { public final int index; @@ -64,6 +67,7 @@ public R accept(@NotNull AstVisitor visitor, C ctx) { * TODO docs, equals, hashcode */ @Builder(builderClassName = "Builder") + @EqualsAndHashCode(callSuper = false) public static class StructWildcard extends ExcludeStep { @NotNull @Override @@ -81,6 +85,7 @@ public R accept(@NotNull AstVisitor visitor, C ctx) { * TODO docs, equals, hashcode */ @Builder(builderClassName = "Builder") + @EqualsAndHashCode(callSuper = false) public static class CollWildcard extends ExcludeStep { @NotNull @Override diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/FromTableRef.java b/partiql-ast/src/main/java/org/partiql/ast/v1/FromTableRef.java index fb50883503..99cf2c6a7c 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/FromTableRef.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/FromTableRef.java @@ -1,19 +1,6 @@ package org.partiql.ast.v1; -import org.jetbrains.annotations.NotNull; - /** * TODO docs, equals, hashcode */ -public abstract class FromTableRef extends AstNode { - @Override - public R accept(@NotNull AstVisitor visitor, C ctx) { - if (this instanceof FromExpr) { - return visitor.visitFromExpr((FromExpr) this, ctx); - } else if (this instanceof FromJoin) { - return visitor.visitFromJoin((FromJoin) this, ctx); - } else { - throw new IllegalStateException("Unexpected value: " + this); - } - } -} +public abstract class FromTableRef extends AstNode {} diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/Select.java b/partiql-ast/src/main/java/org/partiql/ast/v1/Select.java index 275fbcf33e..c09636b86d 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/Select.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/Select.java @@ -1,23 +1,6 @@ package org.partiql.ast.v1; -import org.jetbrains.annotations.NotNull; - /** * TODO docs, equals, hashcode */ -public abstract class Select extends AstNode { - @Override - public R accept(@NotNull AstVisitor visitor, C ctx) { - if (this instanceof SelectStar) { - return visitor.visitSelectStar((SelectStar) this, ctx); - } else if (this instanceof SelectList) { - return visitor.visitSelectList((SelectList) this, ctx); - } else if (this instanceof SelectPivot) { - return visitor.visitSelectPivot((SelectPivot) this, ctx); - } else if (this instanceof SelectValue) { - return visitor.visitSelectValue((SelectValue) this, ctx); - } else { - throw new IllegalStateException("Unexpected value: " + this); - } - } -} +public abstract class Select extends AstNode {} diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/SelectItem.java b/partiql-ast/src/main/java/org/partiql/ast/v1/SelectItem.java index 4178334fd1..8f7fcc69a6 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/SelectItem.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/SelectItem.java @@ -13,17 +13,6 @@ * TODO docs, equals, hashcode */ public abstract class SelectItem extends AstNode { - @Override - public R accept(@NotNull AstVisitor visitor, C ctx) { - if (this instanceof Star) { - return visitor.visitSelectItemStar((Star) this, ctx); - } else if (this instanceof Expr) { - return visitor.visitSelectItemExpr((Expr) this, ctx); - } else { - throw new IllegalStateException("Unexpected value: " + this); - } - } - /** * TODO docs, equals, hashcode */ diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/Statement.java b/partiql-ast/src/main/java/org/partiql/ast/v1/Statement.java index 94ba678f98..fa2d8b8d90 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/Statement.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/Statement.java @@ -1,19 +1,6 @@ package org.partiql.ast.v1; -import org.jetbrains.annotations.NotNull; - /** * TODO docs, equals, hashcode */ -public abstract class Statement extends AstNode { - @Override - public R accept(@NotNull AstVisitor visitor, C ctx) { - if (this instanceof Query) { - return visitor.visitQuery((Query) this, ctx); - } else if (this instanceof Explain) { - return visitor.visitExplain((Explain) this, ctx); - } else { - throw new IllegalStateException("Unexpected value: " + this); - } - } -} +public abstract class Statement extends AstNode {} diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/expr/Expr.java b/partiql-ast/src/main/java/org/partiql/ast/v1/expr/Expr.java index 92305a86b9..b049e47528 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/expr/Expr.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/expr/Expr.java @@ -1,79 +1,8 @@ package org.partiql.ast.v1.expr; -import org.jetbrains.annotations.NotNull; import org.partiql.ast.v1.AstNode; -import org.partiql.ast.v1.AstVisitor; /** * TODO docs, equals, hashcode */ -public abstract class Expr extends AstNode { - @Override - public R accept(@NotNull AstVisitor visitor, C ctx) { - if (this instanceof ExprLit) { - return visitor.visitExprLit((ExprLit) this, ctx); - } else if (this instanceof ExprVariant) { - return visitor.visitExprVariant((ExprVariant) this, ctx); - } else if (this instanceof ExprVarRef) { - return visitor.visitExprVarRef((ExprVarRef) this, ctx); - } else if (this instanceof ExprSessionAttribute) { - return visitor.visitExprSessionAttribute((ExprSessionAttribute) this, ctx); - } else if (this instanceof ExprPath) { - return visitor.visitExprPath((ExprPath) this, ctx); - } else if (this instanceof ExprCall) { - return visitor.visitExprCall((ExprCall) this, ctx); - } else if (this instanceof ExprParameter) { - return visitor.visitExprParameter((ExprParameter) this, ctx); - } else if (this instanceof ExprOperator) { - return visitor.visitExprOperator((ExprOperator) this, ctx); - } else if (this instanceof ExprNot) { - return visitor.visitExprNot((ExprNot) this, ctx); - } else if (this instanceof ExprAnd) { - return visitor.visitExprAnd((ExprAnd) this, ctx); - } else if (this instanceof ExprOr) { - return visitor.visitExprOr((ExprOr) this, ctx); - } else if (this instanceof ExprValues) { - return visitor.visitExprValues((ExprValues) this, ctx); - } else if (this instanceof ExprArray) { - return visitor.visitExprArray((ExprArray) this, ctx); - } else if (this instanceof ExprBag) { - return visitor.visitExprBag((ExprBag) this, ctx); - } else if (this instanceof ExprStruct) { - return visitor.visitExprStruct((ExprStruct) this, ctx); - } else if (this instanceof ExprLike) { - return visitor.visitExprLike((ExprLike) this, ctx); - } else if (this instanceof ExprBetween) { - return visitor.visitExprBetween((ExprBetween) this, ctx); - } else if (this instanceof ExprInCollection) { - return visitor.visitExprInCollection((ExprInCollection) this, ctx); - } else if (this instanceof ExprIsType) { - return visitor.visitExprIsType((ExprIsType) this, ctx); - } else if (this instanceof ExprCase) { - return visitor.visitExprCase((ExprCase) this, ctx); - } else if (this instanceof ExprCoalesce) { - return visitor.visitExprCoalesce((ExprCoalesce) this, ctx); - } else if (this instanceof ExprNullIf) { - return visitor.visitExprNullIf((ExprNullIf) this, ctx); - } else if (this instanceof ExprSubstring) { - return visitor.visitExprSubstring((ExprSubstring) this, ctx); - } else if (this instanceof ExprPosition) { - return visitor.visitExprPosition((ExprPosition) this, ctx); - } else if (this instanceof ExprTrim) { - return visitor.visitExprTrim((ExprTrim) this, ctx); - } else if (this instanceof ExprOverlay) { - return visitor.visitExprOverlay((ExprOverlay) this, ctx); - } else if (this instanceof ExprExtract) { - return visitor.visitExprExtract((ExprExtract) this, ctx); - } else if (this instanceof ExprCast) { - return visitor.visitExprCast((ExprCast) this, ctx); - } else if (this instanceof ExprQuerySet) { - return visitor.visitExprQuerySet((ExprQuerySet) this, ctx); - } else if (this instanceof ExprMatch) { - return visitor.visitExprMatch((ExprMatch) this, ctx); - } else if (this instanceof ExprWindow) { - return visitor.visitExprWindow((ExprWindow) this, ctx); - } else { - throw new IllegalStateException("Unexpected value: " + this); - } - } -} +public abstract class Expr extends AstNode {} diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphLabel.java b/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphLabel.java index 37d2d7d439..8d00275133 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphLabel.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphLabel.java @@ -14,23 +14,6 @@ * TODO docs, equals, hashcode */ public abstract class GraphLabel extends AstNode { - @Override - public R accept(@NotNull AstVisitor visitor, C ctx) { - if (this instanceof Name) { - return visitor.visitGraphLabelName((Name) this, ctx); - } else if (this instanceof Wildcard) { - return visitor.visitGraphLabelWildcard((Wildcard) this, ctx); - } else if (this instanceof Negation) { - return visitor.visitGraphLabelNegation((Negation) this, ctx); - } else if (this instanceof Conj) { - return visitor.visitGraphLabelConj((Conj) this, ctx); - } else if (this instanceof Disj) { - return visitor.visitGraphLabelDisj((Disj) this, ctx); - } else { - throw new IllegalStateException("Unexpected value: " + this); - } - } - /** * TODO docs, equals, hashcode */ diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphPart.java b/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphPart.java index 779f1a25dc..c997414915 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphPart.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphPart.java @@ -16,19 +16,6 @@ * TODO docs, equals, hashcode */ public abstract class GraphPart extends AstNode { - @Override - public R accept(@NotNull AstVisitor visitor, C ctx) { - if (this instanceof Node) { - return visitor.visitGraphPartNode((Node) this, ctx); - } else if (this instanceof Edge) { - return visitor.visitGraphPartEdge((Edge) this, ctx); - } else if (this instanceof Pattern) { - return visitor.visitGraphPartPattern((Pattern) this, ctx); - } else { - throw new IllegalStateException("Unexpected value: " + this); - } - } - /** * TODO docs, equals, hashcode */ diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphPattern.java b/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphPattern.java index 716284925c..c1126e8edc 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphPattern.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphPattern.java @@ -59,6 +59,6 @@ public Collection children() { @Override public R accept(@NotNull AstVisitor visitor, C ctx) { - return visitor.visitGraphMatchPattern(this, ctx); + return visitor.visitGraphPattern(this, ctx); } } diff --git a/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphSelector.java b/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphSelector.java index 9b9aa2b996..13ee135e87 100644 --- a/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphSelector.java +++ b/partiql-ast/src/main/java/org/partiql/ast/v1/graph/GraphSelector.java @@ -13,25 +13,6 @@ * TODO docs, equals, hashcode */ public abstract class GraphSelector extends AstNode { - @Override - public R accept(@NotNull AstVisitor visitor, C ctx) { - if (this instanceof AnyShortest) { - return visitor.visitGraphSelectorAnyShortest((AnyShortest) this, ctx); - } else if (this instanceof AllShortest) { - return visitor.visitGraphSelectorAllShortest((AllShortest) this, ctx); - } else if (this instanceof Any) { - return visitor.visitGraphSelectorAny((Any) this, ctx); - } else if (this instanceof AnyK) { - return visitor.visitGraphSelectorAnyK((AnyK) this, ctx); - } else if (this instanceof ShortestK) { - return visitor.visitGraphSelectorShortestK((ShortestK) this, ctx); - } else if (this instanceof ShortestKGroup) { - return visitor.visitGraphSelectorShortestKGroup((ShortestKGroup) this, ctx); - } else { - throw new IllegalStateException("Unexpected value: " + this); - } - } - /** * TODO docs, equals, hashcode */ diff --git a/partiql-ast/src/main/kotlin/org/partiql/ast/helpers/ToBinder.kt b/partiql-ast/src/main/kotlin/org/partiql/ast/helpers/ToBinder.kt index d0bd97ca12..fbc2a78bc4 100644 --- a/partiql-ast/src/main/kotlin/org/partiql/ast/helpers/ToBinder.kt +++ b/partiql-ast/src/main/kotlin/org/partiql/ast/helpers/ToBinder.kt @@ -6,6 +6,8 @@ import org.partiql.ast.builder.ast import org.partiql.value.PartiQLValueExperimental import org.partiql.value.StringValue +// TODO DELETE FILE + private val col = { index: () -> Int -> "_${index()}" } /** diff --git a/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/AstPass.kt b/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/AstPass.kt index 6513c44661..57faa804b5 100644 --- a/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/AstPass.kt +++ b/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/AstPass.kt @@ -16,6 +16,8 @@ package org.partiql.ast.normalize import org.partiql.ast.Statement +// TODO DELETE FILE + /** * Wraps a rewriter with a default entry point. */ diff --git a/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/Normalize.kt b/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/Normalize.kt index 13d01ad5b8..d4bce86b0b 100644 --- a/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/Normalize.kt +++ b/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/Normalize.kt @@ -17,6 +17,8 @@ package org.partiql.ast.normalize import org.partiql.ast.Statement +// TODO DELETE FILE + /** * AST normalization */ diff --git a/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/NormalizeFromSource.kt b/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/NormalizeFromSource.kt index 9fa0bd963a..29531daa6e 100644 --- a/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/NormalizeFromSource.kt +++ b/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/NormalizeFromSource.kt @@ -23,6 +23,8 @@ import org.partiql.ast.fromJoin import org.partiql.ast.helpers.toBinder import org.partiql.ast.util.AstRewriter +// TODO DELETE FILE + /** * Assign aliases to any FROM source which does not have one. */ diff --git a/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/NormalizeGroupBy.kt b/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/NormalizeGroupBy.kt index 85fcad17d5..66228fe237 100644 --- a/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/NormalizeGroupBy.kt +++ b/partiql-ast/src/main/kotlin/org/partiql/ast/normalize/NormalizeGroupBy.kt @@ -22,6 +22,8 @@ import org.partiql.ast.groupByKey import org.partiql.ast.helpers.toBinder import org.partiql.ast.util.AstRewriter +// TODO DELETE FILE + /** * Adds a unique binder to each group key. */ diff --git a/partiql-planner/src/main/kotlin/org/partiql/planner/internal/helpers/ToBinder.kt b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/helpers/ToBinder.kt new file mode 100644 index 0000000000..45f95146a0 --- /dev/null +++ b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/helpers/ToBinder.kt @@ -0,0 +1,82 @@ +package org.partiql.planner.internal.helpers + +import org.partiql.ast.v1.Ast.identifier +import org.partiql.ast.v1.Identifier +import org.partiql.ast.v1.IdentifierChain +import org.partiql.ast.v1.expr.Expr +import org.partiql.ast.v1.expr.ExprCast +import org.partiql.ast.v1.expr.ExprLit +import org.partiql.ast.v1.expr.ExprPath +import org.partiql.ast.v1.expr.ExprSessionAttribute +import org.partiql.ast.v1.expr.ExprVarRef +import org.partiql.ast.v1.expr.PathStep +import org.partiql.value.PartiQLValueExperimental +import org.partiql.value.StringValue + +private val col = { index: () -> Int -> "_${index()}" } + +/** + * Produces a "binder" (AS alias) for an expression following the given rules: + * + * 1. If item is an id, use the last symbol + * 2. If item is a path with a final symbol step, use the symbol — else 4 + * 3. If item is a cast, use the value name + * 4. Else, use item index with prefix _ + * + * See https://github.com/partiql/partiql-lang-kotlin/issues/1122 + */ +internal fun Expr.toBinder(index: () -> Int): Identifier = when (this) { + is ExprVarRef -> this.identifierChain.toBinder() + is ExprPath -> this.toBinder(index) + is ExprCast -> this.value.toBinder(index) + is ExprSessionAttribute -> this.sessionAttribute.name().uppercase().toBinder() + else -> col(index).toBinder() +} + +/** + * Simple toBinder that uses an int literal rather than a closure. + * + * @param index + * @return + */ +internal fun Expr.toBinder(index: Int): Identifier = toBinder { index } + +private fun String.toBinder(): Identifier = + // Every binder preserves case + identifier(this@toBinder, true) + +private fun IdentifierChain.toBinder(): Identifier { + if (next == null) return root.symbol.toBinder() + var cur = next + var prev = cur + while (cur != null) { + prev = cur + cur = cur.next + } + return prev!!.root.symbol.toBinder() +} + +private fun Identifier.toBinder(): Identifier = symbol.toBinder() + +@OptIn(PartiQLValueExperimental::class) +private fun ExprPath.toBinder(index: () -> Int): Identifier { + if (next == null) return root.toBinder(index) + var cur = next + var prev = next + while (cur != null) { + prev = cur + cur = cur.next + } + return when (prev) { + is PathStep.Field -> prev.field.toBinder() + is PathStep.Element -> { + val k = prev.element + if (k is ExprLit && k.value is StringValue) { + (k.value as StringValue).value!!.toBinder() + } else { + col(index).toBinder() + } + } + else -> col(index).toBinder() + } +} diff --git a/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/AstPass.kt b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/AstPass.kt new file mode 100644 index 0000000000..882ff16c06 --- /dev/null +++ b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/AstPass.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2022 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.planner.internal.normalize + +import org.partiql.ast.v1.Statement + +/** + * Wraps a rewriter with a default entry point. + */ +internal interface AstPass { + fun apply(statement: Statement): Statement +} diff --git a/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/Normalize.kt b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/Normalize.kt new file mode 100644 index 0000000000..c5ef7fe47c --- /dev/null +++ b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/Normalize.kt @@ -0,0 +1,29 @@ +@file:JvmName("Normalize") +/* + * Copyright 2022 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.planner.internal.normalize + +import org.partiql.ast.v1.Statement + +/** + * AST normalization + */ +internal fun Statement.normalize(): Statement { + // could be a fold, but this is nice for setting breakpoints + var ast = this + ast = NormalizeFromSource.apply(ast) + ast = NormalizeGroupBy.apply(ast) + return ast +} diff --git a/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/NormalizeFromSource.kt b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/NormalizeFromSource.kt new file mode 100644 index 0000000000..d2e22a9c4b --- /dev/null +++ b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/NormalizeFromSource.kt @@ -0,0 +1,76 @@ +/* + * Copyright 2022 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.planner.internal.normalize + +import org.partiql.ast.v1.Ast.fromExpr +import org.partiql.ast.v1.Ast.fromJoin +import org.partiql.ast.v1.AstNode +import org.partiql.ast.v1.AstRewriter +import org.partiql.ast.v1.From +import org.partiql.ast.v1.FromExpr +import org.partiql.ast.v1.FromJoin +import org.partiql.ast.v1.FromTableRef +import org.partiql.ast.v1.FromType +import org.partiql.ast.v1.QueryBody +import org.partiql.ast.v1.Statement +import org.partiql.ast.v1.expr.Expr +import org.partiql.planner.internal.helpers.toBinder + +/** + * Assign aliases to any FROM source which does not have one. + */ +internal object NormalizeFromSource : AstPass { + + override fun apply(statement: Statement): Statement = statement.accept(Visitor, 0) as Statement + + private object Visitor : AstRewriter() { + + // Each SFW starts the ctx count again. + override fun visitQueryBodySFW(node: QueryBody.SFW, ctx: Int): AstNode = super.visitQueryBodySFW(node, 0) + + override fun visitFrom(node: From, ctx: Int) = super.visitFrom(node, ctx) as From + + override fun visitFromJoin(node: FromJoin, ctx: Int): FromJoin { + val lhs = node.lhs.accept(this, ctx) as FromTableRef + val rhs = node.rhs.accept(this, ctx + 1) as FromTableRef + val condition = node.condition?.accept(this, ctx) as Expr? + return if (lhs !== node.lhs || rhs !== node.rhs || condition !== node.condition) { + fromJoin(lhs, rhs, node.joinType, condition) + } else { + node + } + } + + override fun visitFromExpr(node: FromExpr, ctx: Int): FromExpr { + val expr = node.expr.accept(this, ctx) as Expr + var i = ctx + var asAlias = node.asAlias + var atAlias = node.atAlias + // derive AS alias + if (asAlias == null) { + asAlias = expr.toBinder(i++) + } + // derive AT binder + if (atAlias == null && node.fromType == FromType.UNPIVOT()) { + atAlias = expr.toBinder(i++) + } + return if (expr !== node.expr || asAlias !== node.asAlias || atAlias !== node.atAlias) { + fromExpr(expr = expr, fromType = node.fromType, asAlias = asAlias, atAlias = atAlias) + } else { + node + } + } + } +} diff --git a/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/NormalizeGroupBy.kt b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/NormalizeGroupBy.kt new file mode 100644 index 0000000000..0a96550a05 --- /dev/null +++ b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/normalize/NormalizeGroupBy.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2022 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.planner.internal.normalize + +import org.partiql.ast.v1.Ast.groupBy +import org.partiql.ast.v1.Ast.groupByKey +import org.partiql.ast.v1.AstNode +import org.partiql.ast.v1.AstRewriter +import org.partiql.ast.v1.GroupBy +import org.partiql.ast.v1.Statement +import org.partiql.ast.v1.expr.Expr +import org.partiql.planner.internal.helpers.toBinder + +/** + * Adds a unique binder to each group key. + */ +internal object NormalizeGroupBy : AstPass { + + override fun apply(statement: Statement) = Visitor.visitStatement(statement, 0) as Statement + + private object Visitor : AstRewriter() { + + override fun visitGroupBy(node: GroupBy, ctx: Int): AstNode { + val keys = node.keys.mapIndexed { index, key -> + visitGroupByKey(key, index + 1) + } + return groupBy(strategy = node.strategy, keys = keys, asAlias = node.asAlias) + } + + override fun visitGroupByKey(node: GroupBy.Key, ctx: Int): GroupBy.Key { + val expr = visitExpr(node.expr, 0) as Expr + val alias = when (node.asAlias) { + null -> expr.toBinder(ctx) + else -> node.asAlias + } + return if (expr !== node.expr || alias !== node.asAlias) { + groupByKey(expr, alias) + } else { + node + } + } + } +} diff --git a/partiql-planner/src/main/kotlin/org/partiql/planner/internal/transforms/V1NormalizeSelect.kt b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/transforms/V1NormalizeSelect.kt new file mode 100644 index 0000000000..96a994ac03 --- /dev/null +++ b/partiql-planner/src/main/kotlin/org/partiql/planner/internal/transforms/V1NormalizeSelect.kt @@ -0,0 +1,393 @@ +/* + * 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.planner.internal.transforms + +import org.partiql.ast.v1.Ast.exprCall +import org.partiql.ast.v1.Ast.exprCase +import org.partiql.ast.v1.Ast.exprCaseBranch +import org.partiql.ast.v1.Ast.exprIsType +import org.partiql.ast.v1.Ast.exprLit +import org.partiql.ast.v1.Ast.exprQuerySet +import org.partiql.ast.v1.Ast.exprStruct +import org.partiql.ast.v1.Ast.exprStructField +import org.partiql.ast.v1.Ast.exprVarRef +import org.partiql.ast.v1.Ast.identifier +import org.partiql.ast.v1.Ast.identifierChain +import org.partiql.ast.v1.Ast.queryBodySFW +import org.partiql.ast.v1.Ast.queryBodySetOp +import org.partiql.ast.v1.Ast.selectItemExpr +import org.partiql.ast.v1.Ast.selectList +import org.partiql.ast.v1.Ast.selectValue +import org.partiql.ast.v1.AstRewriter +import org.partiql.ast.v1.DataType +import org.partiql.ast.v1.From +import org.partiql.ast.v1.FromExpr +import org.partiql.ast.v1.FromJoin +import org.partiql.ast.v1.FromTableRef +import org.partiql.ast.v1.GroupBy +import org.partiql.ast.v1.QueryBody +import org.partiql.ast.v1.SelectItem +import org.partiql.ast.v1.SelectList +import org.partiql.ast.v1.SelectStar +import org.partiql.ast.v1.SelectValue +import org.partiql.ast.v1.expr.Expr +import org.partiql.ast.v1.expr.ExprCase +import org.partiql.ast.v1.expr.ExprLit +import org.partiql.ast.v1.expr.ExprQuerySet +import org.partiql.ast.v1.expr.ExprStruct +import org.partiql.ast.v1.expr.ExprVarRef +import org.partiql.ast.v1.expr.Scope +import org.partiql.planner.internal.helpers.toBinder +import org.partiql.value.PartiQLValueExperimental +import org.partiql.value.stringValue + +/** + * Converts SQL-style SELECT to PartiQL SELECT VALUE. + * - If there is a PROJECT ALL, we use the TUPLEUNION. + * - If there is NOT a PROJECT ALL, we use a literal struct. + * + * Here are some example of rewrites: + * + * ``` + * SELECT * + * FROM + * A AS x, + * B AS y AT i + * ``` + * gets rewritten to: + * ``` + * SELECT VALUE TUPLEUNION( + * CASE WHEN x IS STRUCT THEN x ELSE { '_1': x }, + * CASE WHEN y IS STRUCT THEN y ELSE { '_2': y }, + * { 'i': i } + * ) FROM A AS x, B AS y AT i + * ``` + * + * ``` + * SELECT x.*, x.a FROM A AS x + * ``` + * gets rewritten to: + * ``` + * SELECT VALUE TUPLEUNION( + * CASE WHEN x IS STRUCT THEN x ELSE { '_1': x }, + * { 'a': x.a } + * ) FROM A AS x + * ``` + * + * ``` + * SELECT x.a FROM A AS x + * ``` + * gets rewritten to: + * ``` + * SELECT VALUE { + * 'a': x.a + * } FROM A AS x + * ``` + * + * NOTE: This does NOT transform subqueries. It operates directly on an [QueryExpr.SFW] -- and that is it. Therefore: + * ``` + * SELECT + * (SELECT 1 FROM T AS "T") + * FROM R AS "R" + * ``` + * will be transformed to: + * ``` + * SELECT VALUE { + * '_1': (SELECT 1 FROM T AS "T") -- notice that SELECT 1 didn't get transformed. + * } FROM R AS "R" + * ``` + * + * Requires [NormalizeFromSource]. + */ +internal object V1NormalizeSelect { + + internal fun normalize(node: ExprQuerySet): ExprQuerySet { + return when (val body = node.body) { + is QueryBody.SFW -> { + val sfw = Visitor.visitSFW(body, newCtx()) + exprQuerySet( + body = sfw, + orderBy = node.orderBy, + limit = node.limit, + offset = node.offset + ) + } + is QueryBody.SetOp -> { + val lhs = body.lhs.normalizeOrIdentity() + val rhs = body.rhs.normalizeOrIdentity() + exprQuerySet( + body = queryBodySetOp( + type = body.type, + isOuter = body.isOuter, + lhs = lhs, + rhs = rhs + ), + orderBy = node.orderBy, + limit = node.limit, + offset = node.offset + ) + } + else -> error("Unexpected QueryBody type: $body") + } + } + + private fun Expr.normalizeOrIdentity(): Expr { + return when (this) { + is ExprQuerySet -> normalize(this) + else -> this + } + } + + /** + * Closure for incrementing a derived binding counter + */ + private fun newCtx(): () -> Int = run { + var i = 1; + { i++ } + } + + /** + * The type parameter () -> Int + */ + private object Visitor : AstRewriter<() -> Int>() { + + /** + * This is used to give projections a name. For example: + * ``` + * SELECT t.* FROM t AS t + * ``` + * + * Will get converted into: + * ``` + * SELECT VALUE TUPLEUNION( + * CASE + * WHEN t IS STRUCT THEN t + * ELSE { '_1': t } + * END + * ) + * FROM t AS t + * ``` + * + * In order to produce the struct's key in `{ '_1': t }` above, we use [col] to produce the column name + * given the ordinal. + */ + private val col = { index: Int -> "_${index + 1}" } + + internal fun visitSFW(node: QueryBody.SFW, ctx: () -> Int): QueryBody.SFW { + val sfw = super.visitQueryBodySFW(node, ctx) as QueryBody.SFW + return when (val select = sfw.select) { + is SelectStar -> { + val selectValue = when (val group = sfw.groupBy) { + null -> visitSelectAll(select, sfw.from) + else -> visitSelectAll(select, group) + } + queryBodySFW( + select = selectValue, + exclude = sfw.exclude, + from = sfw.from, + let = sfw.let, + where = sfw.where, + groupBy = sfw.groupBy, + having = sfw.having, + ) + } + else -> sfw + } + } + + override fun visitQueryBodySFW(node: QueryBody.SFW, ctx: () -> Int): QueryBody.SFW { + return node + } + + override fun visitSelectList(node: SelectList, ctx: () -> Int): SelectValue { + + // Visit items, adding a binder if necessary + var diff = false + val visitedItems = ArrayList(node.items.size) + node.items.forEach { n -> + val item = n.accept(this, ctx) as SelectItem + if (item !== n) diff = true + visitedItems.add(item) + } + val visitedNode = if (diff) selectList(visitedItems, node.setq) else node + + // Rewrite selection + return when (node.items.any { it is SelectItem.Star }) { + false -> visitSelectProjectWithoutProjectAll(visitedNode) + true -> visitSelectProjectWithProjectAll(visitedNode) + } + } + + override fun visitSelectItemExpr(node: SelectItem.Expr, ctx: () -> Int): SelectItem.Expr { + val expr = visitExpr(node.expr, newCtx()) as Expr + val alias = when (node.asAlias) { + null -> expr.toBinder(ctx) + else -> node.asAlias + } + return if (expr != node.expr || alias != node.asAlias) { + selectItemExpr(expr, alias) + } else { + node + } + } + + // Helpers + + /** + * We need to call this from [visitExprSFW] and not override [visitSelectStar] because we need access to the + * [From] aliases. + * + * Note: We assume that [select] and [from] have already been visited. + */ + private fun visitSelectAll(select: SelectStar, from: From): SelectValue { + val tupleUnionArgs = from.tableRefs.flatMap { it.aliases() }.flatMapIndexed { i, binding -> + val asAlias = binding.first + val atAlias = binding.second + val atAliasItem = atAlias?.simple()?.let { + val alias = it.asAlias ?: error("The AT alias should be present. This wasn't normalized.") + buildSimpleStruct(it.expr, alias.symbol) + } + listOfNotNull( + buildCaseWhenStruct(asAlias.star(i).expr, i), + atAliasItem, + ) + } + return selectValue( + constructor = exprCall( + function = identifierChain(identifier("TUPLEUNION", isDelimited = true), next = null), + args = tupleUnionArgs, + setq = null // setq = null for scalar fn + ), + setq = select.setq + ) + } + + /** + * We need to call this from [visitExprSFW] and not override [visitSelectStar] because we need access to the + * [GroupBy] aliases. + * + * Note: We assume that [select] and [group] have already been visited. + */ + private fun visitSelectAll(select: SelectStar, group: GroupBy): SelectValue { + val groupAs = group.asAlias?.let { structField(it.symbol, varLocal(it.symbol)) } + val fields = group.keys.map { key -> + val alias = key.asAlias ?: error("Expected a GROUP BY alias.") + structField(alias.symbol, varLocal(alias.symbol)) + } + listOfNotNull(groupAs) + val constructor = exprStruct(fields) + return selectValue( + constructor = constructor, + setq = select.setq + ) + } + + private fun visitSelectProjectWithProjectAll(node: SelectList): SelectValue { + val tupleUnionArgs = node.items.mapIndexed { index, item -> + when (item) { + is SelectItem.Star -> buildCaseWhenStruct(item.expr, index) + is SelectItem.Expr -> buildSimpleStruct( + item.expr, + item.asAlias?.symbol + ?: error("The alias should've been here. This AST is not normalized.") + ) + else -> error("Unexpected SelectItem type: $item") + } + } + return selectValue( + setq = node.setq, + constructor = exprCall( + function = identifierChain(identifier("TUPLEUNION", isDelimited = true), next = null), + args = tupleUnionArgs, + setq = null // setq = null for scalar fn + ) + ) + } + + @OptIn(PartiQLValueExperimental::class) + private fun visitSelectProjectWithoutProjectAll(node: SelectList): SelectValue { + val structFields = node.items.map { item -> + val itemExpr = item as? SelectItem.Expr ?: error("Expected the projection to be an expression.") + exprStructField( + name = exprLit(stringValue(itemExpr.asAlias?.symbol!!)), + value = item.expr + ) + } + return selectValue( + setq = node.setq, + constructor = exprStruct( + fields = structFields + ) + ) + } + + private fun buildCaseWhenStruct(expr: Expr, index: Int): ExprCase = exprCase( + expr = null, + branches = listOf( + exprCaseBranch( + condition = exprIsType(expr, DataType.STRUCT(), not = false), + expr = expr + ) + ), + defaultExpr = buildSimpleStruct(expr, col(index)) + ) + + @OptIn(PartiQLValueExperimental::class) + private fun buildSimpleStruct(expr: Expr, name: String): ExprStruct = exprStruct( + fields = listOf( + exprStructField( + name = exprLit(stringValue(name)), + value = expr + ) + ) + ) + + @OptIn(PartiQLValueExperimental::class) + private fun structField(name: String, expr: Expr): ExprStruct.Field = exprStructField( + name = ExprLit(stringValue(name)), + value = expr + ) + + private fun varLocal(name: String): ExprVarRef = exprVarRef( + identifierChain = identifierChain(identifier(name, isDelimited = true), next = null), + scope = Scope.LOCAL() + ) + + private fun FromTableRef.aliases(): List> = when (this) { + is FromJoin -> lhs.aliases() + rhs.aliases() + is FromExpr -> { + val asAlias = asAlias?.symbol ?: error("AST not normalized, missing asAlias on FROM source.") + val atAlias = atAlias?.symbol + listOf(Pair(asAlias, atAlias)) + } + else -> error("Unexpected FromTableRef type: $this") + } + + // t -> t.* AS _i + private fun String.star(i: Int): SelectItem.Expr { + val expr = exprVarRef(identifierChain(id(this), next = null), Scope.DEFAULT()) + val alias = expr.toBinder(i) + return selectItemExpr(expr, alias) + } + + // t -> t AS t + private fun String.simple(): SelectItem.Expr { + val expr = exprVarRef(identifierChain(id(this), next = null), Scope.DEFAULT()) + val alias = id(this) + return selectItemExpr(expr, alias) + } + + private fun id(symbol: String) = identifier(symbol, isDelimited = false) + } +} diff --git a/partiql-planner/src/test/kotlin/org/partiql/planner/internal/transforms/NormalizeSelectTest.kt b/partiql-planner/src/test/kotlin/org/partiql/planner/internal/transforms/NormalizeSelectTest.kt index 0ca74b17c7..ce81b193da 100644 --- a/partiql-planner/src/test/kotlin/org/partiql/planner/internal/transforms/NormalizeSelectTest.kt +++ b/partiql-planner/src/test/kotlin/org/partiql/planner/internal/transforms/NormalizeSelectTest.kt @@ -1,15 +1,23 @@ package org.partiql.planner.internal.transforms import org.junit.jupiter.api.Test -import org.partiql.ast.Expr -import org.partiql.ast.From -import org.partiql.ast.Identifier -import org.partiql.ast.Select -import org.partiql.ast.builder.ast -import org.partiql.ast.exprLit -import org.partiql.ast.exprVar -import org.partiql.ast.identifierSymbol -import org.partiql.ast.selectProjectItemExpression +import org.partiql.ast.v1.Ast.exprLit +import org.partiql.ast.v1.Ast.exprQuerySet +import org.partiql.ast.v1.Ast.exprStruct +import org.partiql.ast.v1.Ast.exprStructField +import org.partiql.ast.v1.Ast.exprVarRef +import org.partiql.ast.v1.Ast.from +import org.partiql.ast.v1.Ast.fromExpr +import org.partiql.ast.v1.Ast.identifier +import org.partiql.ast.v1.Ast.identifierChain +import org.partiql.ast.v1.Ast.queryBodySFW +import org.partiql.ast.v1.Ast.selectItemExpr +import org.partiql.ast.v1.Ast.selectList +import org.partiql.ast.v1.Ast.selectValue +import org.partiql.ast.v1.FromType +import org.partiql.ast.v1.SelectItem +import org.partiql.ast.v1.expr.Expr +import org.partiql.ast.v1.expr.Scope import org.partiql.value.PartiQLValueExperimental import org.partiql.value.int32Value import org.partiql.value.stringValue @@ -38,7 +46,7 @@ class NormalizeSelectTest { "b" to variable("b"), "c" to variable("c"), ) - val actual = NormalizeSelect.normalize(input) + val actual = V1NormalizeSelect.normalize(input) assertEquals(expected, actual) } @@ -63,7 +71,7 @@ class NormalizeSelectTest { "_2" to lit(2), "_3" to lit(3), ) - val actual = NormalizeSelect.normalize(input) + val actual = V1NormalizeSelect.normalize(input) assertEquals(expected, actual) } @@ -88,7 +96,7 @@ class NormalizeSelectTest { "_1" to lit(2), "_2" to lit(3), ) - val actual = NormalizeSelect.normalize(input) + val actual = V1NormalizeSelect.normalize(input) assertEquals(expected, actual) } @@ -113,70 +121,104 @@ class NormalizeSelectTest { "b" to lit(2), "c" to lit(3), ) - val actual = NormalizeSelect.normalize(input) + val actual = V1NormalizeSelect.normalize(input) assertEquals(expected, actual) } // ----- HELPERS ------------------------- - private fun variable(name: String) = exprVar( - identifier = identifierSymbol( - symbol = name, - caseSensitivity = Identifier.CaseSensitivity.INSENSITIVE, + private fun variable(name: String) = exprVarRef( + identifierChain = identifierChain( + identifier( + symbol = name, + isDelimited = false, + ), + next = null ), - scope = Expr.Var.Scope.DEFAULT, + scope = Scope.DEFAULT(), ) - private fun select(vararg items: Select.Project.Item) = ast { - exprQuerySet { - body = queryBodySFW { - select = selectProject { - this.items += items - } - from = fromValue { - expr = variable("T") - type = From.Value.Type.SCAN - } - } - } - } + private fun select(vararg items: SelectItem) = + exprQuerySet( + body = queryBodySFW( + select = selectList( + items = items.toList(), + setq = null + ), + exclude = null, + from = from( + listOf( + fromExpr( + expr = variable("T"), + fromType = FromType.SCAN(), + asAlias = null, + atAlias = null + ) + ) + ), + let = null, + where = null, + groupBy = null, + having = null, + ), + limit = null, + offset = null, + orderBy = null + ) @OptIn(PartiQLValueExperimental::class) - private fun selectValue(vararg items: Pair) = ast { - exprQuerySet { - body = queryBodySFW { - select = selectValue { - constructor = exprStruct { - for ((k, v) in items) { - fields += exprStructField { - name = exprLit(stringValue(k)) - value = v - } - } - } - } - from = fromValue { - expr = exprVar { - identifier = identifierSymbol { - symbol = "T" - caseSensitivity = Identifier.CaseSensitivity.INSENSITIVE + private fun selectValue(vararg items: Pair) = + exprQuerySet( + body = queryBodySFW( + select = selectValue( + constructor = exprStruct( + items.map { + exprStructField( + name = exprLit(stringValue(it.first)), + value = it.second + ) } - scope = Expr.Var.Scope.DEFAULT - } - type = From.Value.Type.SCAN - } - } - } - } + ), + setq = null + ), + exclude = null, + from = from( + listOf( + fromExpr( + expr = exprVarRef( + identifierChain = identifierChain( + identifier( + symbol = "T", + isDelimited = false + ), + next = null + ), + scope = Scope.DEFAULT() + ), + fromType = FromType.SCAN(), + asAlias = null, + atAlias = null + ), + ) + ), + let = null, + where = null, + groupBy = null, + having = null, + ), + limit = null, + offset = null, + orderBy = null + ) - private fun varItem(symbol: String, asAlias: String? = null) = selectProjectItemExpression( + private fun varItem(symbol: String, asAlias: String? = null) = selectItemExpr( expr = variable(symbol), - asAlias = asAlias?.let { identifierSymbol(asAlias, Identifier.CaseSensitivity.INSENSITIVE) } + asAlias = asAlias?.let { identifier(asAlias, isDelimited = false) } ) - private fun litItem(value: Int, asAlias: String? = null) = selectProjectItemExpression( + private fun litItem(value: Int, asAlias: String? = null) = selectItemExpr( expr = lit(value), - asAlias = asAlias?.let { identifierSymbol(asAlias, Identifier.CaseSensitivity.INSENSITIVE) } + asAlias = asAlias?.let { identifier(asAlias, isDelimited = false) } ) @OptIn(PartiQLValueExperimental::class)