Files
upstream-mirror 0f4df23290
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
snapshot of https://github.com/sqlc-dev/sqlc.git (main, 2026-09-16; blobs > 131072B omitted)
2026-09-16 02:17:34 +05:00

1272 lines
34 KiB
Go

// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package astutils
import (
"fmt"
"reflect"
"github.com/sqlc-dev/sqlc/internal/sql/ast"
)
// An ApplyFunc is invoked by Apply for each node n, even if n is nil,
// before and/or after the node's children, using a Cursor describing
// the current node and providing operations on it.
//
// The return value of ApplyFunc controls the syntax tree traversal.
// See Apply for details.
type ApplyFunc func(*Cursor) bool
// Apply traverses a syntax tree recursively, starting with root,
// and calling pre and post for each node as described below.
// Apply returns the syntax tree, possibly modified.
//
// If pre is not nil, it is called for each node before the node's
// children are traversed (pre-order). If pre returns false, no
// children are traversed, and post is not called for that node.
//
// If post is not nil, and a prior call of pre didn't return false,
// post is called for each node after its children are traversed
// (post-order). If post returns false, traversal is terminated and
// Apply returns immediately.
//
// Only fields that refer to AST nodes are considered children;
// i.e., token.Pos, Scopes, Objects, and fields of basic types
// (strings, etc.) are ignored.
//
// Children are traversed in the order in which they appear in the
// respective node's struct definition. A package's files are
// traversed in the filenames' alphabetical order.
func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node) {
parent := &struct{ ast.Node }{root}
defer func() {
if r := recover(); r != nil && r != abort {
panic(r)
}
result = parent.Node
}()
a := &application{pre: pre, post: post}
a.apply(parent, "Node", nil, root)
return
}
var abort = new(int) // singleton, to signal termination of Apply
// A Cursor describes a node encountered during Apply.
// Information about the node and its parent is available
// from the Node, Parent, Name, and Index methods.
//
// If p is a variable of type and value of the current parent node
// c.Parent(), and f is the field identifier with name c.Name(),
// the following invariants hold:
//
// p.f == c.Node() if c.Index() < 0
// p.f[c.Index()] == c.Node() if c.Index() >= 0
//
// The methods Replace, Delete, InsertBefore, and InsertAfter
// can be used to change the AST without disrupting Apply.
type Cursor struct {
parent ast.Node
name string
iter *iterator // valid if non-nil
node ast.Node
}
// Node returns the current Node.
func (c *Cursor) Node() ast.Node { return c.node }
// Parent returns the parent of the current Node.
func (c *Cursor) Parent() ast.Node { return c.parent }
// Name returns the name of the parent Node field that contains the current Node.
// If the parent is a *ast.Package and the current Node is a *ast.File, Name returns
// the filename for the current Node.
func (c *Cursor) Name() string { return c.name }
// Index reports the index >= 0 of the current Node in the slice of Nodes that
// contains it, or a value < 0 if the current Node is not part of a slice.
// The index of the current node changes if InsertBefore is called while
// processing the current node.
func (c *Cursor) Index() int {
if c.iter != nil {
return c.iter.index
}
return -1
}
// field returns the current node's parent field value.
func (c *Cursor) field() reflect.Value {
return reflect.Indirect(reflect.ValueOf(c.parent)).FieldByName(c.name)
}
// Replace replaces the current Node with n.
// The replacement node is not walked by Apply.
func (c *Cursor) Replace(n ast.Node) {
v := c.field()
if i := c.Index(); i >= 0 {
v = v.Index(i)
}
v.Set(reflect.ValueOf(n))
}
// D// application carries all the shared data so we can pass it around cheaply.
type application struct {
pre, post ApplyFunc
cursor Cursor
iter iterator
}
func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.Node) {
// convert typed nil into untyped nil
if v := reflect.ValueOf(n); v.Kind() == reflect.Pointer && v.IsNil() {
n = nil
}
// avoid heap-allocating a new cursor for each apply call; reuse a.cursor instead
saved := a.cursor
a.cursor.parent = parent
a.cursor.name = name
a.cursor.iter = iter
a.cursor.node = n
if a.pre != nil && !a.pre(&a.cursor) {
a.cursor = saved
return
}
// walk children
// (the order of the cases matches the order of the corresponding node types in go/ast)
switch n := n.(type) {
case nil:
// nothing to do
case *ast.AlterTableSetSchemaStmt:
a.apply(n, "Table", nil, n.Table)
case *ast.AlterTypeAddValueStmt:
a.apply(n, "Type", nil, n.Type)
case *ast.AlterTypeRenameValueStmt:
a.apply(n, "Type", nil, n.Type)
case *ast.CommentOnColumnStmt:
a.apply(n, "Table", nil, n.Table)
a.apply(n, "Col", nil, n.Col)
case *ast.CommentOnSchemaStmt:
a.apply(n, "Schema", nil, n.Schema)
case *ast.CommentOnTableStmt:
a.apply(n, "Table", nil, n.Table)
case *ast.CommentOnTypeStmt:
a.apply(n, "Type", nil, n.Type)
case *ast.CommentOnViewStmt:
a.apply(n, "View", nil, n.View)
case *ast.CreateTableStmt:
a.apply(n, "Name", nil, n.Name)
case *ast.DropFunctionStmt:
// pass
case *ast.DropSchemaStmt:
// pass
case *ast.DropTableStmt:
// pass
case *ast.DropTypeStmt:
// pass
case *ast.FuncName:
// pass
case *ast.FuncParam:
a.apply(n, "Type", nil, n.Type)
a.apply(n, "DefExpr", nil, n.DefExpr)
case *ast.FuncSpec:
a.apply(n, "Name", nil, n.Name)
case *ast.In:
a.applyList(n, "List")
a.apply(n, "Sel", nil, n.Sel)
case *ast.List:
// Since item is a slice
a.applyList(n, "Items")
case *ast.RawStmt:
a.apply(n, "Stmt", nil, n.Stmt)
case *ast.RenameColumnStmt:
a.apply(n, "Table", nil, n.Table)
a.apply(n, "Col", nil, n.Col)
case *ast.RenameTableStmt:
a.apply(n, "Table", nil, n.Table)
case *ast.RenameTypeStmt:
a.apply(n, "Type", nil, n.Type)
case *ast.Statement:
a.apply(n, "Raw", nil, n.Raw)
case *ast.String:
// pass
case *ast.TODO:
// pass
case *ast.TableName:
// pass
case *ast.A_ArrayExpr:
a.apply(n, "Elements", nil, n.Elements)
case *ast.A_Const:
a.apply(n, "Val", nil, n.Val)
case *ast.A_Expr:
a.apply(n, "Name", nil, n.Name)
a.apply(n, "Lexpr", nil, n.Lexpr)
a.apply(n, "Rexpr", nil, n.Rexpr)
case *ast.A_Indices:
a.apply(n, "Lidx", nil, n.Lidx)
a.apply(n, "Uidx", nil, n.Uidx)
case *ast.A_Indirection:
a.apply(n, "Arg", nil, n.Arg)
a.apply(n, "Indirection", nil, n.Indirection)
case *ast.A_Star:
// pass
case *ast.AccessPriv:
a.apply(n, "Cols", nil, n.Cols)
case *ast.Aggref:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Aggargtypes", nil, n.Aggargtypes)
a.apply(n, "Aggdirectargs", nil, n.Aggdirectargs)
a.apply(n, "Args", nil, n.Args)
a.apply(n, "Aggorder", nil, n.Aggorder)
a.apply(n, "Aggdistinct", nil, n.Aggdistinct)
a.apply(n, "Aggfilter", nil, n.Aggfilter)
case *ast.Alias:
a.apply(n, "Colnames", nil, n.Colnames)
case *ast.AlterCollationStmt:
a.apply(n, "Collname", nil, n.Collname)
case *ast.AlterDatabaseSetStmt:
a.apply(n, "Setstmt", nil, n.Setstmt)
case *ast.AlterDatabaseStmt:
a.apply(n, "Options", nil, n.Options)
case *ast.AlterDefaultPrivilegesStmt:
a.apply(n, "Options", nil, n.Options)
a.apply(n, "Action", nil, n.Action)
case *ast.AlterDomainStmt:
a.apply(n, "TypeName", nil, n.TypeName)
a.apply(n, "Def", nil, n.Def)
case *ast.AlterEnumStmt:
a.apply(n, "TypeName", nil, n.TypeName)
case *ast.AlterEventTrigStmt:
// pass
case *ast.AlterExtensionContentsStmt:
a.apply(n, "Object", nil, n.Object)
case *ast.AlterExtensionStmt:
a.apply(n, "Options", nil, n.Options)
case *ast.AlterFdwStmt:
a.apply(n, "FuncOptions", nil, n.FuncOptions)
a.apply(n, "Options", nil, n.Options)
case *ast.AlterForeignServerStmt:
a.apply(n, "Options", nil, n.Options)
case *ast.AlterFunctionStmt:
a.apply(n, "Func", nil, n.Func)
a.apply(n, "Actions", nil, n.Actions)
case *ast.AlterObjectDependsStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "Object", nil, n.Object)
a.apply(n, "Extname", nil, n.Extname)
case *ast.AlterObjectSchemaStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "Object", nil, n.Object)
case *ast.AlterOpFamilyStmt:
a.apply(n, "Opfamilyname", nil, n.Opfamilyname)
a.apply(n, "Items", nil, n.Items)
case *ast.AlterOperatorStmt:
a.apply(n, "Opername", nil, n.Opername)
a.apply(n, "Options", nil, n.Options)
case *ast.AlterOwnerStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "Object", nil, n.Object)
a.apply(n, "Newowner", nil, n.Newowner)
case *ast.AlterPolicyStmt:
a.apply(n, "Table", nil, n.Table)
a.apply(n, "Roles", nil, n.Roles)
a.apply(n, "Qual", nil, n.Qual)
a.apply(n, "WithCheck", nil, n.WithCheck)
case *ast.AlterPublicationStmt:
a.apply(n, "Options", nil, n.Options)
a.apply(n, "Tables", nil, n.Tables)
case *ast.AlterRoleSetStmt:
a.apply(n, "Role", nil, n.Role)
a.apply(n, "Setstmt", nil, n.Setstmt)
case *ast.AlterRoleStmt:
a.apply(n, "Role", nil, n.Role)
a.apply(n, "Options", nil, n.Options)
case *ast.AlterSeqStmt:
a.apply(n, "Sequence", nil, n.Sequence)
a.apply(n, "Options", nil, n.Options)
case *ast.AlterSubscriptionStmt:
a.apply(n, "Publication", nil, n.Publication)
a.apply(n, "Options", nil, n.Options)
case *ast.AlterSystemStmt:
a.apply(n, "Setstmt", nil, n.Setstmt)
case *ast.AlterTSConfigurationStmt:
a.apply(n, "Cfgname", nil, n.Cfgname)
a.apply(n, "Tokentype", nil, n.Tokentype)
a.apply(n, "Dicts", nil, n.Dicts)
case *ast.AlterTSDictionaryStmt:
a.apply(n, "Dictname", nil, n.Dictname)
a.apply(n, "Options", nil, n.Options)
case *ast.AlterTableCmd:
a.apply(n, "Newowner", nil, n.Newowner)
a.apply(n, "Def", nil, n.Def)
case *ast.AlterTableMoveAllStmt:
a.apply(n, "Roles", nil, n.Roles)
case *ast.AlterTableSpaceOptionsStmt:
a.apply(n, "Options", nil, n.Options)
case *ast.AlterTableStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "Table", nil, n.Table)
a.apply(n, "Cmds", nil, n.Cmds)
case *ast.AlterUserMappingStmt:
a.apply(n, "User", nil, n.User)
a.apply(n, "Options", nil, n.Options)
case *ast.AlternativeSubPlan:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Subplans", nil, n.Subplans)
case *ast.ArrayCoerceExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
case *ast.ArrayExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Elements", nil, n.Elements)
case *ast.ArrayRef:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Refupperindexpr", nil, n.Refupperindexpr)
a.apply(n, "Reflowerindexpr", nil, n.Reflowerindexpr)
a.apply(n, "Refexpr", nil, n.Refexpr)
a.apply(n, "Refassgnexpr", nil, n.Refassgnexpr)
case *ast.BetweenExpr:
a.apply(n, "Expr", nil, n.Expr)
a.apply(n, "Left", nil, n.Left)
a.apply(n, "Right", nil, n.Right)
case *ast.BitString:
// pass
case *ast.BlockIdData:
// pass
case *ast.Boolean:
// pass
case *ast.BoolExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Args", nil, n.Args)
case *ast.BooleanTest:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
case *ast.CallStmt:
a.apply(n, "FuncCall", nil, n.FuncCall)
case *ast.CaseExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
a.apply(n, "Args", nil, n.Args)
a.apply(n, "Defresult", nil, n.Defresult)
case *ast.CaseTestExpr:
a.apply(n, "Xpr", nil, n.Xpr)
case *ast.CaseWhen:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Expr", nil, n.Expr)
a.apply(n, "Result", nil, n.Result)
case *ast.CheckPointStmt:
// pass
case *ast.ClosePortalStmt:
// pass
case *ast.ClusterStmt:
a.apply(n, "Relation", nil, n.Relation)
case *ast.CoalesceExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Args", nil, n.Args)
case *ast.CoerceToDomain:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
case *ast.CoerceToDomainValue:
a.apply(n, "Xpr", nil, n.Xpr)
case *ast.CoerceViaIO:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
case *ast.CollateClause:
a.apply(n, "Arg", nil, n.Arg)
a.apply(n, "Collname", nil, n.Collname)
case *ast.CollateExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
case *ast.ColumnDef:
a.apply(n, "TypeName", nil, n.TypeName)
a.apply(n, "RawDefault", nil, n.RawDefault)
a.apply(n, "CookedDefault", nil, n.CookedDefault)
a.apply(n, "CollClause", nil, n.CollClause)
a.apply(n, "Constraints", nil, n.Constraints)
a.apply(n, "Fdwoptions", nil, n.Fdwoptions)
case *ast.ColumnRef:
a.apply(n, "Fields", nil, n.Fields)
case *ast.CommentStmt:
a.apply(n, "Object", nil, n.Object)
case *ast.CommonTableExpr:
a.apply(n, "Aliascolnames", nil, n.Aliascolnames)
a.apply(n, "Ctequery", nil, n.Ctequery)
a.apply(n, "Ctecolnames", nil, n.Ctecolnames)
a.apply(n, "Ctecoltypes", nil, n.Ctecoltypes)
a.apply(n, "Ctecoltypmods", nil, n.Ctecoltypmods)
a.apply(n, "Ctecolcollations", nil, n.Ctecolcollations)
case *ast.CompositeTypeStmt:
a.apply(n, "TypeName", nil, n.TypeName)
case *ast.Const:
a.apply(n, "Xpr", nil, n.Xpr)
case *ast.Constraint:
a.apply(n, "RawExpr", nil, n.RawExpr)
a.apply(n, "Keys", nil, n.Keys)
a.apply(n, "Exclusions", nil, n.Exclusions)
a.apply(n, "Options", nil, n.Options)
a.apply(n, "WhereClause", nil, n.WhereClause)
a.apply(n, "Pktable", nil, n.Pktable)
a.apply(n, "FkAttrs", nil, n.FkAttrs)
a.apply(n, "PkAttrs", nil, n.PkAttrs)
a.apply(n, "OldConpfeqop", nil, n.OldConpfeqop)
case *ast.ConstraintsSetStmt:
a.apply(n, "Constraints", nil, n.Constraints)
case *ast.ConvertRowtypeExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
case *ast.CopyStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "Query", nil, n.Query)
a.apply(n, "Attlist", nil, n.Attlist)
a.apply(n, "Options", nil, n.Options)
case *ast.CreateAmStmt:
a.apply(n, "HandlerName", nil, n.HandlerName)
case *ast.CreateCastStmt:
a.apply(n, "Sourcetype", nil, n.Sourcetype)
a.apply(n, "Targettype", nil, n.Targettype)
a.apply(n, "Func", nil, n.Func)
case *ast.CreateConversionStmt:
a.apply(n, "ConversionName", nil, n.ConversionName)
a.apply(n, "FuncName", nil, n.FuncName)
case *ast.CreateDomainStmt:
a.apply(n, "Domainname", nil, n.Domainname)
a.apply(n, "TypeName", nil, n.TypeName)
a.apply(n, "CollClause", nil, n.CollClause)
a.apply(n, "Constraints", nil, n.Constraints)
case *ast.CreateEnumStmt:
a.apply(n, "TypeName", nil, n.TypeName)
a.apply(n, "Vals", nil, n.Vals)
case *ast.CreateEventTrigStmt:
a.apply(n, "Whenclause", nil, n.Whenclause)
a.apply(n, "Funcname", nil, n.Funcname)
case *ast.CreateExtensionStmt:
a.apply(n, "Options", nil, n.Options)
case *ast.CreateFdwStmt:
a.apply(n, "FuncOptions", nil, n.FuncOptions)
a.apply(n, "Options", nil, n.Options)
case *ast.CreateForeignServerStmt:
a.apply(n, "Options", nil, n.Options)
case *ast.CreateForeignTableStmt:
a.apply(n, "Base", nil, n.Base)
a.apply(n, "Options", nil, n.Options)
case *ast.CreateFunctionStmt:
a.apply(n, "Func", nil, n.Func)
a.apply(n, "Params", nil, n.Params)
a.apply(n, "ReturnType", nil, n.ReturnType)
a.apply(n, "Options", nil, n.Options)
a.apply(n, "WithClause", nil, n.WithClause)
case *ast.CreateOpClassItem:
a.apply(n, "Name", nil, n.Name)
a.apply(n, "OrderFamily", nil, n.OrderFamily)
a.apply(n, "ClassArgs", nil, n.ClassArgs)
a.apply(n, "Storedtype", nil, n.Storedtype)
case *ast.CreateOpClassStmt:
a.apply(n, "Opclassname", nil, n.Opclassname)
a.apply(n, "Opfamilyname", nil, n.Opfamilyname)
a.apply(n, "Datatype", nil, n.Datatype)
a.apply(n, "Items", nil, n.Items)
case *ast.CreateOpFamilyStmt:
a.apply(n, "Opfamilyname", nil, n.Opfamilyname)
case *ast.CreatePLangStmt:
a.apply(n, "Plhandler", nil, n.Plhandler)
a.apply(n, "Plinline", nil, n.Plinline)
a.apply(n, "Plvalidator", nil, n.Plvalidator)
case *ast.CreatePolicyStmt:
a.apply(n, "Table", nil, n.Table)
a.apply(n, "Roles", nil, n.Roles)
a.apply(n, "Qual", nil, n.Qual)
a.apply(n, "WithCheck", nil, n.WithCheck)
case *ast.CreatePublicationStmt:
a.apply(n, "Options", nil, n.Options)
a.apply(n, "Tables", nil, n.Tables)
case *ast.CreateRangeStmt:
a.apply(n, "TypeName", nil, n.TypeName)
a.apply(n, "Params", nil, n.Params)
case *ast.CreateRoleStmt:
a.apply(n, "Options", nil, n.Options)
case *ast.CreateSchemaStmt:
a.apply(n, "Authrole", nil, n.Authrole)
a.apply(n, "SchemaElts", nil, n.SchemaElts)
case *ast.CreateSeqStmt:
a.apply(n, "Sequence", nil, n.Sequence)
a.apply(n, "Options", nil, n.Options)
case *ast.CreateStatsStmt:
a.apply(n, "Defnames", nil, n.Defnames)
a.apply(n, "StatTypes", nil, n.StatTypes)
a.apply(n, "Exprs", nil, n.Exprs)
a.apply(n, "Relations", nil, n.Relations)
case *ast.CreateStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "TableElts", nil, n.TableElts)
a.apply(n, "InhRelations", nil, n.InhRelations)
a.apply(n, "Partbound", nil, n.Partbound)
a.apply(n, "Partspec", nil, n.Partspec)
a.apply(n, "OfTypename", nil, n.OfTypename)
a.apply(n, "Constraints", nil, n.Constraints)
a.apply(n, "Options", nil, n.Options)
case *ast.CreateSubscriptionStmt:
a.apply(n, "Publication", nil, n.Publication)
a.apply(n, "Options", nil, n.Options)
case *ast.CreateTableAsStmt:
a.apply(n, "Query", nil, n.Query)
a.apply(n, "Into", nil, n.Into)
case *ast.CreateTableSpaceStmt:
a.apply(n, "Owner", nil, n.Owner)
a.apply(n, "Options", nil, n.Options)
case *ast.CreateTransformStmt:
a.apply(n, "TypeName", nil, n.TypeName)
a.apply(n, "Fromsql", nil, n.Fromsql)
a.apply(n, "Tosql", nil, n.Tosql)
case *ast.CreateTrigStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "Funcname", nil, n.Funcname)
a.apply(n, "Args", nil, n.Args)
a.apply(n, "Columns", nil, n.Columns)
a.apply(n, "WhenClause", nil, n.WhenClause)
a.apply(n, "TransitionRels", nil, n.TransitionRels)
a.apply(n, "Constrrel", nil, n.Constrrel)
case *ast.CreateUserMappingStmt:
a.apply(n, "User", nil, n.User)
a.apply(n, "Options", nil, n.Options)
case *ast.CreatedbStmt:
a.apply(n, "Options", nil, n.Options)
case *ast.CurrentOfExpr:
a.apply(n, "Xpr", nil, n.Xpr)
case *ast.DeallocateStmt:
// pass
case *ast.DeclareCursorStmt:
a.apply(n, "Query", nil, n.Query)
case *ast.DefElem:
a.apply(n, "Arg", nil, n.Arg)
case *ast.DefineStmt:
a.apply(n, "Defnames", nil, n.Defnames)
a.apply(n, "Args", nil, n.Args)
a.apply(n, "Definition", nil, n.Definition)
case *ast.DeleteStmt:
a.apply(n, "Relations", nil, n.Relations)
a.apply(n, "UsingClause", nil, n.UsingClause)
a.apply(n, "WhereClause", nil, n.WhereClause)
a.apply(n, "ReturningList", nil, n.ReturningList)
a.apply(n, "WithClause", nil, n.WithClause)
a.apply(n, "Targets", nil, n.Targets)
a.apply(n, "FromClause", nil, n.FromClause)
case *ast.DiscardStmt:
// pass
case *ast.DoStmt:
a.apply(n, "Args", nil, n.Args)
case *ast.DropOwnedStmt:
a.apply(n, "Roles", nil, n.Roles)
case *ast.DropRoleStmt:
a.apply(n, "Roles", nil, n.Roles)
case *ast.DropStmt:
a.apply(n, "Objects", nil, n.Objects)
case *ast.DropSubscriptionStmt:
// pass
case *ast.DropTableSpaceStmt:
// pass
case *ast.DropUserMappingStmt:
a.apply(n, "User", nil, n.User)
case *ast.DropdbStmt:
// pass
case *ast.ExecuteStmt:
a.apply(n, "Params", nil, n.Params)
case *ast.ExplainStmt:
a.apply(n, "Query", nil, n.Query)
a.apply(n, "Options", nil, n.Options)
case *ast.Expr:
// pass
case *ast.FetchStmt:
// pass
case *ast.FieldSelect:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
case *ast.FieldStore:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
a.apply(n, "Newvals", nil, n.Newvals)
a.apply(n, "Fieldnums", nil, n.Fieldnums)
case *ast.Float:
// pass
case *ast.FromExpr:
a.apply(n, "Fromlist", nil, n.Fromlist)
a.apply(n, "Quals", nil, n.Quals)
case *ast.FuncCall:
a.apply(n, "Func", nil, n.Func)
a.apply(n, "Funcname", nil, n.Funcname)
a.apply(n, "Args", nil, n.Args)
a.apply(n, "AggOrder", nil, n.AggOrder)
a.apply(n, "AggFilter", nil, n.AggFilter)
a.apply(n, "Over", nil, n.Over)
case *ast.FuncExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Args", nil, n.Args)
case *ast.FunctionParameter:
a.apply(n, "ArgType", nil, n.ArgType)
a.apply(n, "Defexpr", nil, n.Defexpr)
case *ast.GrantRoleStmt:
a.apply(n, "GrantedRoles", nil, n.GrantedRoles)
a.apply(n, "GranteeRoles", nil, n.GranteeRoles)
a.apply(n, "Grantor", nil, n.Grantor)
case *ast.GrantStmt:
a.apply(n, "Objects", nil, n.Objects)
a.apply(n, "Privileges", nil, n.Privileges)
a.apply(n, "Grantees", nil, n.Grantees)
case *ast.GroupingFunc:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Args", nil, n.Args)
a.apply(n, "Refs", nil, n.Refs)
a.apply(n, "Cols", nil, n.Cols)
case *ast.GroupingSet:
a.apply(n, "Content", nil, n.Content)
case *ast.ImportForeignSchemaStmt:
a.apply(n, "TableList", nil, n.TableList)
a.apply(n, "Options", nil, n.Options)
case *ast.IndexElem:
a.apply(n, "Expr", nil, n.Expr)
a.apply(n, "Collation", nil, n.Collation)
a.apply(n, "Opclass", nil, n.Opclass)
case *ast.IndexStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "IndexParams", nil, n.IndexParams)
a.apply(n, "Options", nil, n.Options)
a.apply(n, "WhereClause", nil, n.WhereClause)
a.apply(n, "ExcludeOpNames", nil, n.ExcludeOpNames)
case *ast.InferClause:
a.apply(n, "IndexElems", nil, n.IndexElems)
a.apply(n, "WhereClause", nil, n.WhereClause)
case *ast.InferenceElem:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Expr", nil, n.Expr)
case *ast.InlineCodeBlock:
// pass
case *ast.InsertStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "Cols", nil, n.Cols)
a.apply(n, "SelectStmt", nil, n.SelectStmt)
a.apply(n, "OnConflictClause", nil, n.OnConflictClause)
a.apply(n, "OnDuplicateKeyUpdate", nil, n.OnDuplicateKeyUpdate)
a.apply(n, "ReturningList", nil, n.ReturningList)
a.apply(n, "WithClause", nil, n.WithClause)
case *ast.Integer:
// pass
case *ast.IntervalExpr:
a.apply(n, "Value", nil, n.Value)
case *ast.IntoClause:
a.apply(n, "Rel", nil, n.Rel)
a.apply(n, "ColNames", nil, n.ColNames)
a.apply(n, "Options", nil, n.Options)
a.apply(n, "ViewQuery", nil, n.ViewQuery)
case *ast.JoinExpr:
a.apply(n, "Larg", nil, n.Larg)
a.apply(n, "Rarg", nil, n.Rarg)
a.apply(n, "UsingClause", nil, n.UsingClause)
a.apply(n, "Quals", nil, n.Quals)
a.apply(n, "Alias", nil, n.Alias)
case *ast.ListenStmt:
// pass
case *ast.LoadStmt:
// pass
case *ast.LockStmt:
a.apply(n, "Relations", nil, n.Relations)
case *ast.LockingClause:
a.apply(n, "LockedRels", nil, n.LockedRels)
case *ast.MinMaxExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Args", nil, n.Args)
case *ast.MultiAssignRef:
a.apply(n, "Source", nil, n.Source)
case *ast.NamedArgExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
case *ast.NextValueExpr:
a.apply(n, "Xpr", nil, n.Xpr)
case *ast.NotifyStmt:
// pass
case *ast.Null:
// pass
case *ast.NullTest:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
case *ast.ObjectWithArgs:
a.apply(n, "Objname", nil, n.Objname)
a.apply(n, "Objargs", nil, n.Objargs)
case *ast.OnConflictClause:
a.apply(n, "Infer", nil, n.Infer)
a.apply(n, "TargetList", nil, n.TargetList)
a.apply(n, "WhereClause", nil, n.WhereClause)
case *ast.OnConflictExpr:
a.apply(n, "ArbiterElems", nil, n.ArbiterElems)
a.apply(n, "ArbiterWhere", nil, n.ArbiterWhere)
a.apply(n, "OnConflictSet", nil, n.OnConflictSet)
a.apply(n, "OnConflictWhere", nil, n.OnConflictWhere)
a.apply(n, "ExclRelTlist", nil, n.ExclRelTlist)
case *ast.OnDuplicateKeyUpdate:
a.apply(n, "TargetList", nil, n.TargetList)
case *ast.OpExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Args", nil, n.Args)
case *ast.Param:
a.apply(n, "Xpr", nil, n.Xpr)
case *ast.ParamExecData:
// pass
case *ast.ParamExternData:
// pass
case *ast.ParamListInfoData:
// pass
case *ast.ParamRef:
// pass
case *ast.ParenExpr:
a.apply(n, "Expr", nil, n.Expr)
case *ast.VariableExpr:
// Leaf node - no children to traverse
case *ast.PartitionBoundSpec:
a.apply(n, "Listdatums", nil, n.Listdatums)
a.apply(n, "Lowerdatums", nil, n.Lowerdatums)
a.apply(n, "Upperdatums", nil, n.Upperdatums)
case *ast.PartitionCmd:
a.apply(n, "Name", nil, n.Name)
a.apply(n, "Bound", nil, n.Bound)
case *ast.PartitionElem:
a.apply(n, "Expr", nil, n.Expr)
a.apply(n, "Collation", nil, n.Collation)
a.apply(n, "Opclass", nil, n.Opclass)
case *ast.PartitionRangeDatum:
a.apply(n, "Value", nil, n.Value)
case *ast.PartitionSpec:
a.apply(n, "PartParams", nil, n.PartParams)
case *ast.PrepareStmt:
a.apply(n, "Argtypes", nil, n.Argtypes)
a.apply(n, "Query", nil, n.Query)
case *ast.Query:
a.apply(n, "UtilityStmt", nil, n.UtilityStmt)
a.apply(n, "CteList", nil, n.CteList)
a.apply(n, "Rtable", nil, n.Rtable)
a.apply(n, "Jointree", nil, n.Jointree)
a.apply(n, "TargetList", nil, n.TargetList)
a.apply(n, "OnConflict", nil, n.OnConflict)
a.apply(n, "ReturningList", nil, n.ReturningList)
a.apply(n, "GroupClause", nil, n.GroupClause)
a.apply(n, "GroupingSets", nil, n.GroupingSets)
a.apply(n, "HavingQual", nil, n.HavingQual)
a.apply(n, "WindowClause", nil, n.WindowClause)
a.apply(n, "DistinctClause", nil, n.DistinctClause)
a.apply(n, "SortClause", nil, n.SortClause)
a.apply(n, "LimitOffset", nil, n.LimitOffset)
a.apply(n, "LimitCount", nil, n.LimitCount)
a.apply(n, "RowMarks", nil, n.RowMarks)
a.apply(n, "SetOperations", nil, n.SetOperations)
a.apply(n, "ConstraintDeps", nil, n.ConstraintDeps)
a.apply(n, "WithCheckOptions", nil, n.WithCheckOptions)
case *ast.RangeFunction:
a.apply(n, "Functions", nil, n.Functions)
a.apply(n, "Alias", nil, n.Alias)
a.apply(n, "Coldeflist", nil, n.Coldeflist)
case *ast.RangeSubselect:
a.apply(n, "Subquery", nil, n.Subquery)
a.apply(n, "Alias", nil, n.Alias)
case *ast.RangeTableFunc:
a.apply(n, "Docexpr", nil, n.Docexpr)
a.apply(n, "Rowexpr", nil, n.Rowexpr)
a.apply(n, "Namespaces", nil, n.Namespaces)
a.apply(n, "Columns", nil, n.Columns)
a.apply(n, "Alias", nil, n.Alias)
case *ast.RangeTableFuncCol:
a.apply(n, "TypeName", nil, n.TypeName)
a.apply(n, "Colexpr", nil, n.Colexpr)
a.apply(n, "Coldefexpr", nil, n.Coldefexpr)
case *ast.RangeTableSample:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "Method", nil, n.Method)
a.apply(n, "Args", nil, n.Args)
a.apply(n, "Repeatable", nil, n.Repeatable)
case *ast.RangeTblEntry:
a.apply(n, "Tablesample", nil, n.Tablesample)
a.apply(n, "Subquery", nil, n.Subquery)
a.apply(n, "Joinaliasvars", nil, n.Joinaliasvars)
a.apply(n, "Functions", nil, n.Functions)
a.apply(n, "Tablefunc", nil, n.Tablefunc)
a.apply(n, "ValuesLists", nil, n.ValuesLists)
a.apply(n, "Coltypes", nil, n.Coltypes)
a.apply(n, "Coltypmods", nil, n.Coltypmods)
a.apply(n, "Colcollations", nil, n.Colcollations)
a.apply(n, "Alias", nil, n.Alias)
a.apply(n, "Eref", nil, n.Eref)
a.apply(n, "SecurityQuals", nil, n.SecurityQuals)
case *ast.RangeTblFunction:
a.apply(n, "Funcexpr", nil, n.Funcexpr)
a.apply(n, "Funccolnames", nil, n.Funccolnames)
a.apply(n, "Funccoltypes", nil, n.Funccoltypes)
a.apply(n, "Funccoltypmods", nil, n.Funccoltypmods)
a.apply(n, "Funccolcollations", nil, n.Funccolcollations)
case *ast.RangeTblRef:
// pass
case *ast.RangeVar:
a.apply(n, "Alias", nil, n.Alias)
case *ast.ReassignOwnedStmt:
a.apply(n, "Roles", nil, n.Roles)
a.apply(n, "Newrole", nil, n.Newrole)
case *ast.RefreshMatViewStmt:
a.apply(n, "Relation", nil, n.Relation)
case *ast.ReindexStmt:
a.apply(n, "Relation", nil, n.Relation)
case *ast.RelabelType:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Arg", nil, n.Arg)
case *ast.RenameStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "Object", nil, n.Object)
case *ast.ReplicaIdentityStmt:
// pass
case *ast.ResTarget:
a.apply(n, "Indirection", nil, n.Indirection)
a.apply(n, "Val", nil, n.Val)
case *ast.RoleSpec:
// pass
case *ast.RowCompareExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Opnos", nil, n.Opnos)
a.apply(n, "Opfamilies", nil, n.Opfamilies)
a.apply(n, "Inputcollids", nil, n.Inputcollids)
a.apply(n, "Largs", nil, n.Largs)
a.apply(n, "Rargs", nil, n.Rargs)
case *ast.RowExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Args", nil, n.Args)
a.apply(n, "Colnames", nil, n.Colnames)
case *ast.RowMarkClause:
// pass
case *ast.RuleStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "WhereClause", nil, n.WhereClause)
a.apply(n, "Actions", nil, n.Actions)
case *ast.SQLValueFunction:
a.apply(n, "Xpr", nil, n.Xpr)
case *ast.ScalarArrayOpExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Args", nil, n.Args)
case *ast.SecLabelStmt:
a.apply(n, "Object", nil, n.Object)
case *ast.SelectStmt:
a.apply(n, "DistinctClause", nil, n.DistinctClause)
a.apply(n, "IntoClause", nil, n.IntoClause)
a.apply(n, "TargetList", nil, n.TargetList)
a.apply(n, "FromClause", nil, n.FromClause)
a.apply(n, "WhereClause", nil, n.WhereClause)
a.apply(n, "GroupClause", nil, n.GroupClause)
a.apply(n, "HavingClause", nil, n.HavingClause)
a.apply(n, "WindowClause", nil, n.WindowClause)
a.apply(n, "ValuesLists", nil, n.ValuesLists)
a.apply(n, "SortClause", nil, n.SortClause)
a.apply(n, "LimitOffset", nil, n.LimitOffset)
a.apply(n, "LimitCount", nil, n.LimitCount)
a.apply(n, "LockingClause", nil, n.LockingClause)
a.apply(n, "WithClause", nil, n.WithClause)
a.apply(n, "Larg", nil, n.Larg)
a.apply(n, "Rarg", nil, n.Rarg)
case *ast.SetOperationStmt:
a.apply(n, "Larg", nil, n.Larg)
a.apply(n, "Rarg", nil, n.Rarg)
a.apply(n, "ColTypes", nil, n.ColTypes)
a.apply(n, "ColTypmods", nil, n.ColTypmods)
a.apply(n, "ColCollations", nil, n.ColCollations)
a.apply(n, "GroupClauses", nil, n.GroupClauses)
case *ast.SetToDefault:
a.apply(n, "Xpr", nil, n.Xpr)
case *ast.SortBy:
a.apply(n, "Node", nil, n.Node)
a.apply(n, "UseOp", nil, n.UseOp)
case *ast.SortGroupClause:
// pass
case *ast.SubLink:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Testexpr", nil, n.Testexpr)
a.apply(n, "OperName", nil, n.OperName)
a.apply(n, "Subselect", nil, n.Subselect)
case *ast.SubPlan:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Testexpr", nil, n.Testexpr)
a.apply(n, "ParamIds", nil, n.ParamIds)
a.apply(n, "SetParam", nil, n.SetParam)
a.apply(n, "ParParam", nil, n.ParParam)
a.apply(n, "Args", nil, n.Args)
case *ast.TableFunc:
a.apply(n, "NsUris", nil, n.NsUris)
a.apply(n, "NsNames", nil, n.NsNames)
a.apply(n, "Docexpr", nil, n.Docexpr)
a.apply(n, "Rowexpr", nil, n.Rowexpr)
a.apply(n, "Colnames", nil, n.Colnames)
a.apply(n, "Coltypes", nil, n.Coltypes)
a.apply(n, "Coltypmods", nil, n.Coltypmods)
a.apply(n, "Colcollations", nil, n.Colcollations)
a.apply(n, "Colexprs", nil, n.Colexprs)
a.apply(n, "Coldefexprs", nil, n.Coldefexprs)
case *ast.TableLikeClause:
a.apply(n, "Relation", nil, n.Relation)
case *ast.TableSampleClause:
a.apply(n, "Args", nil, n.Args)
a.apply(n, "Repeatable", nil, n.Repeatable)
case *ast.TargetEntry:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Expr", nil, n.Expr)
case *ast.TransactionStmt:
a.apply(n, "Options", nil, n.Options)
case *ast.TriggerTransition:
// pass
case *ast.TruncateStmt:
a.apply(n, "Relations", nil, n.Relations)
case *ast.TypeCast:
a.apply(n, "Arg", nil, n.Arg)
a.apply(n, "TypeName", nil, n.TypeName)
case *ast.TypeName:
a.apply(n, "Names", nil, n.Names)
a.apply(n, "Typmods", nil, n.Typmods)
a.apply(n, "ArrayBounds", nil, n.ArrayBounds)
case *ast.UnlistenStmt:
// pass
case *ast.UpdateStmt:
a.apply(n, "Relations", nil, n.Relations)
a.apply(n, "TargetList", nil, n.TargetList)
a.apply(n, "WhereClause", nil, n.WhereClause)
a.apply(n, "FromClause", nil, n.FromClause)
a.apply(n, "ReturningList", nil, n.ReturningList)
a.apply(n, "WithClause", nil, n.WithClause)
case *ast.VacuumStmt:
a.apply(n, "Relation", nil, n.Relation)
a.apply(n, "VaCols", nil, n.VaCols)
case *ast.Var:
a.apply(n, "Xpr", nil, n.Xpr)
case *ast.VariableSetStmt:
a.apply(n, "Args", nil, n.Args)
case *ast.VariableShowStmt:
// pass
case *ast.ViewStmt:
a.apply(n, "View", nil, n.View)
a.apply(n, "Aliases", nil, n.Aliases)
a.apply(n, "Query", nil, n.Query)
a.apply(n, "Options", nil, n.Options)
case *ast.WindowClause:
a.apply(n, "PartitionClause", nil, n.PartitionClause)
a.apply(n, "OrderClause", nil, n.OrderClause)
a.apply(n, "StartOffset", nil, n.StartOffset)
a.apply(n, "EndOffset", nil, n.EndOffset)
case *ast.WindowDef:
a.apply(n, "PartitionClause", nil, n.PartitionClause)
a.apply(n, "OrderClause", nil, n.OrderClause)
a.apply(n, "StartOffset", nil, n.StartOffset)
a.apply(n, "EndOffset", nil, n.EndOffset)
case *ast.WindowFunc:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "Args", nil, n.Args)
a.apply(n, "Aggfilter", nil, n.Aggfilter)
case *ast.WithCheckOption:
a.apply(n, "Qual", nil, n.Qual)
case *ast.WithClause:
a.apply(n, "Ctes", nil, n.Ctes)
case *ast.XmlExpr:
a.apply(n, "Xpr", nil, n.Xpr)
a.apply(n, "NamedArgs", nil, n.NamedArgs)
a.apply(n, "ArgNames", nil, n.ArgNames)
a.apply(n, "Args", nil, n.Args)
case *ast.XmlSerialize:
a.apply(n, "Expr", nil, n.Expr)
a.apply(n, "TypeName", nil, n.TypeName)
// Comments and fields
default:
panic(fmt.Sprintf("Apply: unexpected node type %T", n))
}
if a.post != nil && !a.post(&a.cursor) {
panic(abort)
}
a.cursor = saved
}
// An iterator controls iteration over a slice of nodes.
type iterator struct {
index, step int
}
func (a *application) applyList(parent ast.Node, name string) {
// avoid heap-allocating a new iterator for each applyList call; reuse a.iter instead
saved := a.iter
a.iter.index = 0
for {
// must reload parent.name each time, since cursor modifications might change it
v := reflect.Indirect(reflect.ValueOf(parent)).FieldByName(name)
if a.iter.index >= v.Len() {
break
}
// element x may be nil in a bad AST - be cautious
var x ast.Node
if e := v.Index(a.iter.index); e.IsValid() {
x = e.Interface().(ast.Node)
}
a.iter.step = 1
a.apply(parent, name, &a.iter, x)
a.iter.index += a.iter.step
}
a.iter = saved
}