diff --git a/pkg/expr/mongo.go b/pkg/expr/mongo.go index 71f3bddafd5444dde63352ededa4b53bc20d2739..bb4187dda74adce707798781b77d23a648db0eb1 100644 --- a/pkg/expr/mongo.go +++ b/pkg/expr/mongo.go @@ -713,7 +713,7 @@ func (c *compiler) handleLenNode(node *ast.BinaryNode) bson.M { } } -// handleTryNode получает узел AST с двумя выражениями-строками и пытается выполнить первое +// handleTryNode получает узел AST с двумя выражениями и пытается выполнить первое // в случае успеха - возвращает его // в случае ошибки - пытается выполнить второе и вернуть его результат func (c *compiler) handleTryNode(node *ast.CallNode) (result interface{}) { @@ -721,23 +721,17 @@ func (c *compiler) handleTryNode(node *ast.CallNode) (result interface{}) { panic("try() expects exactly 2 arguments") } - subcompiler := &compiler{env: c.env, config: c.config, identifierRenameFn: c.identifierRenameFn} - subexprCompile := func(subexpr string) interface{} { - tree, err := parser.Parse(subexpr) - if err != nil { - panic(err) - } - - subcompiler.tree = tree - return subcompiler.compile(tree.Node) - } - defer func() { if r := recover(); r != nil { - result = subexprCompile(node.Arguments[1].(*ast.StringNode).Value) + result = c.compile(node.Arguments[1]) } }() - result = subexprCompile(node.Arguments[0].(*ast.StringNode).Value).(bson.M) + tree, err := parser.Parse(node.Arguments[0].(*ast.StringNode).Value) + if err != nil { + panic(err) + } + subcompiler := &compiler{tree: tree, env: c.env, config: c.config, identifierRenameFn: c.identifierRenameFn} + result = subcompiler.compile(tree.Node).(bson.M) return } diff --git a/pkg/expr/mongo_test.go b/pkg/expr/mongo_test.go index 65070bbcccbb19a33d282dca5250bbaa76894779..9a7df77d00a8c006327b5b2645818a014d86d9b7 100644 --- a/pkg/expr/mongo_test.go +++ b/pkg/expr/mongo_test.go @@ -79,10 +79,10 @@ func TestConvertToMongo(t *testing.T) { {"in", "In(s, 1)", nil, bson.M{"s": bson.M{"$in": []interface{}{1}}}, false}, {"text search or id", "id", nil, nil, true}, {"struct env", "db_item.id == env_item.id", map[string]interface{}{"env_item": &testEnvStruct{ID: "id1"}}, bson.M{"db_item.id": "id1"}, false}, - {"try#1", "try('s == 1', 's == 2')", nil, bson.M{"s": 1}, false}, - {"try#2", "try('some-slug', 'search(\\'some\\') || _id contains \\'some-slug\\'')", nil, bson.M{"$or": bson.A{bson.M{"$text": bson.M{"$search": "some"}}, bson.M{"_id": bson.M{"$regex": "some-slug"}}}}, false}, - {"try#3", "try(bad-expr, bad-expr)", nil, nil, true}, - {"try#4", "try('3', 's == 1')", nil, bson.M{"s": 1}, false}, + {"try#1", "try('s == 1', s == 2)", nil, bson.M{"s": 1}, false}, + {"try#2", "try('some-slug', search('some-slug') || _id contains 'some-slug')", nil, bson.M{"$or": bson.A{bson.M{"$text": bson.M{"$search": "some-slug"}}, bson.M{"_id": bson.M{"$regex": "some-slug"}}}}, false}, + {"try#3", "try('bad-expr', bad-expr)", nil, nil, true}, + {"try#4", "try('3', s == 1)", nil, bson.M{"s": 1}, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {