MCPcopy Create free account
hub / github.com/brimdata/super / buildRangePruner

Function buildRangePruner

compiler/optimizer/pruner.go:42–87  ·  view source on GitHub ↗

buildRangePruner creates a DAG comparison expression that can evalaute whether a value adhering to the from/to pattern can be excluded from a scan because the expression pred would evaluate to false for all values of fld in the from/to value range. If a pruning decision cannot be reliably determine

(pred dag.Expr, fld field.Path, min, max *dag.ThisExpr)

Source from the content-addressed store, hash-verified

40// from/to value range. If a pruning decision cannot be reliably determined then
41// the return value is nil.
42func buildRangePruner(pred dag.Expr, fld field.Path, min, max *dag.ThisExpr) *dag.BinaryExpr {
43 e, ok := pred.(*dag.BinaryExpr)
44 if !ok {
45 // If this isn't a binary predicate composed of comparison operators, we
46 // simply punt here. This doesn't mean we can't optimize, because if the
47 // unknown part (from here) appears in the context of an "and", then we
48 // can still prune the known side of the "and" as implemented in the
49 // logic below.
50 return nil
51 }
52 switch e.Op {
53 case "and":
54 // For an "and", if we know either side is prunable, then we can prune
55 // because both conditions are required. So we "or" together the result
56 // when both sub-expressions are valid.
57 lhs := buildRangePruner(e.LHS, fld, min, max)
58 rhs := buildRangePruner(e.RHS, fld, min, max)
59 if lhs == nil {
60 return rhs
61 }
62 if rhs == nil {
63 return lhs
64 }
65 return dag.NewBinaryExpr("or", lhs, rhs)
66 case "or":
67 // For an "or", if we know both sides are prunable, then we can prune
68 // because either condition is required. So we "and" together the result
69 // when both sub-expressions are valid.
70 lhs := buildRangePruner(e.LHS, fld, min, max)
71 rhs := buildRangePruner(e.RHS, fld, min, max)
72 if lhs == nil || rhs == nil {
73 return nil
74 }
75 return dag.NewBinaryExpr("and", lhs, rhs)
76 case "==", "<", "<=", ">", ">=":
77 this, literal, op := literalComparison(e)
78 if this == nil || !fld.Equal(this.Path) {
79 return nil
80 }
81 // At this point, we know we can definitely run a pruning decision based
82 // on the literal value we found, the comparison op, and the lower/upper bounds.
83 return rangePrunerPred(op, literal, min, max)
84 default:
85 return nil
86 }
87}
88
89func rangePrunerPred(op string, literal *dag.PrimitiveExpr, min, max *dag.ThisExpr) *dag.BinaryExpr {
90 switch op {

Callers 1

newRangePrunerFunction · 0.85

Calls 4

NewBinaryExprFunction · 0.92
literalComparisonFunction · 0.85
rangePrunerPredFunction · 0.85
EqualMethod · 0.45

Tested by

no test coverage detected