From 783a03be40400cd325f6b349c7a8219d41b5f83e Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Mon, 18 Nov 2019 13:05:43 -0800 Subject: [PATCH 1/2] parser: Add support for simple case expressions More complex case expressions will generate columns with the `any` type --- internal/dinosql/parser.go | 34 ++++++++++++++++++++++++++++++++++ internal/dinosql/query_test.go | 19 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/internal/dinosql/parser.go b/internal/dinosql/parser.go index a5a12a7c8d..45bba9a5c4 100644 --- a/internal/dinosql/parser.go +++ b/internal/dinosql/parser.go @@ -574,6 +574,32 @@ func outputColumns(c core.Catalog, node nodes.Node) ([]core.Column, error) { cols = append(cols, core.Column{Name: name, DataType: "any", NotNull: false}) } + case nodes.CaseExpr: + spew.Dump(n) + name := "" + if res.Name != nil { + name = *res.Name + } + // TODO: The TypeCase code has been copied from below. Instead, we need a recurse function to get the type of a node. + if tc, ok := n.Defresult.(nodes.TypeCast); ok { + if tc.TypeName == nil { + return nil, errors.New("no type name type cast") + } + name := "" + if ref, ok := tc.Arg.(nodes.ColumnRef); ok { + name = join(ref.Fields, "_") + } + if res.Name != nil { + name = *res.Name + } + // TODO Validate column names + col := catalog.ToColumn(tc.TypeName) + col.Name = name + cols = append(cols, col) + } else { + cols = append(cols, core.Column{Name: name, DataType: "any", NotNull: false}) + } + case nodes.CoalesceExpr: for _, arg := range n.Args.Items { if ref, ok := arg.(nodes.ColumnRef); ok { @@ -652,6 +678,14 @@ func outputColumns(c core.Catalog, node nodes.Node) ([]core.Column, error) { col := catalog.ToColumn(n.TypeName) col.Name = name cols = append(cols, col) + + default: + name := "" + if res.Name != nil { + name = *res.Name + } + cols = append(cols, core.Column{Name: name, DataType: "any", NotNull: false}) + } } return cols, nil diff --git a/internal/dinosql/query_test.go b/internal/dinosql/query_test.go index 06bdd63534..d90c60d40f 100644 --- a/internal/dinosql/query_test.go +++ b/internal/dinosql/query_test.go @@ -703,6 +703,25 @@ func TestQueries(t *testing.T) { }, }, }, + { + "case-stmt-bool", + ` + CREATE TABLE foo (id text not null); + SELECT CASE + WHEN id = $1 THEN true + ELSE false + END is_one + FROM foo; + `, + Query{ + Params: []Parameter{ + {1, core.Column{Table: public("foo"), Name: "id", DataType: "text", NotNull: true}}, + }, + Columns: []core.Column{ + {Name: "is_one", DataType: "pg_catalog.bool", NotNull: true}, + }, + }, + }, } { test := tc t.Run(test.name, func(t *testing.T) { From b65052eb7ff2986dea475746c78f55b0e0bf3be5 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Mon, 18 Nov 2019 13:07:34 -0800 Subject: [PATCH 2/2] remove spew --- internal/dinosql/parser.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/dinosql/parser.go b/internal/dinosql/parser.go index 45bba9a5c4..3d60cedde8 100644 --- a/internal/dinosql/parser.go +++ b/internal/dinosql/parser.go @@ -575,7 +575,6 @@ func outputColumns(c core.Catalog, node nodes.Node) ([]core.Column, error) { } case nodes.CaseExpr: - spew.Dump(n) name := "" if res.Name != nil { name = *res.Name