示例#1
0
文件: dnf.go 项目: pkdevboxy/query
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
}
示例#2
0
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
}
示例#3
0
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
}
示例#4
0
文件: dnf.go 项目: pkdevboxy/query
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
}