3
0

Add support for IS NULL and IS NOT NULL syntax

This commit is contained in:
Denis Arh 2019-07-16 09:54:39 +02:00
parent b006cb8784
commit ed4acf58ca
No known key found for this signature in database
GPG Key ID: 8623A75D5895F1B9
6 changed files with 43 additions and 1 deletions

View File

@ -20,6 +20,8 @@ type (
Columns []Column
Null struct{}
String struct {
Value string
Args []interface{}
@ -51,12 +53,16 @@ type (
Expr ASTNodes
Alias string
}
Function struct {
Name string
Arguments ASTSet
}
)
func (n Null) Validate() (err error) { return }
func (n Null) String() string { return "NULL" }
func (n String) Validate() (err error) { return }
func (n String) String() string { return fmt.Sprintf("%q", n.Value) }

View File

@ -166,6 +166,8 @@ checkToken:
list = append(list, ident)
goto next
}
case NULL:
list = append(list, Null{})
case OPERATOR:
if len(list) > 0 {
// Merge with previous operator node

View File

@ -156,6 +156,33 @@ func TestAstParser_Parser(t *testing.T) {
String{Value: "bar%"},
},
},
{
parser: NewParser().ParseExpression,
in: `foo = NULL`,
tree: ASTNodes{
Ident{Value: "foo"},
Operator{Kind: "="},
Null{},
},
},
{
parser: NewParser().ParseExpression,
in: `foo IS NOT NULL`,
tree: ASTNodes{
Ident{Value: "foo"},
Operator{Kind: "IS NOT"},
Null{},
},
},
{
parser: NewParser().ParseExpression,
in: `foo IS NULL`,
tree: ASTNodes{
Ident{Value: "foo"},
Operator{Kind: "IS"},
Null{},
},
},
}
for i, test := range tests {

View File

@ -62,6 +62,10 @@ func (n Ident) ToSql() (string, []interface{}, error) {
return n.Value, n.Args, nil
}
func (n Null) ToSql() (string, []interface{}, error) {
return "NULL", nil, nil
}
func (n Function) ToSql() (string, []interface{}, error) {
if paramsSql, args, err := n.Arguments.ToSql(); err != nil {
return "", nil, err

View File

@ -23,4 +23,5 @@ const (
PARENTHESIS_OPEN
PARENTHESIS_CLOSE
KEYWORD
NULL
)

View File

@ -85,7 +85,9 @@ func (TokenConsumerIdent) Consume(s RuneReader) Token {
lit := strings.ToUpper(buf.String())
switch lit {
case "LIKE", "NOT", "AND", "OR", "XOR":
case "NULL":
return Token{code: NULL}
case "IS", "LIKE", "NOT", "AND", "OR", "XOR":
return Token{code: OPERATOR, literal: lit}
case "DESC", "ASC", "INTERVAL":
return Token{code: KEYWORD, literal: lit}