Skip to content

Commit 8ac5803

Browse files
authored
Port the rest of the compiler to the new AST (#514)
* rewrite: Port the rewrite package to generic SQL * Find params * On to codegen * ondeck gen almost passes
1 parent 67800a9 commit 8ac5803

File tree

25 files changed

+2121
-66
lines changed

25 files changed

+2121
-66
lines changed

internal/cmd/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ var genCmd = &cobra.Command{
8989
os.Exit(1)
9090
}
9191

92-
output, err := Generate(Env{}, dir, stderr)
92+
output, err := Generate(ParseEnv(), dir, stderr)
9393
if err != nil {
9494
os.Exit(1)
9595
}

internal/codegen/golang/enum.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package golang
22

3-
import "regexp"
3+
import (
4+
"regexp"
5+
"strings"
6+
)
47

58
var IdentPattern = regexp.MustCompile("[^a-zA-Z0-9_]+")
69

@@ -15,3 +18,15 @@ type Enum struct {
1518
Comment string
1619
Constants []Constant
1720
}
21+
22+
func EnumValueName(value string) string {
23+
name := ""
24+
id := strings.Replace(value, "-", "_", -1)
25+
id = strings.Replace(id, ":", "_", -1)
26+
id = strings.Replace(id, "/", "_", -1)
27+
id = IdentPattern.ReplaceAllString(id, "")
28+
for _, part := range strings.Split(id, "_") {
29+
name += strings.Title(part)
30+
}
31+
return name
32+
}

internal/codegen/golang/struct.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package golang
22

33
import (
4+
"strings"
5+
6+
"github.com/kyleconroy/sqlc/internal/config"
47
core "github.com/kyleconroy/sqlc/internal/pg"
58
)
69

@@ -10,3 +13,18 @@ type Struct struct {
1013
Fields []Field
1114
Comment string
1215
}
16+
17+
func StructName(name string, settings config.CombinedSettings) string {
18+
if rename := settings.Rename[name]; rename != "" {
19+
return rename
20+
}
21+
out := ""
22+
for _, p := range strings.Split(name, "_") {
23+
if p == "id" {
24+
out += "ID"
25+
} else {
26+
out += strings.Title(p)
27+
}
28+
}
29+
return out
30+
}

internal/compiler/build_result.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package compiler
2+
3+
import (
4+
"github.com/kyleconroy/sqlc/internal/codegen/golang"
5+
"github.com/kyleconroy/sqlc/internal/config"
6+
)
7+
8+
type BuildResult struct {
9+
enums []golang.Enum
10+
structs []golang.Struct
11+
queries []golang.Query
12+
}
13+
14+
func (r *BuildResult) Structs(settings config.CombinedSettings) []golang.Struct {
15+
return r.structs
16+
}
17+
18+
func (r *BuildResult) GoQueries(settings config.CombinedSettings) []golang.Query {
19+
return r.queries
20+
}
21+
22+
func (r *BuildResult) Enums(settings config.CombinedSettings) []golang.Enum {
23+
return r.enums
24+
}

internal/compiler/compat.go

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package compiler
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
core "github.com/kyleconroy/sqlc/internal/pg"
8+
"github.com/kyleconroy/sqlc/internal/sql/ast"
9+
"github.com/kyleconroy/sqlc/internal/sql/ast/pg"
10+
"github.com/kyleconroy/sqlc/internal/sql/astutils"
11+
)
12+
13+
func sameTableName(n *ast.TableName, f core.FQN) bool {
14+
if n == nil {
15+
return false
16+
}
17+
return n.Catalog == n.Catalog && n.Schema == f.Schema && n.Name == f.Rel
18+
}
19+
20+
// This is mainly copy-pasted from internal/postgresql/parse.go
21+
func stringSlice(list *ast.List) []string {
22+
items := []string{}
23+
for _, item := range list.Items {
24+
if n, ok := item.(*pg.String); ok {
25+
items = append(items, n.Str)
26+
continue
27+
}
28+
if n, ok := item.(*ast.String); ok {
29+
items = append(items, n.Str)
30+
continue
31+
}
32+
}
33+
return items
34+
}
35+
36+
type relation struct {
37+
Catalog string
38+
Schema string
39+
Name string
40+
}
41+
42+
func parseRelation(node ast.Node) (*relation, error) {
43+
switch n := node.(type) {
44+
45+
case *ast.List:
46+
parts := stringSlice(n)
47+
switch len(parts) {
48+
case 1:
49+
return &relation{
50+
Name: parts[0],
51+
}, nil
52+
case 2:
53+
return &relation{
54+
Schema: parts[0],
55+
Name: parts[1],
56+
}, nil
57+
case 3:
58+
return &relation{
59+
Catalog: parts[0],
60+
Schema: parts[1],
61+
Name: parts[2],
62+
}, nil
63+
default:
64+
return nil, fmt.Errorf("invalid name: %s", astutils.Join(n, "."))
65+
}
66+
67+
case *pg.RangeVar:
68+
name := relation{}
69+
if n.Catalogname != nil {
70+
name.Catalog = *n.Catalogname
71+
}
72+
if n.Schemaname != nil {
73+
name.Schema = *n.Schemaname
74+
}
75+
if n.Relname != nil {
76+
name.Name = *n.Relname
77+
}
78+
return &name, nil
79+
80+
case *pg.TypeName:
81+
return parseRelation(n.Names)
82+
83+
default:
84+
return nil, fmt.Errorf("unexpected node type: %T", n)
85+
}
86+
}
87+
88+
func parseTableName(node ast.Node) (*ast.TableName, error) {
89+
rel, err := parseRelation(node)
90+
if err != nil {
91+
return nil, fmt.Errorf("parse table name: %w", err)
92+
}
93+
return &ast.TableName{
94+
Catalog: rel.Catalog,
95+
Schema: rel.Schema,
96+
Name: rel.Name,
97+
}, nil
98+
}
99+
100+
func parseTypeName(node ast.Node) (*ast.TypeName, error) {
101+
rel, err := parseRelation(node)
102+
if err != nil {
103+
return nil, fmt.Errorf("parse table name: %w", err)
104+
}
105+
return &ast.TypeName{
106+
Catalog: rel.Catalog,
107+
Schema: rel.Schema,
108+
Name: rel.Name,
109+
}, nil
110+
}
111+
112+
func parseRelationString(name string) (*relation, error) {
113+
parts := strings.Split(name, ".")
114+
switch len(parts) {
115+
case 1:
116+
return &relation{
117+
Name: parts[0],
118+
}, nil
119+
case 2:
120+
return &relation{
121+
Schema: parts[0],
122+
Name: parts[1],
123+
}, nil
124+
case 3:
125+
return &relation{
126+
Catalog: parts[0],
127+
Schema: parts[1],
128+
Name: parts[2],
129+
}, nil
130+
default:
131+
return nil, fmt.Errorf("invalid name: %s", name)
132+
}
133+
}

