Skip to content

Commit dad80f4

Browse files
committed
Improve generated CountIntent.
1. Move count_intent to option. 2. Only SELECT query by default will have count intents.
1 parent a2d6677 commit dad80f4

5 files changed

Lines changed: 57 additions & 12 deletions

File tree

internal/codegen/golang/option.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import (
77
)
88

99
const (
10-
WPgxOptionKeyCache = "cache"
11-
WPgxOptionKeyInvalidate = "invalidate"
10+
WPgxOptionKeyCache = "cache"
11+
WPgxOptionKeyInvalidate = "invalidate"
12+
WpgxOptionKeyCountIntent = "count_intent"
1213
)
1314

1415
type WPgxOption struct {
1516
Cache time.Duration
1617
Invalidates []string
18+
CountIntent bool
1719
}
1820

1921
func parseOption(options map[string]string, queryNames map[string]bool) (rv WPgxOption, err error) {
@@ -24,7 +26,7 @@ func parseOption(options map[string]string, queryNames map[string]bool) (rv WPgx
2426
if err != nil {
2527
return
2628
}
27-
if rv.Cache < 1 * time.Millisecond {
29+
if rv.Cache < 1*time.Millisecond {
2830
return rv, fmt.Errorf("cache duration too short: %s", v)
2931
}
3032
case WPgxOptionKeyInvalidate:
@@ -37,6 +39,16 @@ func parseOption(options map[string]string, queryNames map[string]bool) (rv WPgx
3739
}
3840
rv.Invalidates = append(rv.Invalidates, queryName)
3941
}
42+
case WpgxOptionKeyCountIntent:
43+
if v == "true" {
44+
rv.CountIntent = true
45+
} else if v == "false" {
46+
rv.CountIntent = false
47+
} else {
48+
return rv, fmt.Errorf("Unknown count_intent value: %s", v)
49+
}
50+
default:
51+
return rv, fmt.Errorf("Unknown option: %s", k)
4052
}
4153
}
4254
return

internal/codegen/golang/query.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,11 @@ func (q Query) TableIdentifierForMySQL() string {
320320
return strings.Join(escapedNames, ".")
321321
}
322322

