Skip to content

Commit

Permalink
feat(spanner/spansql): add support for coalesce expressions (#6461)
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 Sep 3, 2022
1 parent e9a94c2 commit bff16a7
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 0 deletions.
14 changes: 14 additions & 0 deletions spanner/spansql/parser.go
Expand Up @@ -3038,6 +3038,9 @@ func (p *parser) parseLit() (Expr, *parseError) {
case tok.caseEqual("CASE"):
p.back()
return p.parseCaseExpr()
case tok.caseEqual("COALESCE"):
p.back()
return p.parseCoalesceExpr()
case tok.caseEqual("IF"):
p.back()
return p.parseIfExpr()
Expand Down Expand Up @@ -3157,6 +3160,17 @@ func (p *parser) parseWhenClause() (WhenClause, *parseError) {
return WhenClause{Cond: cond, Result: result}, nil
}

func (p *parser) parseCoalesceExpr() (Coalesce, *parseError) {
if err := p.expect("COALESCE"); err != nil {
return Coalesce{}, err
}
exprList, err := p.parseParenExprList()
if err != nil {
return Coalesce{}, err
}
return Coalesce{ExprList: exprList}, nil
}

func (p *parser) parseIfExpr() (If, *parseError) {
if err := p.expect("IF", "("); err != nil {
return If{}, err
Expand Down
3 changes: 3 additions & 0 deletions spanner/spansql/parser_test.go
Expand Up @@ -433,6 +433,9 @@ func TestParseExpr(t *testing.T) {
},
},
},
{`COALESCE(NULL, "B", "C")`,
Coalesce{ExprList: []Expr{Null, StringLiteral("B"), StringLiteral("C")}},
},
{`IF(A < B, TRUE, FALSE)`,
If{
Expr: ComparisonOp{LHS: ID("A"), Op: Lt, RHS: ID("B")},
Expand Down
12 changes: 12 additions & 0 deletions spanner/spansql/sql.go
Expand Up @@ -733,6 +733,18 @@ func (c Case) addSQL(sb *strings.Builder) {
sb.WriteString("END")
}

func (c Coalesce) SQL() string { return buildSQL(c) }
func (c Coalesce) addSQL(sb *strings.Builder) {
sb.WriteString("COALESCE(")
for i, expr := range c.ExprList {
if i > 0 {
sb.WriteString(", ")
}
expr.addSQL(sb)
}
sb.WriteString(")")
}

func (i If) SQL() string { return buildSQL(i) }
func (i If) addSQL(sb *strings.Builder) {
sb.WriteString("IF(")
Expand Down
17 changes: 17 additions & 0 deletions spanner/spansql/sql_test.go
Expand Up @@ -699,6 +699,23 @@ func TestSQL(t *testing.T) {
`SELECT NULLIF(10, 0)`,
reparseQuery,
},
{
Query{
Select: Select{
List: []Expr{
Coalesce{
ExprList: []Expr{
StringLiteral("A"),
Null,
StringLiteral("C"),
},
},
},
},
},
`SELECT COALESCE("A", NULL, "C")`,
reparseQuery,
},
}
for _, test := range tests {
sql := test.data.SQL()
Expand Down
7 changes: 7 additions & 0 deletions spanner/spansql/types.go
Expand Up @@ -743,6 +743,13 @@ type WhenClause struct {
Result Expr
}

type Coalesce struct {
ExprList []Expr
}

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

type If struct {
Expr Expr
TrueResult Expr
Expand Down

0 comments on commit bff16a7

Please sign in to comment.