@@ -42,9 +42,13 @@ type EvalBaseContext struct {
4242// @ctx is the evaluation context ie the variables/values which the expression will be
4343// evaluated against. It may be a simple reader of message/data or any
4444// object whhich implements EvalContext.
45- func Eval (ctx expr.EvalContext , arg expr.Node ) (value.Value , bool ) {
45+ func Eval (eCtx expr.EvalContext , arg expr.Node ) (value.Value , bool ) {
4646 // Initialize a visited includes stack of 10
47- return evalDepth (ctx , arg , 0 , make ([]string , 0 , 10 ))
47+ return evalDepth (eCtx , nil , arg , 0 , make ([]string , 0 , 10 ))
48+ }
49+ func EvalInc (includer expr.Includer , eCtx expr.EvalContext , arg expr.Node ) (value.Value , bool ) {
50+ // Initialize a visited includes stack of 10
51+ return evalDepth (eCtx , includer , arg , 0 , make ([]string , 0 , 10 ))
4852}
4953
5054// creates a new Value with a nil group and given value.
@@ -117,8 +121,8 @@ func resolveIncludesDepth(ctx expr.Includer, arg expr.Node, depth int, visitedIn
117121 return nil
118122}
119123
120- func evalBool (ctx expr.EvalContext , arg expr.Node , depth int , visitedIncludes []string ) (bool , bool ) {
121- val , ok := evalDepth (ctx , arg , depth , visitedIncludes )
124+ func evalBool (ctx expr.EvalContext , includer expr. Includer , arg expr.Node , depth int , visitedIncludes []string ) (bool , bool ) {
125+ val , ok := evalDepth (ctx , includer , arg , depth , visitedIncludes )
122126 if ! ok || val == nil {
123127 return false , false
124128 }
@@ -128,7 +132,7 @@ func evalBool(ctx expr.EvalContext, arg expr.Node, depth int, visitedIncludes []
128132 return false , false
129133}
130134
131- func evalDepth (ctx expr.EvalContext , arg expr.Node , depth int , visitedIncludes []string ) (value.Value , bool ) {
135+ func evalDepth (ctx expr.EvalContext , includer expr. Includer , arg expr.Node , depth int , visitedIncludes []string ) (value.Value , bool ) {
132136 if depth > MaxDepth {
133137 return nil , false
134138 }
@@ -137,17 +141,17 @@ func evalDepth(ctx expr.EvalContext, arg expr.Node, depth int, visitedIncludes [
137141 case * expr.NumberNode :
138142 return numberNodeToValue (argVal )
139143 case * expr.BinaryNode :
140- return evalBinary (ctx , argVal , depth , visitedIncludes )
144+ return evalBinary (ctx , includer , argVal , depth , visitedIncludes )
141145 case * expr.BooleanNode :
142- return walkBoolean (ctx , argVal , depth , visitedIncludes )
146+ return walkBoolean (ctx , includer , argVal , depth , visitedIncludes )
143147 case * expr.UnaryNode :
144- return walkUnary (ctx , argVal , depth , visitedIncludes )
148+ return walkUnary (ctx , includer , argVal , depth , visitedIncludes )
145149 case * expr.TriNode :
146- return walkTernary (ctx , argVal , depth , visitedIncludes )
150+ return walkTernary (ctx , includer , argVal , depth , visitedIncludes )
147151 case * expr.ArrayNode :
148- return walkArray (ctx , argVal , depth , visitedIncludes )
152+ return walkArray (ctx , includer , argVal , depth , visitedIncludes )
149153 case * expr.FuncNode :
150- return walkFunc (ctx , argVal , depth , visitedIncludes )
154+ return walkFunc (ctx , includer , argVal , depth , visitedIncludes )
151155 case * expr.IdentityNode :
152156 return walkIdentity (ctx , argVal )
153157 case * expr.StringNode :
@@ -158,7 +162,7 @@ func evalDepth(ctx expr.EvalContext, arg expr.Node, depth int, visitedIncludes [
158162 // WHERE (`users.user_id` != NULL)
159163 return value .NewNilValue (), true
160164 case * expr.IncludeNode :
161- return walkInclude (ctx , argVal , depth + 1 , visitedIncludes )
165+ return walkInclude (ctx , includer , argVal , depth + 1 , visitedIncludes )
162166 case * expr.ValueNode :
163167 if argVal .Value == nil {
164168 return nil , false
@@ -210,49 +214,10 @@ func resolveInclude(ctx expr.Includer, inc *expr.IncludeNode, depth int, visited
210214
211215var errFailedInclusion = errors .New ("failed inclusion" )
212216
213- func walkInclude (ctx expr.EvalContext , inc * expr.IncludeNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
217+ func walkInclude (ctx expr.EvalContext , includer expr. Includer , inc * expr.IncludeNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
214218 var matches , ok bool
215219 var err error
216220 var cachedValue expr.CachedValue
217- if cacheCtx , hasCacheCtx := ctx .(expr.IncludeCacheContextV2 ); hasCacheCtx {
218- matches , err := cacheCtx .GetOrSet (inc .Identity .Text , func () (bool , error ) {
219- if inc .ExprNode == nil {
220- incCtx , ok := ctx .(expr.EvalIncludeContext )
221- if ! ok {
222- return false , fmt .Errorf ("no Includer context? %T stack:%v" , ctx , u .PrettyStack (14 ))
223- }
224- if err := resolveInclude (incCtx , inc , depth , visitedIncludes ); err != nil {
225- return false , fmt .Errorf ("could not resolve include %w" , err )
226- }
227- }
228-
229- switch exp := inc .ExprNode .(type ) {
230- case * expr.IdentityNode :
231- if exp .Text == "*" || exp .Text == "match_all" {
232- return true , nil
233- }
234- }
235-
236- matches , ok = evalBool (ctx , inc .ExprNode , depth + 1 , visitedIncludes )
237- if ! ok {
238- return matches , errFailedInclusion
239- }
240- return matches , nil
241- })
242- if errors .Is (err , errFailedInclusion ) {
243- if inc .Negated () {
244- return value .NewBoolValue (true ), true
245- }
246- return nil , false
247- } else if err != nil {
248- u .Errorf ("failed to get or set include in cache: %v" , err )
249- return nil , false
250- }
251- if inc .Negated () {
252- return value .NewBoolValue (! matches ), true
253- }
254- return value .NewBoolValue (matches ), true
255- }
256221 if cacheCtx , hasCacheCtx := ctx .(expr.IncludeCacheContext ); hasCacheCtx {
257222 var hasCachedValue bool
258223 cachedValue , hasCachedValue = cacheCtx .GetCachedValue (inc .Identity .Text )
@@ -264,24 +229,33 @@ func walkInclude(ctx expr.EvalContext, inc *expr.IncludeNode, depth int, visited
264229 }
265230 if err != nil || cachedValue == nil {
266231 if inc .ExprNode == nil {
267- incCtx , ok := ctx .(expr.EvalIncludeContext )
268- if ! ok {
269- u .Errorf ("No Includer context? %T stack:%v" , ctx , u .PrettyStack (14 ))
270- return nil , false
271- }
272- if err := resolveInclude (incCtx , inc , depth , visitedIncludes ); err != nil {
273- return nil , false
232+ if includer != nil {
233+ if err := resolveInclude (includer , inc , depth , visitedIncludes ); err != nil {
234+ return nil , false
235+ }
236+ } else {
237+ incCtx , ok := ctx .(expr.EvalIncludeContext )
238+ if ! ok {
239+ u .Errorf ("No Includer context? %T stack:%v" , ctx , u .PrettyStack (14 ))
240+ return nil , false
241+ }
242+ if err := resolveInclude (incCtx , inc , depth , visitedIncludes ); err != nil {
243+ return nil , false
244+ }
274245 }
275246 }
276247
277248 switch exp := inc .ExprNode .(type ) {
278249 case * expr.IdentityNode :
279250 if exp .Text == "*" || exp .Text == "match_all" {
251+ if cachedValue != nil {
252+ cachedValue .Set (true , true )
253+ }
280254 return value .NewBoolValue (true ), true
281255 }
282256 }
283257
284- matches , ok = evalBool (ctx , inc .ExprNode , depth + 1 , visitedIncludes )
258+ matches , ok = evalBool (ctx , includer , inc .ExprNode , depth + 1 , visitedIncludes )
285259 if cachedValue != nil {
286260 cachedValue .Set (matches , ok )
287261 }
@@ -298,7 +272,7 @@ func walkInclude(ctx expr.EvalContext, inc *expr.IncludeNode, depth int, visited
298272 return value .NewBoolValue (matches ), true
299273}
300274
301- func walkBoolean (ctx expr.EvalContext , n * expr.BooleanNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
275+ func walkBoolean (ctx expr.EvalContext , includer expr. Includer , n * expr.BooleanNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
302276 if depth > MaxDepth {
303277 u .Warnf ("Recursive query death? %v" , n )
304278 return nil , false
@@ -316,7 +290,7 @@ func walkBoolean(ctx expr.EvalContext, n *expr.BooleanNode, depth int, visitedIn
316290
317291 for _ , bn := range n .Args {
318292
319- matches , ok := evalBool (ctx , bn , depth + 1 , visitedIncludes )
293+ matches , ok := evalBool (ctx , includer , bn , depth + 1 , visitedIncludes )
320294 if ! ok && and {
321295 return nil , false
322296 } else if ! ok {
@@ -353,9 +327,9 @@ func walkBoolean(ctx expr.EvalContext, n *expr.BooleanNode, depth int, visitedIn
353327// x OR y
354328// x > y
355329// x < =
356- func evalBinary (ctx expr.EvalContext , node * expr.BinaryNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
357- ar , aok := evalDepth (ctx , node .Args [0 ], depth + 1 , visitedIncludes )
358- br , bok := evalDepth (ctx , node .Args [1 ], depth + 1 , visitedIncludes )
330+ func evalBinary (ctx expr.EvalContext , includer expr. Includer , node * expr.BinaryNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
331+ ar , aok := evalDepth (ctx , includer , node .Args [0 ], depth + 1 , visitedIncludes )
332+ br , bok := evalDepth (ctx , includer , node .Args [1 ], depth + 1 , visitedIncludes )
359333
360334 // If we could not evaluate either we can shortcut
361335 if ! aok && ! bok {
@@ -843,9 +817,9 @@ func walkIdentity(ctx expr.EvalContext, node *expr.IdentityNode) (value.Value, b
843817 return ctx .Get (node .Text )
844818}
845819
846- func walkUnary (ctx expr.EvalContext , node * expr.UnaryNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
820+ func walkUnary (ctx expr.EvalContext , includer expr. Includer , node * expr.UnaryNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
847821
848- a , ok := evalDepth (ctx , node .Arg , depth , visitedIncludes )
822+ a , ok := evalDepth (ctx , includer , node .Arg , depth , visitedIncludes )
849823 if ! ok {
850824 switch node .Operator .T {
851825 case lex .TokenExists :
@@ -890,17 +864,17 @@ func walkUnary(ctx expr.EvalContext, node *expr.UnaryNode, depth int, visitedInc
890864// walkTernary ternary evaluator
891865//
892866// A BETWEEN B AND C
893- func walkTernary (ctx expr.EvalContext , node * expr.TriNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
867+ func walkTernary (ctx expr.EvalContext , includer expr. Includer , node * expr.TriNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
894868
895- a , aok := evalDepth (ctx , node .Args [0 ], depth , visitedIncludes )
869+ a , aok := evalDepth (ctx , includer , node .Args [0 ], depth , visitedIncludes )
896870 if a == nil || ! aok {
897871 return nil , false
898872 }
899- b , bok := evalDepth (ctx , node .Args [1 ], depth , visitedIncludes )
873+ b , bok := evalDepth (ctx , includer , node .Args [1 ], depth , visitedIncludes )
900874 if b == nil || ! bok {
901875 return nil , false
902876 }
903- c , cok := evalDepth (ctx , node .Args [2 ], depth , visitedIncludes )
877+ c , cok := evalDepth (ctx , includer , node .Args [2 ], depth , visitedIncludes )
904878 if c == nil || ! cok {
905879 return nil , false
906880 }
@@ -983,12 +957,12 @@ func walkTernary(ctx expr.EvalContext, node *expr.TriNode, depth int, visitedInc
983957// walkArray Array evaluator: evaluate multiple values into an array
984958//
985959// (b,c,d)
986- func walkArray (ctx expr.EvalContext , node * expr.ArrayNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
960+ func walkArray (ctx expr.EvalContext , includer expr. Includer , node * expr.ArrayNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
987961
988962 vals := make ([]value.Value , len (node .Args ))
989963
990964 for i := range node .Args {
991- v , _ := evalDepth (ctx , node .Args [i ], depth , visitedIncludes )
965+ v , _ := evalDepth (ctx , includer , node .Args [i ], depth , visitedIncludes )
992966 vals [i ] = v
993967 }
994968
@@ -997,7 +971,7 @@ func walkArray(ctx expr.EvalContext, node *expr.ArrayNode, depth int, visitedInc
997971}
998972
999973// walkFunc evaluates a function
1000- func walkFunc (ctx expr.EvalContext , node * expr.FuncNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
974+ func walkFunc (ctx expr.EvalContext , includer expr. Includer , node * expr.FuncNode , depth int , visitedIncludes []string ) (value.Value , bool ) {
1001975
1002976 if node .F .CustomFunc == nil {
1003977 return nil , false
@@ -1010,7 +984,7 @@ func walkFunc(ctx expr.EvalContext, node *expr.FuncNode, depth int, visitedInclu
1010984 args := make ([]value.Value , len (node .Args ))
1011985
1012986 for i , a := range node .Args {
1013- v , ok := evalDepth (ctx , a , depth , visitedIncludes )
987+ v , ok := evalDepth (ctx , includer , a , depth , visitedIncludes )
1014988 if ! ok {
1015989 v = value .NewNilValue ()
1016990 }
0 commit comments