internal/compiler/compile.go

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"io"
66
"io/ioutil"
7+
"path/filepath"
78
"regexp"
89
"sort"
910
"strings"
@@ -85,7 +86,9 @@ func parseCatalog(p Parser, c *catalog.Catalog, schemas []string) error {
8586
}
8687

8788
func parseQueries(p Parser, c *catalog.Catalog, queries []string) (*Result, error) {
89+
var q []*Query
8890
merr := multierr.New()
91+
set := map[string]struct{}{}
8992
files, err := sqlpath.Glob(queries)
9093
if err != nil {
9194
return nil, err
@@ -103,21 +106,41 @@ func parseQueries(p Parser, c *catalog.Catalog, queries []string) (*Result, erro
103106
continue
104107
}
105108
for _, stmt := range stmts {
106-
_, err := parseQuery(p, c, stmt.Raw, src, false)
109+
query, err := parseQuery(p, c, stmt.Raw, src, false)
110+
if err == ErrUnsupportedStatementType {
111+
continue
112+
}
107113
if err != nil {
108114
merr.Add(filename, src, stmt.Raw.Pos(), err)
109115
continue
110116
}
117+
if query.Name != "" {
118+
if _, exists := set[query.Name]; exists {
119+
merr.Add(filename, src, 0, fmt.Errorf("duplicate query name: %s", query.Name))
120+
continue
121+
}
122+
set[query.Name] = struct{}{}
123+
}
124+
query.Filename = filepath.Base(filename)
125+
if query != nil {
126+
q = append(q, query)
127+
}
111128
}
112129
}
113130
if len(merr.Errs()) > 0 {
114131
return nil, merr
115132
}
116-
return &Result{}, nil
133+
if len(q) == 0 {
134+
return nil, fmt.Errorf("no queries contained in paths %s", strings.Join(queries, ","))
135+
}
136+
return &Result{
137+
Catalog: c,
138+
Queries: q,
139+
}, nil
117140
}
118141

119142
// Deprecated.
120-
func buildResult(c *catalog.Catalog) (*Result, error) {
143+
func buildResult(c *catalog.Catalog) (*BuildResult, error) {
121144
var structs []golang.Struct
122145
var enums []golang.Enum
123146
for _, schema := range c.Schemas {
@@ -167,10 +190,10 @@ func buildResult(c *catalog.Catalog) (*Result, error) {
167190
if len(enums) > 0 {
168191
sort.Slice(enums, func(i, j int) bool { return enums[i].Name < enums[j].Name })
169192
}
170-
return &Result{structs: structs, enums: enums}, nil
193+
return &BuildResult{structs: structs, enums: enums}, nil
171194
}
172195

173-
func Run(conf config.SQL, combo config.CombinedSettings) (*Result, error) {
196+
func Run(conf config.SQL, combo config.CombinedSettings) (*BuildResult, error) {
174197
var c *catalog.Catalog
175198
var p Parser
176199

0 commit comments

Comments
 (0)