Skip to content

Commit 5b7bfeb

Browse files
feat(spanner/spansql): add support for nullif expressions (#6423)
Co-authored-by: rahul2393 <[email protected]>
1 parent 417ef94 commit 5b7bfeb

File tree

5 files changed

+64
-0
lines changed

5 files changed

+64
-0
lines changed

spanner/spansql/parser.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3044,6 +3044,9 @@ func (p *parser) parseLit() (Expr, *parseError) {
30443044
case tok.caseEqual("IFNULL"):
30453045
p.back()
30463046
return p.parseIfNullExpr()
3047+
case tok.caseEqual("NULLIF"):
3048+
p.back()
3049+
return p.parseNullIfExpr()
30473050
}
30483051

30493052
// Handle typed literals.
@@ -3210,6 +3213,30 @@ func (p *parser) parseIfNullExpr() (IfNull, *parseError) {
32103213
return IfNull{Expr: expr, NullResult: nullResult}, nil
32113214
}
32123215

3216+
func (p *parser) parseNullIfExpr() (NullIf, *parseError) {
3217+
if err := p.expect("NULLIF", "("); err != nil {
3218+
return NullIf{}, err
3219+
}
3220+
3221+
expr, err := p.parseExpr()
3222+
if err != nil {
3223+
return NullIf{}, err
3224+
}
3225+
if err := p.expect(","); err != nil {
3226+
return NullIf{}, err
3227+
}
3228+
3229+
exprToMatch, err := p.parseExpr()
3230+
if err != nil {
3231+
return NullIf{}, err
3232+
}
3233+
if err := p.expect(")"); err != nil {
3234+
return NullIf{}, err
3235+
}
3236+
3237+
return NullIf{Expr: expr, ExprToMatch: exprToMatch}, nil
3238+
}
3239+
32133240
func (p *parser) parseArrayLit() (Array, *parseError) {
32143241
// ARRAY keyword is optional.
32153242
// TODO: If it is present, consume any <T> after it.

spanner/spansql/parser_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,12 @@ func TestParseExpr(t *testing.T) {
446446
NullResult: True,
447447
},
448448
},
449+
{`NULLIF("a", "b")`,
450+
NullIf{
451+
Expr: StringLiteral("a"),
452+
ExprToMatch: StringLiteral("b"),
453+
},
454+
},
449455

450456
// String literal:
451457
// Accept double quote and single quote.

spanner/spansql/sql.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,15 @@ func (in IfNull) addSQL(sb *strings.Builder) {
753753
sb.WriteString(")")
754754
}
755755

756+
func (ni NullIf) SQL() string { return buildSQL(ni) }
757+
func (ni NullIf) addSQL(sb *strings.Builder) {
758+
sb.WriteString("NULLIF(")
759+
ni.Expr.addSQL(sb)
760+
sb.WriteString(", ")
761+
ni.ExprToMatch.addSQL(sb)
762+
sb.WriteString(")")
763+
}
764+
756765
func (b BoolLiteral) SQL() string { return buildSQL(b) }
757766
func (b BoolLiteral) addSQL(sb *strings.Builder) {
758767
if b {

spanner/spansql/sql_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,20 @@ func TestSQL(t *testing.T) {
685685
`SELECT IFNULL(10, 0)`,
686686
reparseQuery,
687687
},
688+
{
689+
Query{
690+
Select: Select{
691+
List: []Expr{
692+
NullIf{
693+
Expr: IntegerLiteral(10),
694+
ExprToMatch: IntegerLiteral(0),
695+
},
696+
},
697+
},
698+
},
699+
`SELECT NULLIF(10, 0)`,
700+
reparseQuery,
701+
},
688702
}
689703
for _, test := range tests {
690704
sql := test.data.SQL()

spanner/spansql/types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,14 @@ type IfNull struct {
760760
func (IfNull) isBoolExpr() {} // possibly bool
761761
func (IfNull) isExpr() {}
762762

763+
type NullIf struct {
764+
Expr Expr
765+
ExprToMatch Expr
766+
}
767+
768+
func (NullIf) isBoolExpr() {} // possibly bool
769+
func (NullIf) isExpr() {}
770+
763771
type BoolLiteral bool
764772

765773
const (

0 commit comments

Comments
 (0)