323+
// CountIntent is used by WPgx only.
324+
func (q Query) CountIntent() bool {
325+
return q.Option.CountIntent
326+
}
327+
323328
// CacheKey is used by WPgx only.
324329
func (q Query) CacheKey() string {
325330
return genCacheKeyWithArgName(q, q.Arg.Name)

internal/codegen/golang/templates/wpgx/queryCode.tmpl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ type {{.Ret.Type}} struct { {{- range .Ret.Struct.Fields}}
3636
{{range .Comments}}//{{.}}
3737
{{end -}}
3838
func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}} {{.InvalidateArgs}}) (*{{.Ret.Type}}, error) {
39+
{{- if .CountIntent }}
3940
q.db.CountIntent("{{.UniqueLabel}}")
41+
{{- end}}
4042
{{- if eq .Option.Cache.Milliseconds 0}}
4143
row := q.db.WQueryRow(ctx, "{{.UniqueLabel}}", {{.ConstantName}}, {{.Arg.Params}})
4244
var {{.Ret.Name}} *{{.Ret.Type}} = new({{.Ret.Type}})
@@ -99,7 +101,9 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}} {{.Invalida
99101
{{range .Comments}}//{{.}}
100102
{{end -}}
101103
func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}} {{.InvalidateArgs}}) ([]{{.Ret.Type}}, error) {
104+
{{- if .CountIntent }}
102105
q.db.CountIntent("{{.UniqueLabel}}")
106+
{{- end}}
103107
{{- if eq .Option.Cache.Milliseconds 0}}
104108
rows, err := q.db.WQuery(ctx, "{{.UniqueLabel}}", {{.ConstantName}}, {{.Arg.Params}})
105109
if err != nil {
@@ -179,7 +183,6 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}} {{.Invalida
179183
{{range .Comments}}//{{.}}
180184
{{end -}}
181185
func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}} {{.InvalidateArgs}}) error {
182-
q.db.CountIntent("{{.UniqueLabel}}")
183186
_, err := q.db.WExec(ctx, "{{.UniqueLabel}}", {{.ConstantName}}, {{.Arg.Params}})
184187
if err != nil {
185188
return err
@@ -214,7 +217,6 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}} {{.Invalida
214217
{{range .Comments}}//{{.}}
215218
{{end -}}
216219
func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}} {{.InvalidateArgs}}) (int64, error) {
217-
q.db.CountIntent("{{.UniqueLabel}}")
218220
result, err := q.db.WExec(ctx, "{{.UniqueLabel}}", {{.ConstantName}}, {{.Arg.Params}})
219221
if err != nil {
220222
return 0, err
@@ -249,7 +251,6 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}} {{.Invalida
249251
{{range .Comments}}//{{.}}
250252
{{end -}}
251253
func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}} {{.InvalidateArgs}}) (pgconn.CommandTag, error) {
252-
q.db.CountIntent("{{.UniqueLabel}}")
253254
rv, err := q.db.WExec(ctx, "{{.UniqueLabel}}", {{.ConstantName}}, {{.Arg.Params}})
254255
if err != nil {
255256
return rv, err

internal/compiler/parse.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
"github.com/sqlc-dev/sqlc/internal/sql/astutils"
1616
"github.com/sqlc-dev/sqlc/internal/sql/rewrite"
1717
"github.com/sqlc-dev/sqlc/internal/sql/validate"
18+
19+
"github.com/sqlc-dev/sqlc/internal/codegen/golang"
1820
)
1921

2022
var ErrUnsupportedStatementType = errors.New("parseQuery: unsupported statement type")
@@ -79,6 +81,11 @@ func (c *Compiler) parseQuery(stmt ast.Node, src string, o opts.Parser) (*Query,
7981
raw.Stmt, queryConfig.Name, queryConfig.Cmd, queryConfig.Options); err != nil {
8082
return nil, err
8183
}
84+
err = validateAndSetDefaultOptions(
85+
raw.Stmt, queryConfig.Name, queryConfig.Cmd, queryConfig.Options)
86+
if err != nil {
87+
return nil, err
88+
}
8289
rvs := rangeVars(raw.Stmt)
8390
refs, err := findParameters(raw.Stmt)
8491
if err != nil {
@@ -183,3 +190,29 @@ func uniqueParamRefs(in []paramRef, dollar bool) []paramRef {
183190
}
184191
return o
185192
}
193+
194+
// wicked-sqlc specific function
195+
func validateAndSetDefaultOptions(n ast.Node, name, cmd string, options map[string]string) error {
196+
countIntent, hasCountIntentDefaultVal := options[golang.WpgxOptionKeyCountIntent]
197+
if !(cmd == metadata.CmdMany || cmd == metadata.CmdOne) {
198+
if countIntent == "true" {
199+
return fmt.Errorf(
200+
"query %q uses count_intent option but cmd is neither 'one' or 'many'", name)
201+
}
202+
return nil
203+
}
204+
_, isSelect := n.(*ast.SelectStmt)
205+
if !hasCountIntentDefaultVal {
206+
if isSelect {
207+
options[golang.WpgxOptionKeyCountIntent] = "true"
208+
} else {
209+
options[golang.WpgxOptionKeyCountIntent] = "false"
210+
}
211+
}
212+
if !isSelect {
213+
if _, ok := options[golang.WPgxOptionKeyCache]; ok {
214+
return fmt.Errorf("query %q uses cache option but is not a SELECT", name)
215+
}
216+
}
217+
return nil
218+
}

internal/sql/validate/cmd.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import (
66

77
"github.com/sqlc-dev/sqlc/internal/metadata"
88
"github.com/sqlc-dev/sqlc/internal/sql/ast"
9-
10-
"github.com/sqlc-dev/sqlc/internal/codegen/golang"
119
)
1210

1311
func validateCopyfrom(n ast.Node) error {
@@ -80,9 +78,5 @@ func Cmd(n ast.Node, name, cmd string, options map[string]string) error {
8078
if list == nil || len(list.Items) == 0 {
8179
return fmt.Errorf("query %q specifies parameter %q without containing a RETURNING clause", name, cmd)
8280
}
83-
// XXX(yumin): dirty hack here to use the wpgx options here.
84-
if _, ok := options[golang.WPgxOptionKeyCache]; ok {
85-
return fmt.Errorf("query %q uses cache option but is not a SELECT", name)
86-
}
8781
return nil
8882
}

0 commit comments

Comments
 (0)