func newSubsetAnd(expr *expression.And) *subsetAnd { rv := &subsetAnd{} rv.test = func(expr2 expression.Expression) (bool, error) { for _, child := range expr.Operands() { if SubsetOf(child, expr2) { return true, nil } } switch expr2 := expr2.(type) { case *expression.And: for _, child2 := range expr2.Operands() { if !SubsetOf(expr, child2) { return false, nil } } return true, nil } return false, nil } return rv }
func newSargAnd(pred *expression.And) *sargAnd { rv := &sargAnd{} rv.sarger = func(expr2 expression.Expression) (spans plan.Spans, err error) { if SubsetOf(pred, expr2) { return _SELF_SPANS, nil } var s plan.Spans for _, op := range pred.Operands() { s, err = sargFor(op, expr2, rv.MissingHigh()) if err != nil { return nil, err } if len(s) == 0 { continue } if len(spans) == 0 { spans = s.Copy() } else { spans = constrainSpans(spans, s) } } return } return rv }
func (this *JSConverter) VisitAnd(expr *expression.And) (interface{}, error) { var buf bytes.Buffer buf.WriteString("(") for i, op := range expr.Operands() { if i > 0 { buf.WriteString(" && ") } buf.WriteString(this.Visit(op)) } buf.WriteString(")") return buf.String(), nil }
func newSargableAnd(pred *expression.And) *sargableAnd { rv := &sargableAnd{} rv.test = func(expr2 expression.Expression) (bool, error) { exprs := expression.Expressions{expr2} for _, child := range pred.Operands() { if SargableFor(child, exprs) > 0 { return true, nil } } return false, nil } return rv }
/* Apply Disjunctive Normal Form. Convert ANDs of ORs to ORs of ANDs. For example: (A OR B) AND C => (A AND C) OR (B AND C) Also apply constant folding. Remove any constant terms. */ func (this *DNF) VisitAnd(expr *expression.And) (interface{}, error) { err := expr.MapChildren(this) if err != nil { return nil, err } // Constant folding var terms expression.Expressions for _, term := range expr.Operands() { val := term.Value() if val == nil { if terms == nil { terms = make(expression.Expressions, 0, len(expr.Operands())) } terms = append(terms, term) continue } if !val.Truth() { return expression.FALSE_EXPR, nil } } if len(terms) == 0 { return expression.TRUE_EXPR, nil } if len(terms) < len(expr.Operands()) { expr = expression.NewAnd(terms...) } // DNF if dnfComplexity(expr, 16) >= 16 { return expr, nil } else { return applyDNF(expr, 0), nil } }
/* Bounded DNF, to mitigate combinatorial worst-case. Internally apply Disjunctive Normal Form. Convert ANDs of ORs to ORs of ANDs. For example: (A OR B) AND C => (A AND C) OR (B AND C) */ func applyDNF(expr *expression.And, level int) expression.Expression { na := len(expr.Operands()) if na > 4 { return expr } for i, aterm := range expr.Operands() { switch aterm := aterm.(type) { case *expression.Or: no := len(aterm.Operands()) if no*na > 8 { return expr } oterms := make(expression.Expressions, no) for j, oterm := range aterm.Operands() { aterms := make(expression.Expressions, na) for ii, atrm := range expr.Operands() { if ii == i { aterms[ii] = oterm } else { aterms[ii] = atrm } } if level > 2 { oterms[j] = expression.NewAnd(aterms...) } else { oterms[j] = applyDNF(expression.NewAnd(aterms...), level+1) } } rv := expression.NewOr(oterms...) return rv } } return expr }