From 23b8a9bc4d3e7e89ad211af35c6b0484d0fd3aa0 Mon Sep 17 00:00:00 2001 From: invisig0th Date: Wed, 11 Nov 2020 11:48:48 -0500 Subject: [PATCH] short circuit and/or expressions in storm (#1952) short circuit and/or expressions in storm --- synapse/lib/ast.py | 22 ++++++++++++++++------ synapse/lib/parser.py | 4 ++-- synapse/tests/test_lib_grammar.py | 8 ++++---- synapse/tests/test_lib_storm.py | 3 +++ 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/synapse/lib/ast.py b/synapse/lib/ast.py index 84972db601..85a4fd7d50 100644 --- a/synapse/lib/ast.py +++ b/synapse/lib/ast.py @@ -2479,10 +2479,6 @@ async def expr_ge(x, y): return await toint(x) >= await toint(y) async def expr_le(x, y): return await toint(x) <= await toint(y) -async def expr_or(x, y): - return await tobool(x) or await tobool(y) -async def expr_and(x, y): - return await tobool(x) and await tobool(y) async def expr_prefix(x, y): x, y = await tostr(x), await tostr(y) return x.startswith(y) @@ -2503,8 +2499,6 @@ async def expr_re(x, y): '<': expr_lt, '>=': expr_ge, '<=': expr_le, - 'or': expr_or, - 'and': expr_and, '^=': expr_prefix, } @@ -2546,6 +2540,22 @@ async def compute(self, runt, path): parm2 = await self.kids[2].compute(runt, path) return await self._operfunc(parm1, parm2) +class ExprOrNode(Value): + async def compute(self, runt, path): + parm1 = await self.kids[0].compute(runt, path) + if await tobool(parm1): + return True + parm2 = await self.kids[2].compute(runt, path) + return await tobool(parm2) + +class ExprAndNode(Value): + async def compute(self, runt, path): + parm1 = await self.kids[0].compute(runt, path) + if not await tobool(parm1): + return False + parm2 = await self.kids[2].compute(runt, path) + return await tobool(parm2) + class TagName(Value): def prepare(self): diff --git a/synapse/lib/parser.py b/synapse/lib/parser.py index d01a76cfb1..3f77db090c 100644 --- a/synapse/lib/parser.py +++ b/synapse/lib/parser.py @@ -465,8 +465,8 @@ def massage_vartokn(x): 'edittagpropdel': s_ast.EditTagPropDel, 'editunivdel': s_ast.EditUnivDel, 'editunivset': s_ast.EditPropSet, - 'expror': s_ast.ExprNode, - 'exprand': s_ast.ExprNode, + 'expror': s_ast.ExprOrNode, + 'exprand': s_ast.ExprAndNode, 'exprnot': s_ast.UnaryExprNode, 'exprcmp': s_ast.ExprNode, 'exprproduct': s_ast.ExprNode, diff --git a/synapse/tests/test_lib_grammar.py b/synapse/tests/test_lib_grammar.py index 9423affc91..dcbeb22052 100644 --- a/synapse/tests/test_lib_grammar.py +++ b/synapse/tests/test_lib_grammar.py @@ -589,8 +589,8 @@ 'Query: [LiftProp: [Const: media:news], EditEdgeDel: [Const: refs, SubQuery: [Query: [LiftPropBy: [Const: inet:fqdn, Const: =, Const: woot.com]]]]]', 'Query: [LiftProp: [Const: media:news], EditEdgeAdd: [Const: refs, SubQuery: [Query: [LiftPropBy: [Const: inet:fqdn, Const: =, Const: woot.com]]]]]', 'Query: [CmdOper: [Const: cron, List: [Const: add, Const: --monthly, Const: -1:12:30, ArgvQuery: [Query: [LiftTag: [TagName: [Const: bar]]]]]]]', - 'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprNode: [ExprNode: [Const: 1, Const: or, Const: 1], Const: or, Const: 0]]]]', - 'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprNode: [ExprNode: [Const: 1, Const: and, Const: 1], Const: and, Const: 0]]]]', + 'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprOrNode: [ExprOrNode: [Const: 1, Const: or, Const: 1], Const: or, Const: 0]]]]', + 'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprAndNode: [ExprAndNode: [Const: 1, Const: and, Const: 1], Const: and, Const: 0]]]]', 'Query: [SetVarOper: [Const: var, Const: tag1], LiftTag: [TagName: [Const: base, VarValue: [Const: var]]]]', 'Query: [LiftProp: [Const: test:str], SetVarOper: [Const: var, Const: tag1], FiltOper: [Const: +, TagValuCond: [TagMatch: [Const: base, VarValue: [Const: var]], Const: @=, Const: 2014]]]', 'Query: [LiftProp: [Const: test:str], SetVarOper: [Const: var, Const: tag1], PivotToTags: [TagMatch: [Const: base, VarValue: [Const: var]]], isjoin=False]', @@ -1014,8 +1014,8 @@ 'Query: [IfStmt: [IfClause: [VarValue: [Const: foo], SubQuery: [Query: [EditTagAdd: [TagName: [Const: woot]]]]], IfClause: [DollarExpr: [ExprNode: [Const: 1, Const: -, Const: 1]], SubQuery: [Query: [EditTagAdd: [TagName: [Const: nowoot]]]]]]]', 'Query: [IfStmt: [IfClause: [VarValue: [Const: foo], SubQuery: [Query: [EditTagAdd: [TagName: [Const: woot]]]]], IfClause: [DollarExpr: [ExprNode: [Const: 1, Const: -, Const: 1]], SubQuery: [Query: [EditTagAdd: [TagName: [Const: nowoot]]]]], SubQuery: [Query: [EditTagAdd: [TagName: [Const: nonowoot]]]]]]', 'Query: [IfStmt: [IfClause: [DollarExpr: [ExprNode: [VarValue: [Const: data], Const: ~=, Const: hehe]], SubQuery: [Query: [VarEvalOper: [FuncCall: [VarDeref: [VarValue: [Const: lib], Const: print], CallArgs: [Const: yes], CallKwargs: []]]]]], SubQuery: [Query: [VarEvalOper: [FuncCall: [VarDeref: [VarValue: [Const: lib], Const: print], CallArgs: [Const: no], CallKwargs: []]]]]]]', - 'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprNode: [Const: 1, Const: or, ExprNode: [Const: 0, Const: and, Const: 0]]]]]', - 'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprNode: [UnaryExprNode: [Const: not, Const: 1], Const: and, Const: 1]]]]', + 'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprOrNode: [Const: 1, Const: or, ExprAndNode: [Const: 0, Const: and, Const: 0]]]]]', + 'Query: [SetVarOper: [Const: foo, DollarExpr: [ExprAndNode: [UnaryExprNode: [Const: not, Const: 1], Const: and, Const: 1]]]]', 'Query: [SetVarOper: [Const: foo, DollarExpr: [UnaryExprNode: [Const: not, ExprNode: [Const: 1, Const: >, Const: 1]]]]]', 'Query: [LiftTagProp: [TagProp: [Const: baz.faz, Const: lol]]]', 'Query: [LiftFormTagProp: [FormTagProp: [Const: foo:bar, Const: baz.faz, Const: lol]]]', diff --git a/synapse/tests/test_lib_storm.py b/synapse/tests/test_lib_storm.py index c44f76d399..742e1e6d4b 100644 --- a/synapse/tests/test_lib_storm.py +++ b/synapse/tests/test_lib_storm.py @@ -89,6 +89,9 @@ async def test_lib_storm_basics(self): self.len(1, await core.nodes('inet:ipv4=1.2.3.4', opts={'view': view1})) + self.len(0, await core.nodes('$x = $lib.null if ($x and $x > 20) { [ ps:contact=* ] }')) + self.len(1, await core.nodes('$x = $lib.null if ($lib.true or $x > 20) { [ ps:contact=* ] }')) + async def test_storm_tree(self): async with self.getTestCore() as core: