@@ -73,209 +73,131 @@ func (a aggfuncs) tmp() string {
7373}
7474
7575func (a * aggfuncs ) subst (e sem.Expr ) sem.Expr {
76- switch e := e .(type ) {
77- case nil :
78- return e
79- case * sem.AggFunc :
80- // swap in a temp column for each agg function found, which
81- // will then be referred to by the containing expression.
82- // The agg function is computed into the tmp value with
83- // the generated aggregate operator.
84- tmp := a .tmp ()
85- * a = append (* a , namedAgg {name : tmp , agg : e })
86- return sem .NewThis (e , []string {"in" , tmp })
87- case * sem.ArrayExpr :
88- e .Elems = a .substArrayElems (e .Elems )
89- case * sem.BadExpr :
90- case * sem.BinaryExpr :
91- e .LHS = a .subst (e .LHS )
92- e .RHS = a .subst (e .RHS )
93- case * sem.CallExpr :
94- for k , arg := range e .Args {
95- e .Args [k ] = a .subst (arg )
96- }
97- case * sem.CondExpr :
98- e .Cond = a .subst (e .Cond )
99- e .Then = a .subst (e .Then )
100- e .Else = a .subst (e .Else )
101- case * sem.DotExpr :
102- e .LHS = a .subst (e .LHS )
103- case * sem.IndexExpr :
104- e .Expr = a .subst (e .Expr )
105- e .Index = a .subst (e .Index )
106- case * sem.IsNullExpr :
107- e .Expr = a .subst (e .Expr )
108- case * sem.LiteralExpr :
109- case * sem.MapExpr :
110- for _ , ent := range e .Entries {
111- ent .Key = a .subst (ent .Key )
112- ent .Value = a .subst (ent .Value )
113- }
114- case * sem.RecordExpr :
115- var elems []sem.RecordElem
116- for _ , elem := range e .Elems {
117- switch elem := elem .(type ) {
118- case * sem.FieldElem :
119- sub := a .subst (elem .Value )
120- elems = append (elems , & sem.FieldElem {Node : elem , Name : elem .Name , Value : sub })
121- case * sem.SpreadElem :
122- elems = append (elems , & sem.SpreadElem {Node : elem , Expr : a .subst (elem .Expr )})
123- default :
124- panic (elem )
125- }
76+ return exprWalk (e , func (e sem.Expr ) (sem.Expr , bool ) {
77+ switch e := e .(type ) {
78+ case * sem.AggFunc :
79+ // swap in a temp column for each agg function found, which
80+ // will then be referred to by the containing expression.
81+ // The agg function is computed into the tmp value with
82+ // the generated aggregate operator.
83+ tmp := a .tmp ()
84+ * a = append (* a , namedAgg {name : tmp , agg : e })
85+ return sem .NewThis (e , []string {"in" , tmp }), true
86+ default :
87+ return e , false
12688 }
127- e .Elems = elems
128- case * sem.RegexpMatchExpr :
129- e .Expr = a .subst (e .Expr )
130- case * sem.RegexpSearchExpr :
131- e .Expr = a .subst (e .Expr )
132- case * sem.SearchTermExpr :
133- e .Expr = a .subst (e .Expr )
134- case * sem.SetExpr :
135- e .Elems = a .substArrayElems (e .Elems )
136- case * sem.SliceExpr :
137- e .Expr = a .subst (e .Expr )
138- e .From = a .subst (e .From )
139- e .To = a .subst (e .To )
140- case * sem.ThisExpr :
141- case * sem.UnaryExpr :
142- e .Operand = a .subst (e .Operand )
143- }
144- return e
89+ })
14590}
14691
147- func (a * aggfuncs ) substArrayElems (elems []sem.ArrayElem ) []sem.ArrayElem {
148- var out []sem.ArrayElem
149- for _ , e := range elems {
92+ func keySubst (e sem.Expr , exprs []exprloc ) (sem.Expr , bool ) {
93+ ok := true
94+ e = exprWalk (e , func (e sem.Expr ) (sem.Expr , bool ) {
95+ if i := exprMatch (e , exprs ); i >= 0 {
96+ return sem .NewThis (e , []string {"in" , fmt .Sprintf ("k%d" , i )}), true
97+ }
15098 switch e := e .(type ) {
151- case * sem.SpreadElem :
152- out = append (out , & sem.SpreadElem {Node : e , Expr : a .subst (e .Expr )})
153- case * sem.ExprElem :
154- out = append (out , & sem.ExprElem {Node : e , Expr : a .subst (e .Expr )})
155- default :
99+ case * sem.ThisExpr :
100+ ok = false
101+ case * sem.AggFunc :
102+ // This should't happen.
156103 panic (e )
157104 }
158- }
159- return out
105+ return e , false
106+ })
107+ return e , ok
160108}
161109
162- func keySubst (e sem.Expr , exprs []exprloc ) (sem.Expr , bool ) {
163- if i := exprMatch (e , exprs ); i >= 0 {
164- return sem .NewThis (e , []string {"in" , fmt .Sprintf ("k%d" , i )}), true
110+ type exprVisitor func (e sem.Expr ) (sem.Expr , bool )
111+
112+ func exprWalk (e sem.Expr , visit exprVisitor ) sem.Expr {
113+ var stop bool
114+ if e , stop = visit (e ); stop {
115+ return e
165116 }
166- ok := true
167117 switch e := e .(type ) {
168118 case nil :
169119 case * sem.AggFunc :
170- // This shouldn't happen.
171- panic ( e )
120+ e . Expr = exprWalk ( e , visit )
121+ e . Where = exprWalk ( e , visit )
172122 case * sem.ArrayExpr :
173- e .Elems , ok = keySubstArrayElems (e .Elems , exprs )
123+ e .Elems = exprWalkArrayElems (e .Elems , visit )
174124 case * sem.BadExpr :
175125 case * sem.BinaryExpr :
176- if e .LHS , ok = keySubst (e .LHS , exprs ); ok {
177- e .RHS , ok = keySubst (e .RHS , exprs )
178- }
126+ e .LHS = exprWalk (e .LHS , visit )
127+ e .RHS = exprWalk (e .RHS , visit )
179128 case * sem.CallExpr :
180- var args []sem.Expr
129+ var out []sem.Expr
181130 for _ , arg := range e .Args {
182- if arg , ok = keySubst (arg , exprs ); ! ok {
183- return nil , false
184- }
185- args = append (args , arg )
131+ out = append (out , exprWalk (arg , visit ))
186132 }
187- e .Args = args
133+ e .Args = out
188134 case * sem.CondExpr :
189- var ok1 , ok2 , ok3 bool
190- e .Cond , ok1 = keySubst (e .Cond , exprs )
191- e .Then , ok2 = keySubst (e .Then , exprs )
192- e .Else , ok3 = keySubst (e .Else , exprs )
193- ok = ok1 && ok2 && ok3
135+ e .Cond = exprWalk (e .Cond , visit )
136+ e .Then = exprWalk (e .Then , visit )
137+ e .Else = exprWalk (e .Else , visit )
194138 case * sem.DotExpr :
195- e .LHS , ok = keySubst (e .LHS , exprs )
139+ e .LHS = exprWalk (e .LHS , visit )
196140 case * sem.IndexExpr :
197- if e .Expr , ok = keySubst (e .Expr , exprs ); ok {
198- e .Index , ok = keySubst (e .Index , exprs )
199- }
141+ e .Expr = exprWalk (e .Expr , visit )
142+ e .Index = exprWalk (e .Index , visit )
200143 case * sem.IsNullExpr :
201- e .Expr , ok = keySubst (e .Expr , exprs )
144+ e .Expr = exprWalk (e .Expr , visit )
202145 case * sem.LiteralExpr :
203146 case * sem.MapExpr :
204147 for _ , ent := range e .Entries {
205- if ent .Key , ok = keySubst (ent .Key , exprs ); ! ok {
206- break
207- }
208- if ent .Value , ok = keySubst (ent .Value , exprs ); ! ok {
209- break
210- }
148+ ent .Key = exprWalk (ent .Key , visit )
149+ ent .Value = exprWalk (ent .Value , visit )
211150 }
212151 case * sem.RecordExpr :
213- var elems []sem.RecordElem
152+ var out []sem.RecordElem
214153 for _ , elem := range e .Elems {
215154 switch elem := elem .(type ) {
216155 case * sem.FieldElem :
217- e , ok := keySubst (elem .Value , exprs )
218- if ! ok {
219- return nil , false
220- }
221- elems = append (elems , & sem.FieldElem {Node : elem , Name : elem .Name , Value : e })
156+ e := exprWalk (elem .Value , visit )
157+ out = append (out , & sem.FieldElem {Node : elem , Name : elem .Name , Value : e })
222158 case * sem.SpreadElem :
223- e , ok := keySubst (elem .Expr , exprs )
224- if ! ok {
225- return nil , false
226- }
227- elems = append (elems , & sem.SpreadElem {Node : elem , Expr : e })
159+ e := exprWalk (elem .Expr , visit )
160+ out = append (out , & sem.SpreadElem {Node : elem , Expr : e })
228161 default :
229162 panic (elem )
230163 }
231164 }
232- e .Elems = elems
165+ e .Elems = out
233166 case * sem.RegexpMatchExpr :
234- e .Expr , ok = keySubst (e .Expr , exprs )
167+ e .Expr = exprWalk (e .Expr , visit )
235168 case * sem.RegexpSearchExpr :
236- e .Expr , ok = keySubst (e .Expr , exprs )
169+ e .Expr = exprWalk (e .Expr , visit )
237170 case * sem.SearchTermExpr :
238- e .Expr , ok = keySubst (e .Expr , exprs )
171+ e .Expr = exprWalk (e .Expr , visit )
239172 case * sem.SetExpr :
240- e .Elems , ok = keySubstArrayElems (e .Elems , exprs )
173+ e .Elems = exprWalkArrayElems (e .Elems , visit )
241174 case * sem.SliceExpr :
242- var ok1 , ok2 , ok3 bool
243- e .Expr , ok1 = keySubst (e .Expr , exprs )
244- e .From , ok2 = keySubst (e .From , exprs )
245- e .To , ok3 = keySubst (e .To , exprs )
246- ok = ok1 && ok2 && ok3
175+ e .Expr = exprWalk (e .Expr , visit )
176+ e .From = exprWalk (e .From , visit )
177+ e .To = exprWalk (e .To , visit )
247178 case * sem.SubqueryExpr : // XXX This might need to be traversed?
248179 case * sem.ThisExpr :
249- // If we've gotten here it means we have a portion of e that does
250- // not exist in exprs so we are in an error state.
251- return nil , false
252180 case * sem.UnaryExpr :
253- e .Operand , ok = keySubst (e .Operand , exprs )
181+ e .Operand = exprWalk (e .Operand , visit )
254182 default :
255183 panic (e )
256184 }
257- return e , ok
185+ return e
258186}
259187
260- func keySubstArrayElems (elems []sem.ArrayElem , exprs [] exprloc ) ( []sem.ArrayElem , bool ) {
188+ func exprWalkArrayElems (elems []sem.ArrayElem , visit exprVisitor ) []sem.ArrayElem {
261189 var out []sem.ArrayElem
262190 for _ , elem := range elems {
263191 switch elem := elem .(type ) {
264192 case * sem.SpreadElem :
265- e , ok := keySubst (elem .Expr , exprs )
266- if ! ok {
267- return nil , false
268- }
269- out = append (out , & sem.SpreadElem {Node : elem , Expr : e })
193+ e := exprWalk (elem .Expr , visit )
194+ out = append (out , & sem.SpreadElem {Node : elem .Node , Expr : e })
270195 case * sem.ExprElem :
271- e , ok := keySubst (elem .Expr , exprs )
272- if ! ok {
273- return nil , false
274- }
275- out = append (out , & sem.ExprElem {Node : elem , Expr : e })
196+ e := exprWalk (elem .Expr , visit )
197+ out = append (out , & sem.ExprElem {Node : elem .Node , Expr : e })
276198 default :
277199 panic (elem )
278200 }
279201 }
280- return out , true
202+ return out
281203}
0 commit comments