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)) } return newSubsetAnd(and.(*expression.And)) }
func (this *NNF) VisitFunction(expr expression.Function) (interface{}, error) { var exp expression.Expression = expr switch expr := expr.(type) { case *expression.IsBoolean: exp = expression.NewLE(expr.Operand(), expression.TRUE_EXPR) case *expression.IsNumber: exp = expression.NewAnd( expression.NewGT(expr.Operand(), expression.TRUE_EXPR), expression.NewLT(expr.Operand(), expression.EMPTY_STRING_EXPR)) case *expression.IsString: exp = expression.NewAnd( expression.NewGE(expr.Operand(), expression.EMPTY_STRING_EXPR), expression.NewLT(expr.Operand(), expression.EMPTY_ARRAY_EXPR)) case *expression.IsArray: exp = expression.NewAnd( expression.NewGE(expr.Operand(), expression.EMPTY_ARRAY_EXPR), expression.NewLT(expr.Operand(), _EMPTY_OBJECT_EXPR)) case *expression.IsObject: // Not equivalent to IS OBJECT. Includes BINARY values. exp = expression.NewGE(expr.Operand(), _EMPTY_OBJECT_EXPR) } return exp, exp.MapChildren(this) }
func (this *NNF) VisitBetween(expr *expression.Between) (interface{}, error) { err := expr.MapChildren(this) if err != nil { return nil, err } return expression.NewAnd(expression.NewGE(expr.First(), expr.Second()), expression.NewLE(expr.First(), expr.Third())), nil }
func (this *NNF) VisitNot(expr *expression.Not) (interface{}, error) { err := expr.MapChildren(this) if err != nil { return nil, err } var exp expression.Expression = expr switch operand := expr.Operand().(type) { case *expression.Not: exp = operand.Operand() case *expression.And: operands := make(expression.Expressions, len(operand.Operands())) for i, op := range operand.Operands() { operands[i] = expression.NewNot(op) } exp = expression.NewOr(operands...) case *expression.Or: operands := make(expression.Expressions, len(operand.Operands())) for i, op := range operand.Operands() { operands[i] = expression.NewNot(op) } exp = expression.NewAnd(operands...) case *expression.Eq: exp = expression.NewOr(expression.NewLT(operand.First(), operand.Second()), expression.NewLT(operand.Second(), operand.First())) case *expression.LT: exp = expression.NewLE(operand.Second(), operand.First()) case *expression.LE: exp = expression.NewLT(operand.Second(), operand.First()) } return exp, exp.MapChildren(this) }