func (this *DNF) VisitIn(expr *expression.In) (interface{}, error) { err := expr.MapChildren(this) if err != nil { return nil, err } a, ok := expr.Second().(*expression.ArrayConstruct) if !ok { return expr, nil } first := expr.First() operands := make(expression.Expressions, len(a.Operands())) for i, op := range a.Operands() { operands[i] = expression.NewEq(first, op) } return expression.NewOr(operands...), nil }
func newSubsetLike(expr expression.BinaryFunction, re *regexp.Regexp) expression.Visitor { if re == nil { // Pattern is not a constant return newSubsetDefault(expr) } prefix, complete := re.LiteralPrefix() if complete { eq := expression.NewEq(expr.First(), expression.NewConstant(prefix)) return newSubsetEq(eq.(*expression.Eq)) } if prefix == "" { return newSubsetDefault(expr) } var and expression.Expression le := expression.NewLE(expression.NewConstant(prefix), expr.First()) last := len(prefix) - 1 if prefix[last] < math.MaxUint8 { bytes := []byte(prefix) bytes[last]++ and = expression.NewAnd(le, expression.NewLT( expr.First(), expression.NewConstant(string(bytes)))) } else { and = expression.NewAnd(le, expression.NewLT( expr.First(), expression.EMPTY_ARRAY_EXPR)) } sand := newSubsetAnd(and.(*expression.And)) rv := &subsetLike{} rv.test = func(expr2 expression.Expression) (bool, error) { if expr.EquivalentTo(expr2) { return true, nil } return sand.test(expr2) } return rv }
func newSargLike(pred expression.BinaryFunction, re *regexp.Regexp) expression.Visitor { prefix := "" if re != nil { var complete bool prefix, complete = re.LiteralPrefix() if complete { eq := expression.NewEq(pred.First(), expression.NewConstant(prefix)) return newSargEq(eq.(*expression.Eq)) } } rv := &sargLike{} rv.sarger = func(expr2 expression.Expression) (plan.Spans, error) { if SubsetOf(pred, expr2) { return _SELF_SPANS, nil } if !pred.First().EquivalentTo(expr2) { return nil, nil } span := &plan.Span{} span.Range.Low = expression.Expressions{expression.NewConstant(prefix)} last := len(prefix) - 1 if last >= 0 && prefix[last] < math.MaxUint8 { bytes := []byte(prefix) bytes[last]++ span.Range.High = expression.Expressions{expression.NewConstant(string(bytes))} } else { span.Range.High = _EMPTY_ARRAY } span.Range.Inclusion = datastore.LOW return plan.Spans{span}, nil } return rv }
func (this *DNF) VisitLike(expr *expression.Like) (interface{}, error) { err := expr.MapChildren(this) if err != nil { return nil, err } re := expr.Regexp() if re == nil { return expr, nil } prefix, complete := re.LiteralPrefix() if complete { eq := expression.NewEq(expr.First(), expression.NewConstant(prefix)) return eq, nil } if prefix == "" { return expr, nil } var and expression.Expression le := expression.NewLE(expression.NewConstant(prefix), expr.First()) last := len(prefix) - 1 if prefix[last] < math.MaxUint8 { bytes := []byte(prefix) bytes[last]++ and = expression.NewAnd(le, expression.NewLT( expr.First(), expression.NewConstant(string(bytes)))) } else { and = expression.NewAnd(le, expression.NewLT( expr.First(), expression.EMPTY_ARRAY_EXPR)) } return and, nil }