Skip to content

Commit

Permalink
feat(spanner/spansql): add support for IFNULL expressions (#6389)
Browse files Browse the repository at this point in the history
Co-authored-by: rahul2393 <rahulyadavsep92@gmail.com>
  • Loading branch information
neglect-yp and rahul2393 committed Jul 23, 2022
1 parent 267a9bb commit 09e96ce
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 0 deletions.
27 changes: 27 additions & 0 deletions spanner/spansql/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3041,6 +3041,9 @@ func (p *parser) parseLit() (Expr, *parseError) {
case tok.caseEqual("IF"):
p.back()
return p.parseIfExpr()
case tok.caseEqual("IFNULL"):
p.back()
return p.parseIfNullExpr()
}

// Handle typed literals.
Expand Down Expand Up @@ -3183,6 +3186,30 @@ func (p *parser) parseIfExpr() (If, *parseError) {
return If{Expr: expr, TrueResult: trueResult, ElseResult: elseResult}, nil
}

func (p *parser) parseIfNullExpr() (IfNull, *parseError) {
if err := p.expect("IFNULL", "("); err != nil {
return IfNull{}, err
}

expr, err := p.parseExpr()
if err != nil {
return IfNull{}, err
}
if err := p.expect(","); err != nil {
return IfNull{}, err
}

nullResult, err := p.parseExpr()
if err != nil {
return IfNull{}, err
}
if err := p.expect(")"); err != nil {
return IfNull{}, err
}

return IfNull{Expr: expr, NullResult: nullResult}, nil
}

func (p *parser) parseArrayLit() (Array, *parseError) {
// ARRAY keyword is optional.
// TODO: If it is present, consume any <T> after it.
Expand Down
6 changes: 6 additions & 0 deletions spanner/spansql/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,12 @@ func TestParseExpr(t *testing.T) {
ElseResult: False,
},
},
{`IFNULL(NULL, TRUE)`,
IfNull{
Expr: Null,
NullResult: True,
},
},

// String literal:
// Accept double quote and single quote.
Expand Down
9 changes: 9 additions & 0 deletions spanner/spansql/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,15 @@ func (i If) addSQL(sb *strings.Builder) {
sb.WriteString(")")
}

func (in IfNull) SQL() string { return buildSQL(in) }
func (in IfNull) addSQL(sb *strings.Builder) {
sb.WriteString("IFNULL(")
in.Expr.addSQL(sb)
sb.WriteString(", ")
in.NullResult.addSQL(sb)
sb.WriteString(")")
}

func (b BoolLiteral) SQL() string { return buildSQL(b) }
func (b BoolLiteral) addSQL(sb *strings.Builder) {
if b {
Expand Down
14 changes: 14 additions & 0 deletions spanner/spansql/sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,20 @@ func TestSQL(t *testing.T) {
`SELECT IF(1 < 2, TRUE, FALSE)`,
reparseQuery,
},
{
Query{
Select: Select{
List: []Expr{
IfNull{
Expr: IntegerLiteral(10),
NullResult: IntegerLiteral(0),
},
},
},
},
`SELECT IFNULL(10, 0)`,
reparseQuery,
},
}
for _, test := range tests {
sql := test.data.SQL()
Expand Down
8 changes: 8 additions & 0 deletions spanner/spansql/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,14 @@ type If struct {
func (If) isBoolExpr() {} // possibly bool
func (If) isExpr() {}

type IfNull struct {
Expr Expr
NullResult Expr
}

func (IfNull) isBoolExpr() {} // possibly bool
func (IfNull) isExpr() {}

type BoolLiteral bool

const (
Expand Down

0 comments on commit 09e96ce

Please sign in to comment.