Support ql between/not between operator
For number type, IE (Field1 BETWEEN X X) or (Field1 NOT BETWEEN X X)
This commit is contained in:
@@ -319,15 +319,30 @@ func (nn parserNodes) ToAST() (out *ASTNode) {
|
||||
// Have the op consume what it needs.
|
||||
arg := auxArgs[bestOpIx]
|
||||
if !isUnary(arg.Ref) {
|
||||
arg.Args = append(arg.Args, auxArgs[bestOpIx-1], auxArgs[bestOpIx+1])
|
||||
for i, auxArg := range auxArgs {
|
||||
if isOperator(auxArg.Ref) {
|
||||
break
|
||||
}
|
||||
|
||||
if i == bestOpIx {
|
||||
continue
|
||||
}
|
||||
|
||||
arg.Args = append(arg.Args, auxArg)
|
||||
}
|
||||
|
||||
// this is not needed anymore so we can remove it
|
||||
arg.pMeta = nil
|
||||
|
||||
// Remove the consumed bits and replace it with the new bit
|
||||
aux := auxArgs[0 : bestOpIx-1]
|
||||
aux = append(aux, arg)
|
||||
// +1 for right side, +1 because the left index is inclusive
|
||||
aux = append(aux, auxArgs[bestOpIx+2:]...)
|
||||
// +X for right side, +1 because the left index is inclusive
|
||||
skip := 2
|
||||
if len(arg.Args) > 2 {
|
||||
skip = len(arg.Args)
|
||||
}
|
||||
aux = append(aux, auxArgs[bestOpIx+skip:]...)
|
||||
auxArgs = aux
|
||||
} else {
|
||||
arg.Args = append(arg.Args, auxArgs[bestOpIx+1])
|
||||
|
||||
@@ -95,6 +95,10 @@ var (
|
||||
// str comp.
|
||||
`LIKE`: {name: `like`, weight: 40},
|
||||
`NOT LIKE`: {name: `nlike`, weight: 40},
|
||||
|
||||
// range comp.
|
||||
`BETWEEN`: {name: `between`, weight: 40},
|
||||
`NOT BETWEEN`: {name: `nbetween`, weight: 40},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -102,6 +106,10 @@ func isUnary(s string) bool {
|
||||
return s == "!" || s == "not"
|
||||
}
|
||||
|
||||
func isOperator(s string) bool {
|
||||
return s == "and" || s == "or" || s == "xor"
|
||||
}
|
||||
|
||||
func getOp(op string) *opDef {
|
||||
o, ok := ops[strings.ToUpper(op)]
|
||||
if !ok {
|
||||
|
||||
@@ -89,7 +89,7 @@ func (TokenConsumerIdent) Consume(s RuneReader) Token {
|
||||
return Token{code: LNULL}
|
||||
case "TRUE", "FALSE":
|
||||
return Token{code: LBOOL, literal: lit}
|
||||
case "IS", "LIKE", "NOT", "AND", "OR", "XOR", "IN":
|
||||
case "IS", "LIKE", "NOT", "AND", "OR", "XOR", "IN", "BETWEEN":
|
||||
return Token{code: OPERATOR, literal: lit}
|
||||
case "DESC", "ASC", "INTERVAL":
|
||||
return Token{code: KEYWORD, literal: lit}
|
||||
|
||||
@@ -13,8 +13,9 @@ type (
|
||||
ExprHandlerMap map[string]*ExprHandler
|
||||
|
||||
ExprHandler struct {
|
||||
Handler func(...exp.Expression) exp.Expression
|
||||
HandlerE func(...exp.Expression) (exp.Expression, error)
|
||||
Handler func(...exp.Expression) exp.Expression
|
||||
HandlerE func(...exp.Expression) (exp.Expression, error)
|
||||
RangeHandler func(exp.Expression, exp.RangeVal) exp.Expression
|
||||
}
|
||||
)
|
||||
|
||||
@@ -181,6 +182,18 @@ var (
|
||||
},
|
||||
},
|
||||
|
||||
// range operation
|
||||
"between": {
|
||||
Handler: func(args ...exp.Expression) exp.Expression {
|
||||
return exp.NewRangeExpression(exp.BetweenOp, args[0], exp.NewRangeVal(args[1], args[2]))
|
||||
},
|
||||
},
|
||||
"nbetween": {
|
||||
Handler: func(args ...exp.Expression) exp.Expression {
|
||||
return exp.NewRangeExpression(exp.NotBetweenOp, args[0], exp.NewRangeVal(args[1], args[2]))
|
||||
},
|
||||
},
|
||||
|
||||
"is": {
|
||||
Handler: func(args ...exp.Expression) exp.Expression {
|
||||
return exp.NewBooleanExpression(exp.IsOp, args[0], args[1])
|
||||
|
||||
Reference in New Issue
Block a user