mirror of
https://github.com/hanzoai/traces.git
synced 2026-10-30 18:20:41 +00:00
6c89137ee1
Bumps [github.com/expr-lang/expr](https://github.com/expr-lang/expr) from 1.16.9 to 1.17.0. - [Release notes](https://github.com/expr-lang/expr/releases) - [Commits](https://github.com/expr-lang/expr/compare/v1.16.9...v1.17.0) --- updated-dependencies: - dependency-name: github.com/expr-lang/expr dependency-type: indirect ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
62 lines
1.7 KiB
Go
62 lines
1.7 KiB
Go
package optimizer
|
|
|
|
import (
|
|
. "github.com/expr-lang/expr/ast"
|
|
"github.com/expr-lang/expr/parser/operator"
|
|
)
|
|
|
|
/*
|
|
predicateCombination is a visitor that combines multiple predicate calls into a single call.
|
|
For example, the following expression:
|
|
|
|
all(x, x > 1) && all(x, x < 10) -> all(x, x > 1 && x < 10)
|
|
any(x, x > 1) || any(x, x < 10) -> any(x, x > 1 || x < 10)
|
|
none(x, x > 1) && none(x, x < 10) -> none(x, x > 1 || x < 10)
|
|
*/
|
|
type predicateCombination struct{}
|
|
|
|
func (v *predicateCombination) Visit(node *Node) {
|
|
if op, ok := (*node).(*BinaryNode); ok && operator.IsBoolean(op.Operator) {
|
|
if left, ok := op.Left.(*BuiltinNode); ok {
|
|
if combinedOp, ok := combinedOperator(left.Name, op.Operator); ok {
|
|
if right, ok := op.Right.(*BuiltinNode); ok && right.Name == left.Name {
|
|
if left.Arguments[0].Type() == right.Arguments[0].Type() && left.Arguments[0].String() == right.Arguments[0].String() {
|
|
predicate := &PredicateNode{
|
|
Node: &BinaryNode{
|
|
Operator: combinedOp,
|
|
Left: left.Arguments[1].(*PredicateNode).Node,
|
|
Right: right.Arguments[1].(*PredicateNode).Node,
|
|
},
|
|
}
|
|
v.Visit(&predicate.Node)
|
|
patchCopyType(node, &BuiltinNode{
|
|
Name: left.Name,
|
|
Arguments: []Node{
|
|
left.Arguments[0],
|
|
predicate,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func combinedOperator(fn, op string) (string, bool) {
|
|
switch {
|
|
case fn == "all" && (op == "and" || op == "&&"):
|
|
return op, true
|
|
case fn == "any" && (op == "or" || op == "||"):
|
|
return op, true
|
|
case fn == "none" && (op == "and" || op == "&&"):
|
|
switch op {
|
|
case "and":
|
|
return "or", true
|
|
case "&&":
|
|
return "||", true
|
|
}
|
|
}
|
|
return "", false
|
|
}
|