From cba2aac6a3d7ffba9371f246ed21691a4773c737 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 10 Oct 2023 16:46:02 -0700 Subject: [PATCH 1/9] feat(analyzer): Analyze queries using a running PostgreSQL database 94 of the open issues on sqlc are related to the analyzer. There are many cases where the current analyzer produces false positives or false negatives. sqlx and some other projects have proven that it's possible to extract query metadata from a running database. This approach is a bit different, in that the database analysis is layered on top of the existing query analyzer. We use the new analysis to provide better type information and support a wider set of cases when the existing analyzer fails. --- go.mod | 1 + go.sum | 3 + internal/analyzer/analyzer.go | 46 +++ internal/cmd/cmd.go | 23 +- internal/cmd/diff.go | 6 +- internal/cmd/generate.go | 14 +- internal/cmd/options.go | 24 ++ internal/cmd/package.go | 7 +- internal/cmd/vet.go | 10 +- internal/codegen/golang/result.go | 4 +- internal/compiler/analyze.go | 195 +++++++++++ internal/compiler/compile.go | 2 +- internal/compiler/engine.go | 45 ++- internal/compiler/expand.go | 29 +- internal/compiler/find_params.go | 9 +- internal/compiler/output_columns.go | 40 ++- internal/compiler/parse.go | 111 ++---- internal/compiler/query_catalog.go | 15 +- internal/compiler/resolve.go | 5 +- internal/config/config.go | 5 +- .../engine/postgresql/analyzer/analyze.go | 321 ++++++++++++++++++ internal/engine/postgresql/pg_catalog.go | 13 + internal/sql/named/param_set.go | 7 + internal/sql/validate/cmd.go | 11 +- internal/sql/validate/func_call.go | 29 +- internal/sql/validate/param_ref.go | 2 +- internal/sql/validate/param_style.go | 86 +++-- 27 files changed, 871 insertions(+), 192 deletions(-) create mode 100644 internal/analyzer/analyzer.go create mode 100644 internal/cmd/options.go create mode 100644 internal/compiler/analyze.go create mode 100644 internal/engine/postgresql/analyzer/analyze.go diff --git a/go.mod b/go.mod index f159367c74..53170cb5dc 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( require ( github.com/benbjohnson/clock v1.3.5 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect diff --git a/go.sum b/go.sum index 5c7434d1c3..938f46d429 100644 --- a/go.sum +++ b/go.sum @@ -100,7 +100,10 @@ github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSlj github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go new file mode 100644 index 0000000000..4ad7034823 --- /dev/null +++ b/internal/analyzer/analyzer.go @@ -0,0 +1,46 @@ +package analyzer + +import ( + "context" + + "github.com/sqlc-dev/sqlc/internal/sql/ast" + "github.com/sqlc-dev/sqlc/internal/sql/named" +) + +type Column struct { + Name string + OriginalName string + DataType string + NotNull bool + Unsigned bool + IsArray bool + ArrayDims int + Comment string + Length *int + IsNamedParam bool + IsFuncCall bool + + // XXX: Figure out what PostgreSQL calls `foo.id` + Scope string + Table *ast.TableName + TableAlias string + Type *ast.TypeName + EmbedTable *ast.TableName + + IsSqlcSlice bool // is this sqlc.slice() +} + +type Parameter struct { + Number int + Column *Column +} + +type Analysis struct { + Columns []Column + Params []Parameter +} + +type Analyzer interface { + Analyze(context.Context, ast.Node, string, []string, *named.ParamSet) (*Analysis, error) + Close(context.Context) error +} diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index 4b542d2f42..6e31be3ab8 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -197,7 +197,10 @@ var genCmd = &cobra.Command{ defer trace.StartRegion(cmd.Context(), "generate").End() stderr := cmd.ErrOrStderr() dir, name := getConfigPath(stderr, cmd.Flag("file")) - output, err := Generate(cmd.Context(), ParseEnv(cmd), dir, name, stderr) + output, err := Generate(cmd.Context(), dir, name, &Options{ + Env: ParseEnv(cmd), + Stderr: stderr, + }) if err != nil { os.Exit(1) } @@ -219,7 +222,11 @@ var uploadCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { stderr := cmd.ErrOrStderr() dir, name := getConfigPath(stderr, cmd.Flag("file")) - if err := createPkg(cmd.Context(), ParseEnv(cmd), dir, name, stderr); err != nil { + opts := &Options{ + Env: ParseEnv(cmd), + Stderr: stderr, + } + if err := createPkg(cmd.Context(), dir, name, opts); err != nil { fmt.Fprintf(stderr, "error uploading: %s\n", err) os.Exit(1) } @@ -234,7 +241,11 @@ var checkCmd = &cobra.Command{ defer trace.StartRegion(cmd.Context(), "compile").End() stderr := cmd.ErrOrStderr() dir, name := getConfigPath(stderr, cmd.Flag("file")) - if _, err := Generate(cmd.Context(), ParseEnv(cmd), dir, name, stderr); err != nil { + _, err := Generate(cmd.Context(), dir, name, &Options{ + Env: ParseEnv(cmd), + Stderr: stderr, + }) + if err != nil { os.Exit(1) } return nil @@ -277,7 +288,11 @@ var diffCmd = &cobra.Command{ defer trace.StartRegion(cmd.Context(), "diff").End() stderr := cmd.ErrOrStderr() dir, name := getConfigPath(stderr, cmd.Flag("file")) - if err := Diff(cmd.Context(), ParseEnv(cmd), dir, name, stderr); err != nil { + opts := &Options{ + Env: ParseEnv(cmd), + Stderr: stderr, + } + if err := Diff(cmd.Context(), dir, name, opts); err != nil { os.Exit(1) } return nil diff --git a/internal/cmd/diff.go b/internal/cmd/diff.go index aa1ddc8788..8998971a37 100644 --- a/internal/cmd/diff.go +++ b/internal/cmd/diff.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io" "os" "runtime/trace" "sort" @@ -13,8 +12,9 @@ import ( "github.com/cubicdaiya/gonp" ) -func Diff(ctx context.Context, e Env, dir, name string, stderr io.Writer) error { - output, err := Generate(ctx, e, dir, name, stderr) +func Diff(ctx context.Context, dir, name string, opts *Options) error { + stderr := opts.Stderr + output, err := Generate(ctx, dir, name, opts) if err != nil { return err } diff --git a/internal/cmd/generate.go b/internal/cmd/generate.go index 589295e74d..6c1ce3c57e 100644 --- a/internal/cmd/generate.go +++ b/internal/cmd/generate.go @@ -128,8 +128,11 @@ func readConfig(stderr io.Writer, dir, filename string) (string, *config.Config, return configPath, &conf, nil } -func Generate(ctx context.Context, e Env, dir, filename string, stderr io.Writer) (map[string]string, error) { - configPath, conf, err := readConfig(stderr, dir, filename) +func Generate(ctx context.Context, dir, filename string, o *Options) (map[string]string, error) { + e := o.Env + stderr := o.Stderr + + configPath, conf, err := o.ReadConfig(dir, filename) if err != nil { return nil, err } @@ -332,7 +335,12 @@ func remoteGenerate(ctx context.Context, configPath string, conf *config.Config, func parse(ctx context.Context, name, dir string, sql config.SQL, combo config.CombinedSettings, parserOpts opts.Parser, stderr io.Writer) (*compiler.Result, bool) { defer trace.StartRegion(ctx, "parse").End() - c := compiler.NewCompiler(sql, combo) + c, err := compiler.NewCompiler(sql, combo) + defer c.Close(ctx) + if err != nil { + fmt.Fprintf(stderr, "error creating compiler: %s\n", err) + return nil, true + } if err := c.ParseCatalog(sql.Schema); err != nil { fmt.Fprintf(stderr, "# package %s\n", name) if parserErr, ok := err.(*multierr.Error); ok { diff --git a/internal/cmd/options.go b/internal/cmd/options.go new file mode 100644 index 0000000000..8dd99fb04f --- /dev/null +++ b/internal/cmd/options.go @@ -0,0 +1,24 @@ +package cmd + +import ( + "io" + + "github.com/sqlc-dev/sqlc/internal/config" +) + +type Options struct { + Env Env + Stderr io.Writer + MutateConfig func(*config.Config) +} + +func (o *Options) ReadConfig(dir, filename string) (string, *config.Config, error) { + path, conf, err := readConfig(o.Stderr, dir, filename) + if err != nil { + return path, conf, err + } + if o.MutateConfig != nil { + o.MutateConfig(conf) + } + return path, conf, nil +} diff --git a/internal/cmd/package.go b/internal/cmd/package.go index 4b3318d915..c4d3df7fd5 100644 --- a/internal/cmd/package.go +++ b/internal/cmd/package.go @@ -2,13 +2,14 @@ package cmd import ( "context" - "io" "os" "github.com/sqlc-dev/sqlc/internal/bundler" ) -func createPkg(ctx context.Context, e Env, dir, filename string, stderr io.Writer) error { +func createPkg(ctx context.Context, dir, filename string, opts *Options) error { + e := opts.Env + stderr := opts.Stderr configPath, conf, err := readConfig(stderr, dir, filename) if err != nil { return err @@ -17,7 +18,7 @@ func createPkg(ctx context.Context, e Env, dir, filename string, stderr io.Write if err := up.Validate(); err != nil { return err } - output, err := Generate(ctx, e, dir, filename, stderr) + output, err := Generate(ctx, dir, filename, opts) if err != nil { os.Exit(1) } diff --git a/internal/cmd/vet.go b/internal/cmd/vet.go index 48fbc2a411..31aa3ec33c 100644 --- a/internal/cmd/vet.go +++ b/internal/cmd/vet.go @@ -47,8 +47,12 @@ func NewCmdVet() *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { defer trace.StartRegion(cmd.Context(), "vet").End() stderr := cmd.ErrOrStderr() + opts := &Options{ + Env: ParseEnv(cmd), + Stderr: stderr, + } dir, name := getConfigPath(stderr, cmd.Flag("file")) - if err := Vet(cmd.Context(), ParseEnv(cmd), dir, name, stderr); err != nil { + if err := Vet(cmd.Context(), dir, name, opts); err != nil { if !errors.Is(err, ErrFailedChecks) { fmt.Fprintf(stderr, "%s\n", err) } @@ -59,7 +63,9 @@ func NewCmdVet() *cobra.Command { } } -func Vet(ctx context.Context, e Env, dir, filename string, stderr io.Writer) error { +func Vet(ctx context.Context, dir, filename string, opts *Options) error { + e := opts.Env + stderr := opts.Stderr configPath, conf, err := readConfig(stderr, dir, filename) if err != nil { return err diff --git a/internal/codegen/golang/result.go b/internal/codegen/golang/result.go index 8e1c2714f7..a9fb9ee604 100644 --- a/internal/codegen/golang/result.go +++ b/internal/codegen/golang/result.go @@ -249,9 +249,7 @@ func buildQueries(req *plugin.CodeGenRequest, structs []Struct) ([]Query, error) if len(query.Columns) == 1 && query.Columns[0].EmbedTable == nil { c := query.Columns[0] name := columnName(c, 0) - if c.IsFuncCall { - name = strings.Replace(name, "$", "_", -1) - } + name = strings.Replace(name, "$", "_", -1) gq.Ret = QueryValue{ Name: name, DBName: name, diff --git a/internal/compiler/analyze.go b/internal/compiler/analyze.go new file mode 100644 index 0000000000..739cd07993 --- /dev/null +++ b/internal/compiler/analyze.go @@ -0,0 +1,195 @@ +package compiler + +import ( + "sort" + + "github.com/sqlc-dev/sqlc/internal/analyzer" + "github.com/sqlc-dev/sqlc/internal/config" + "github.com/sqlc-dev/sqlc/internal/source" + "github.com/sqlc-dev/sqlc/internal/sql/ast" + "github.com/sqlc-dev/sqlc/internal/sql/named" + "github.com/sqlc-dev/sqlc/internal/sql/rewrite" + "github.com/sqlc-dev/sqlc/internal/sql/validate" +) + +type analysis struct { + Table *ast.TableName + Columns []*Column + QueryCatalog *QueryCatalog + Parameters []Parameter + Named *named.ParamSet + Query string +} + +func convertColumn(c analyzer.Column) *Column { + return &Column{ + Name: c.Name, + OriginalName: c.OriginalName, + DataType: c.DataType, + NotNull: c.NotNull, + Unsigned: c.Unsigned, + IsArray: c.IsArray, + ArrayDims: c.ArrayDims, + Comment: c.Comment, + Length: c.Length, + IsNamedParam: c.IsNamedParam, + IsFuncCall: c.IsFuncCall, + Scope: c.Scope, + Table: c.Table, + TableAlias: c.TableAlias, + Type: c.Type, + EmbedTable: c.EmbedTable, + IsSqlcSlice: c.IsSqlcSlice, + } +} + +func combineAnalysis(prev *analysis, a *analyzer.Analysis) *analysis { + var cols []*Column + for _, c := range a.Columns { + cols = append(cols, convertColumn(c)) + } + var params []Parameter + for _, p := range a.Params { + params = append(params, Parameter{ + Number: p.Number, + Column: convertColumn(*p.Column), + }) + } + if len(prev.Columns) == len(cols) { + for i := range prev.Columns { + prev.Columns[i].DataType = cols[i].DataType + } + } else { + embedding := false + for i := range prev.Columns { + if prev.Columns[i].EmbedTable != nil { + embedding = true + } + } + if !embedding { + prev.Columns = cols + } + } + if len(prev.Parameters) == len(params) { + for i := range prev.Parameters { + prev.Parameters[i].Column.DataType = params[i].Column.DataType + } + } else { + prev.Parameters = params + } + return prev +} + +func (c *Compiler) analyzeQuery(raw *ast.RawStmt, query string) (*analysis, error) { + return c._analyzeQuery(raw, query, true) +} + +func (c *Compiler) inferQuery(raw *ast.RawStmt, query string) (*analysis, error) { + return c._analyzeQuery(raw, query, false) +} + +func (c *Compiler) _analyzeQuery(raw *ast.RawStmt, query string, failfast bool) (*analysis, error) { + errors := make([]error, 0) + check := func(err error) error { + if failfast { + return err + } + if err != nil { + errors = append(errors, err) + } + return nil + } + + numbers, dollar, err := validate.ParamRef(raw) + if err := check(err); err != nil { + return nil, err + } + + raw, namedParams, edits := rewrite.NamedParameters(c.conf.Engine, raw, numbers, dollar) + + var table *ast.TableName + switch n := raw.Stmt.(type) { + case *ast.CallStmt: + case *ast.SelectStmt: + case *ast.DeleteStmt: + case *ast.DoStmt: + case *ast.InsertStmt: + if err := check(validate.InsertStmt(n)); err != nil { + return nil, err + } + var err error + table, err = ParseTableName(n.Relation) + if err := check(err); err != nil { + return nil, err + } + case *ast.ListenStmt: + case *ast.NotifyStmt: + case *ast.TruncateStmt: + case *ast.UpdateStmt: + case *ast.RefreshMatViewStmt: + default: + if err := check(ErrUnsupportedStatementType); err != nil { + return nil, err + } + } + + if err := check(validate.FuncCall(c.catalog, c.combo, raw)); err != nil { + return nil, err + } + + if err := check(validate.In(c.catalog, raw)); err != nil { + return nil, err + } + rvs := rangeVars(raw.Stmt) + refs, errs := findParameters(raw.Stmt) + if len(errs) > 0 { + if failfast { + return nil, errs[0] + } + errors = append(errors, errs...) + } + refs = uniqueParamRefs(refs, dollar) + if c.conf.Engine == config.EngineMySQL || !dollar { + sort.Slice(refs, func(i, j int) bool { return refs[i].ref.Location < refs[j].ref.Location }) + } else { + sort.Slice(refs, func(i, j int) bool { return refs[i].ref.Number < refs[j].ref.Number }) + } + raw, embeds := rewrite.Embeds(raw) + qc, err := c.buildQueryCatalog(c.catalog, raw.Stmt, embeds) + if err := check(err); err != nil { + return nil, err + } + + params, err := c.resolveCatalogRefs(qc, rvs, refs, namedParams, embeds) + if err := check(err); err != nil { + return nil, err + } + cols, err := c.outputColumns(qc, raw.Stmt) + if err := check(err); err != nil { + return nil, err + } + + expandEdits, err := c.expand(qc, raw) + if check(err); err != nil { + return nil, err + } + edits = append(edits, expandEdits...) + expanded, err := source.Mutate(query, edits) + if err != nil { + return nil, err + } + + var rerr error + if len(errors) > 0 { + rerr = errors[0] + } + + return &analysis{ + Table: table, + Columns: cols, + Parameters: params, + QueryCatalog: qc, + Query: expanded, + Named: namedParams, + }, rerr +} diff --git a/internal/compiler/compile.go b/internal/compiler/compile.go index 5cbfab674a..a6744fc6d2 100644 --- a/internal/compiler/compile.go +++ b/internal/compiler/compile.go @@ -24,7 +24,6 @@ type Parser interface { IsReservedKeyword(string) bool } -// end copypasta func (c *Compiler) parseCatalog(schemas []string) error { files, err := sqlpath.Glob(schemas) if err != nil { @@ -38,6 +37,7 @@ func (c *Compiler) parseCatalog(schemas []string) error { continue } contents := migrations.RemoveRollbackStatements(string(blob)) + c.schema = append(c.schema, contents) stmts, err := c.parser.Parse(strings.NewReader(contents)) if err != nil { merr.Add(filename, contents, 0, err) diff --git a/internal/compiler/engine.go b/internal/compiler/engine.go index 032c1b0ba7..1287ef3e43 100644 --- a/internal/compiler/engine.go +++ b/internal/compiler/engine.go @@ -1,26 +1,44 @@ package compiler import ( + "context" "fmt" + "github.com/sqlc-dev/sqlc/internal/analyzer" "github.com/sqlc-dev/sqlc/internal/config" "github.com/sqlc-dev/sqlc/internal/engine/dolphin" "github.com/sqlc-dev/sqlc/internal/engine/postgresql" + pganalyze "github.com/sqlc-dev/sqlc/internal/engine/postgresql/analyzer" "github.com/sqlc-dev/sqlc/internal/engine/sqlite" "github.com/sqlc-dev/sqlc/internal/opts" + "github.com/sqlc-dev/sqlc/internal/quickdb" + pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1" "github.com/sqlc-dev/sqlc/internal/sql/catalog" ) type Compiler struct { - conf config.SQL - combo config.CombinedSettings - catalog *catalog.Catalog - parser Parser - result *Result + conf config.SQL + combo config.CombinedSettings + catalog *catalog.Catalog + parser Parser + result *Result + analyzer analyzer.Analyzer + client pb.QuickClient + + schema []string } -func NewCompiler(conf config.SQL, combo config.CombinedSettings) *Compiler { +func NewCompiler(conf config.SQL, combo config.CombinedSettings) (*Compiler, error) { c := &Compiler{conf: conf, combo: combo} + + if conf.Database != nil && conf.Database.Managed { + client, err := quickdb.NewClientFromConfig(combo.Global.Cloud) + if err != nil { + return nil, fmt.Errorf("client error: %w", err) + } + c.client = client + } + switch conf.Engine { case config.EngineSQLite: c.parser = sqlite.NewParser() @@ -31,10 +49,15 @@ func NewCompiler(conf config.SQL, combo config.CombinedSettings) *Compiler { case config.EnginePostgreSQL: c.parser = postgresql.NewParser() c.catalog = postgresql.NewCatalog() + if conf.Database != nil { + if conf.Database.Analyzer == nil || *conf.Database.Analyzer { + c.analyzer = pganalyze.New(c.client, *conf.Database) + } + } default: - panic(fmt.Sprintf("unknown engine: %s", conf.Engine)) + return nil, fmt.Errorf("unknown engine: %s", conf.Engine) } - return c + return c, nil } func (c *Compiler) Catalog() *catalog.Catalog { @@ -57,3 +80,9 @@ func (c *Compiler) ParseQueries(queries []string, o opts.Parser) error { func (c *Compiler) Result() *Result { return c.result } + +func (c *Compiler) Close(ctx context.Context) { + if c.analyzer != nil { + c.analyzer.Close(ctx) + } +} diff --git a/internal/compiler/expand.go b/internal/compiler/expand.go index 29adfa316a..60e654b696 100644 --- a/internal/compiler/expand.go +++ b/internal/compiler/expand.go @@ -2,6 +2,7 @@ package compiler import ( "fmt" + "regexp" "strings" "github.com/sqlc-dev/sqlc/internal/config" @@ -11,6 +12,14 @@ import ( ) func (c *Compiler) expand(qc *QueryCatalog, raw *ast.RawStmt) ([]source.Edit, error) { + // Return early if there are no A_Star nodes to expand + stars := astutils.Search(raw, func(node ast.Node) bool { + _, ok := node.(*ast.A_Star) + return ok + }) + if len(stars.Items) == 0 { + return nil, nil + } list := astutils.Search(raw, func(node ast.Node) bool { switch node.(type) { case *ast.DeleteStmt: @@ -36,14 +45,25 @@ func (c *Compiler) expand(qc *QueryCatalog, raw *ast.RawStmt) ([]source.Edit, er return edits, nil } +var validPostgresIdent = regexp.MustCompile(`^[a-z_][a-z0-9_$]*$`) + func (c *Compiler) quoteIdent(ident string) string { if c.parser.IsReservedKeyword(ident) { return c.quote(ident) } + // SQL identifiers and key words must begin with a letter (a-z, but also + // letters with diacritical marks and non-Latin letters) or an underscore + // (_). Subsequent characters in an identifier or key word can be letters, + // underscores, digits (0-9), or dollar signs ($). + // + // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS if c.conf.Engine == config.EnginePostgreSQL { // camelCase means the column is also camelCase if strings.ToLower(ident) != ident { - return "\"" + ident + "\"" + return c.quote(ident) + } + if !validPostgresIdent.MatchString(strings.ToLower(ident)) { + return c.quote(ident) } } return ident @@ -134,7 +154,11 @@ func (c *Compiler) expandStmt(qc *QueryCatalog, raw *ast.RawStmt, node ast.Node) } var old []string for _, p := range parts { - old = append(old, c.quoteIdent(p)) + if p == "*" { + old = append(old, p) + } else { + old = append(old, c.quoteIdent(p)) + } } var oldString string @@ -169,5 +193,6 @@ func (c *Compiler) expandStmt(qc *QueryCatalog, raw *ast.RawStmt, node ast.Node) New: strings.Join(cols, ", "), }) } + return edits, nil } diff --git a/internal/compiler/find_params.go b/internal/compiler/find_params.go index 41ffaf8ad7..ca38199b9d 100644 --- a/internal/compiler/find_params.go +++ b/internal/compiler/find_params.go @@ -7,14 +7,13 @@ import ( "github.com/sqlc-dev/sqlc/internal/sql/astutils" ) -func findParameters(root ast.Node) ([]paramRef, error) { +func findParameters(root ast.Node) ([]paramRef, []error) { refs := make([]paramRef, 0) errors := make([]error, 0) v := paramSearch{seen: make(map[int]struct{}), refs: &refs, errs: &errors} astutils.Walk(v, root) if len(*v.errs) > 0 { - problems := *v.errs - return nil, problems[0] + return refs, *v.errs } else { return refs, nil } @@ -54,10 +53,6 @@ func (l *limitOffset) Pos() int { } func (p paramSearch) Visit(node ast.Node) astutils.Visitor { - if len(*p.errs) > 0 { - return p - } - switch n := node.(type) { case *ast.A_Expr: diff --git a/internal/compiler/output_columns.go b/internal/compiler/output_columns.go index 75ff457d63..104957e18a 100644 --- a/internal/compiler/output_columns.go +++ b/internal/compiler/output_columns.go @@ -4,10 +4,9 @@ import ( "errors" "fmt" - "github.com/sqlc-dev/sqlc/internal/sql/catalog" - "github.com/sqlc-dev/sqlc/internal/sql/ast" "github.com/sqlc-dev/sqlc/internal/sql/astutils" + "github.com/sqlc-dev/sqlc/internal/sql/catalog" "github.com/sqlc-dev/sqlc/internal/sql/lang" "github.com/sqlc-dev/sqlc/internal/sql/sqlerr" ) @@ -523,6 +522,7 @@ func (c *Compiler) sourceTables(qc *QueryCatalog, node ast.Node) ([]*Table, erro var tables []*Table for _, item := range list.Items { + item := item switch n := item.(type) { case *ast.RangeFunction: @@ -555,16 +555,32 @@ func (c *Compiler) sourceTables(qc *QueryCatalog, node ast.Node) ([]*Table, erro Name: fn.ReturnType.Name, }) if err != nil { - if n.Alias == nil || len(n.Alias.Colnames.Items) == 0 { - continue - } - - table = &Table{} - for _, colName := range n.Alias.Colnames.Items { - table.Columns = append(table.Columns, &Column{ - Name: colName.(*ast.String).Str, - DataType: "any", - }) + if n.Alias != nil && len(n.Alias.Colnames.Items) > 0 { + table = &Table{} + for _, colName := range n.Alias.Colnames.Items { + table.Columns = append(table.Columns, &Column{ + Name: colName.(*ast.String).Str, + DataType: "any", + }) + } + } else { + colName := fn.Rel.Name + if n.Alias != nil { + colName = *n.Alias.Aliasname + } + table = &Table{ + Rel: &ast.TableName{ + Catalog: fn.Rel.Catalog, + Schema: fn.Rel.Schema, + Name: fn.Rel.Name, + }, + Columns: []*Column{ + { + Name: colName, + DataType: fn.ReturnType.Name, + }, + }, + } } } if n.Alias != nil { diff --git a/internal/compiler/parse.go b/internal/compiler/parse.go index c660ef4fb4..53e3043c7d 100644 --- a/internal/compiler/parse.go +++ b/internal/compiler/parse.go @@ -1,63 +1,40 @@ package compiler import ( + "context" "errors" "fmt" - "sort" "strings" - "github.com/sqlc-dev/sqlc/internal/config" "github.com/sqlc-dev/sqlc/internal/debug" "github.com/sqlc-dev/sqlc/internal/metadata" "github.com/sqlc-dev/sqlc/internal/opts" "github.com/sqlc-dev/sqlc/internal/source" "github.com/sqlc-dev/sqlc/internal/sql/ast" "github.com/sqlc-dev/sqlc/internal/sql/astutils" - "github.com/sqlc-dev/sqlc/internal/sql/rewrite" "github.com/sqlc-dev/sqlc/internal/sql/validate" ) var ErrUnsupportedStatementType = errors.New("parseQuery: unsupported statement type") func (c *Compiler) parseQuery(stmt ast.Node, src string, o opts.Parser) (*Query, error) { + ctx := context.Background() + if o.Debug.DumpAST { debug.Dump(stmt) } - if err := validate.ParamStyle(stmt); err != nil { - return nil, err - } - numbers, dollar, err := validate.ParamRef(stmt) - if err != nil { + + // validate sqlc-specific syntax + if err := validate.SqlcFunctions(stmt); err != nil { return nil, err } + + // rewrite queries to remove sqlc.* functions + raw, ok := stmt.(*ast.RawStmt) if !ok { return nil, errors.New("node is not a statement") } - var table *ast.TableName - switch n := raw.Stmt.(type) { - case *ast.CallStmt: - case *ast.SelectStmt: - case *ast.DeleteStmt: - case *ast.DoStmt: - case *ast.InsertStmt: - if err := validate.InsertStmt(n); err != nil { - return nil, err - } - var err error - table, err = ParseTableName(n.Relation) - if err != nil { - return nil, err - } - case *ast.ListenStmt: - case *ast.NotifyStmt: - case *ast.TruncateStmt: - case *ast.UpdateStmt: - case *ast.RefreshMatViewStmt: - default: - return nil, ErrUnsupportedStatementType - } - rawSQL, err := source.Pluck(src, raw.StmtLocation, raw.StmtLen) if err != nil { return nil, err @@ -65,56 +42,42 @@ func (c *Compiler) parseQuery(stmt ast.Node, src string, o opts.Parser) (*Query, if rawSQL == "" { return nil, errors.New("missing semicolon at end of file") } - if err := validate.FuncCall(c.catalog, c.combo, raw); err != nil { - return nil, err - } - if err := validate.In(c.catalog, raw); err != nil { - return nil, err - } + name, cmd, err := metadata.ParseQueryNameAndType(strings.TrimSpace(rawSQL), c.parser.CommentSyntax()) if err != nil { return nil, err } - raw, namedParams, edits := rewrite.NamedParameters(c.conf.Engine, raw, numbers, dollar) if err := validate.Cmd(raw.Stmt, name, cmd); err != nil { return nil, err } - rvs := rangeVars(raw.Stmt) - refs, err := findParameters(raw.Stmt) - if err != nil { - return nil, err - } - refs = uniqueParamRefs(refs, dollar) - if c.conf.Engine == config.EngineMySQL || !dollar { - sort.Slice(refs, func(i, j int) bool { return refs[i].ref.Location < refs[j].ref.Location }) - } else { - sort.Slice(refs, func(i, j int) bool { return refs[i].ref.Number < refs[j].ref.Number }) - } - raw, embeds := rewrite.Embeds(raw) - qc, err := c.buildQueryCatalog(c.catalog, raw.Stmt, embeds) - if err != nil { - return nil, err - } - params, err := c.resolveCatalogRefs(qc, rvs, refs, namedParams, embeds) - if err != nil { - return nil, err - } - cols, err := c.outputColumns(qc, raw.Stmt) - if err != nil { - return nil, err - } + var anlys *analysis + if c.analyzer != nil { + // TODO: Handle panics + inference, _ := c.inferQuery(raw, rawSQL) + if inference == nil { + inference = &analysis{} + } + if inference.Query == "" { + inference.Query = rawSQL + } - expandEdits, err := c.expand(qc, raw) - if err != nil { - return nil, err - } - edits = append(edits, expandEdits...) - expanded, err := source.Mutate(rawSQL, edits) - if err != nil { - return nil, err + result, err := c.analyzer.Analyze(ctx, raw, inference.Query, c.schema, inference.Named) + if err != nil { + return nil, err + } + + // FOOTGUN: combineAnalysis mutates inference + anlys = combineAnalysis(inference, result) + } else { + anlys, err = c.analyzeQuery(raw, rawSQL) + if err != nil { + return nil, err + } } + expanded := anlys.Query + // If the query string was edited, make sure the syntax is valid if expanded != rawSQL { if _, err := c.parser.Parse(strings.NewReader(expanded)); err != nil { @@ -138,10 +101,10 @@ func (c *Compiler) parseQuery(stmt ast.Node, src string, o opts.Parser) (*Query, Comments: comments, Name: name, Flags: flags, - Params: params, - Columns: cols, + Params: anlys.Parameters, + Columns: anlys.Columns, SQL: trimmed, - InsertIntoTable: table, + InsertIntoTable: anlys.Table, }, nil } diff --git a/internal/compiler/query_catalog.go b/internal/compiler/query_catalog.go index ea1190c0de..42088446d2 100644 --- a/internal/compiler/query_catalog.go +++ b/internal/compiler/query_catalog.go @@ -36,9 +36,22 @@ func (comp *Compiler) buildQueryCatalog(c *catalog.Catalog, node ast.Node, embed if err != nil { return nil, err } + var names []string + if cte.Aliascolnames != nil { + for _, item := range cte.Aliascolnames.Items { + if val, ok := item.(*ast.String); ok { + names = append(names, val.Str) + } else { + names = append(names, "") + } + } + } rel := &ast.TableName{Name: *cte.Ctename} for i := range cols { cols[i].Table = rel + if len(names) > i { + cols[i].Name = names[i] + } } qc.ctes[*cte.Ctename] = &Table{ Rel: rel, @@ -67,7 +80,7 @@ func ConvertColumn(rel *ast.TableName, c *catalog.Column) *Column { func (qc QueryCatalog) GetTable(rel *ast.TableName) (*Table, error) { cte, exists := qc.ctes[rel.Name] if exists { - return cte, nil + return &Table{Rel: rel, Columns: cte.Columns}, nil } src, err := qc.catalog.GetTable(rel) if err != nil { diff --git a/internal/compiler/resolve.go b/internal/compiler/resolve.go index 0a91b45f25..3b80a7d118 100644 --- a/internal/compiler/resolve.go +++ b/internal/compiler/resolve.go @@ -10,6 +10,7 @@ import ( "github.com/sqlc-dev/sqlc/internal/sql/named" "github.com/sqlc-dev/sqlc/internal/sql/rewrite" "github.com/sqlc-dev/sqlc/internal/sql/sqlerr" + "golang.org/x/exp/slog" ) func dataType(n *ast.TypeName) string { @@ -580,8 +581,6 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar, }) } } - } else { - fmt.Println("------------------------") } if found == 0 { @@ -600,7 +599,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar, } default: - fmt.Printf("unsupported reference type: %T\n", n) + slog.Debug("unsupported reference type", "type", fmt.Sprintf("%T", n)) } } return a, nil diff --git a/internal/config/config.go b/internal/config/config.go index 4a17903e6e..a33dd51490 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -64,8 +64,9 @@ type Config struct { } type Database struct { - URI string `json:"uri" yaml:"uri"` - Managed bool `json:"managed" yaml:"managed"` + URI string `json:"uri" yaml:"uri"` + Managed bool `json:"managed" yaml:"managed"` + Analyzer *bool `json:"analyzer" yaml:"analyzer"` } type Cloud struct { diff --git a/internal/engine/postgresql/analyzer/analyze.go b/internal/engine/postgresql/analyzer/analyze.go new file mode 100644 index 0000000000..160dcc83ac --- /dev/null +++ b/internal/engine/postgresql/analyzer/analyze.go @@ -0,0 +1,321 @@ +package analyzer + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + "time" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" + "github.com/jackc/pgx/v5/pgxpool" + + core "github.com/sqlc-dev/sqlc/internal/analyzer" + "github.com/sqlc-dev/sqlc/internal/config" + pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1" + "github.com/sqlc-dev/sqlc/internal/sql/ast" + "github.com/sqlc-dev/sqlc/internal/sql/named" + "github.com/sqlc-dev/sqlc/internal/sql/sqlerr" +) + +type Analyzer struct { + db config.Database + client pb.QuickClient + pool *pgxpool.Pool + + formats sync.Map + columns sync.Map + tables sync.Map +} + +func New(client pb.QuickClient, db config.Database) *Analyzer { + return &Analyzer{ + db: db, + client: client, + } +} + +const columnQuery = ` +SELECT + pg_catalog.format_type(pg_attribute.atttypid, pg_attribute.atttypmod) AS data_type, + pg_attribute.attnotnull as not_null, + pg_attribute.attndims as array_dims +FROM + pg_catalog.pg_attribute +WHERE + attrelid = $1 + AND attnum = $2; +` + +const tableQuery = ` +SELECT + pg_class.relname as table_name, + pg_namespace.nspname as schema_name +FROM + pg_catalog.pg_class +JOIN + pg_catalog.pg_namespace ON pg_namespace.oid = pg_class.relnamespace +WHERE + pg_class.oid = $1; +` + +type pgTable struct { + TableName string `db:"table_name"` + SchemaName string `db:"schema_name"` +} + +// Cache these types in memory +func (a *Analyzer) tableInfo(ctx context.Context, oid uint32) (*pgTable, error) { + ctbl, ok := a.tables.Load(oid) + if ok { + return ctbl.(*pgTable), nil + } + rows, err := a.pool.Query(ctx, tableQuery, oid) + if err != nil { + return nil, err + } + tbl, err := pgx.CollectOneRow(rows, pgx.RowToStructByName[pgTable]) + if err != nil { + return nil, err + } + a.tables.Store(oid, &tbl) + return &tbl, nil +} + +type pgColumn struct { + DataType string `db:"data_type"` + NotNull bool `db:"not_null"` + ArrayDims int `db:"array_dims"` +} + +type columnKey struct { + OID uint32 + Attr uint16 +} + +// Cache these types in memory +func (a *Analyzer) columnInfo(ctx context.Context, field pgconn.FieldDescription) (*pgColumn, error) { + key := columnKey{field.TableOID, field.TableAttributeNumber} + cinfo, ok := a.columns.Load(key) + if ok { + return cinfo.(*pgColumn), nil + } + + rows, err := a.pool.Query(ctx, columnQuery, field.TableOID, field.TableAttributeNumber) + if err != nil { + return nil, err + } + col, err := pgx.CollectOneRow(rows, pgx.RowToStructByName[pgColumn]) + if err != nil { + return nil, err + } + a.columns.Store(key, &col) + return &col, nil +} + +type formatKey struct { + OID uint32 + Modified int32 +} + +// TODO: Use PGX to do the lookup for basic OID types +func (a *Analyzer) formatType(ctx context.Context, oid uint32, modifier int32) (string, error) { + key := formatKey{oid, modifier} + ftyp, ok := a.formats.Load(key) + if ok { + return ftyp.(string), nil + } + rows, err := a.pool.Query(ctx, `SELECT format_type($1, $2)`, oid, modifier) + if err != nil { + return "", err + } + dt, err := pgx.CollectOneRow(rows, pgx.RowTo[string]) + if err != nil { + return "", err + } + a.formats.Store(key, dt) + return dt, err +} + +// TODO: This is bad +func rewriteType(dt string) string { + switch { + case strings.HasPrefix(dt, "character("): + return "pg_catalog.bpchar" + case strings.HasPrefix(dt, "character varying"): + return "pg_catalog.varchar" + case strings.HasPrefix(dt, "bit varying"): + return "pg_catalog.varbit" + case strings.HasPrefix(dt, "bit("): + return "pg_catalog.bit" + } + switch dt { + case "bpchar": + return "pg_catalog.bpchar" + case "timestamp without time zone": + return "pg_catalog.timestamp" + case "timestamp with time zone": + return "pg_catalog.timestamptz" + case "time without time zone": + return "pg_catalog.time" + case "time with time zone": + return "pg_catalog.timetz" + } + return dt +} + +func parseType(dt string) (string, bool, int) { + size := 0 + for { + trimmed := strings.TrimSuffix(dt, "[]") + if trimmed == dt { + return rewriteType(dt), size > 0, size + } + size += 1 + dt = trimmed + } +} + +// Don't create a database per query +func (a *Analyzer) Analyze(ctx context.Context, n ast.Node, query string, migrations []string, ps *named.ParamSet) (*core.Analysis, error) { + extractSqlErr := func(e error) error { + var pgErr *pgconn.PgError + if errors.As(e, &pgErr) { + return &sqlerr.Error{ + Code: pgErr.Code, + Message: pgErr.Message, + Location: max(n.Pos()+int(pgErr.Position)-1, 0), + } + } + return e + } + + if a.pool == nil { + var uri string + if a.db.Managed { + if a.client == nil { + return nil, fmt.Errorf("client is nil") + } + edb, err := a.client.CreateEphemeralDatabase(ctx, &pb.CreateEphemeralDatabaseRequest{ + Engine: "postgresql", + Migrations: migrations, + }) + if err != nil { + return nil, err + } + uri = edb.Uri + } else { + uri = a.db.URI + } + conf, err := pgxpool.ParseConfig(uri) + if err != nil { + return nil, err + } + conf.MaxConns = 2 + conf.MinConns = 0 + conf.MaxConnLifetime = time.Second * 1 + pool, err := pgxpool.NewWithConfig(ctx, conf) + if err != nil { + return nil, err + } + a.pool = pool + } + + c, err := a.pool.Acquire(ctx) + if err != nil { + return nil, err + } + defer c.Release() + + // TODO: Pick a random name + desc, err := c.Conn().Prepare(ctx, "foo", query) + if err != nil { + return nil, extractSqlErr(err) + } + + if err := c.Conn().Deallocate(ctx, "foo"); err != nil { + return nil, err + } + + var result core.Analysis + for _, field := range desc.Fields { + if field.TableOID > 0 { + col, err := a.columnInfo(ctx, field) + if err != nil { + return nil, err + } + // debug.Dump(i, field, col) + tbl, err := a.tableInfo(ctx, field.TableOID) + if err != nil { + return nil, err + } + // TODO: Why are these dims different? + dt, isArray, _ := parseType(col.DataType) + notNull := col.NotNull + name := field.Name + result.Columns = append(result.Columns, core.Column{ + Name: name, + OriginalName: field.Name, + DataType: dt, + NotNull: notNull, + IsArray: isArray, + ArrayDims: col.ArrayDims, + Table: &ast.TableName{ + Schema: tbl.SchemaName, + Name: tbl.TableName, + }, + }) + } else { + dataType, err := a.formatType(ctx, field.DataTypeOID, field.TypeModifier) + if err != nil { + return nil, err + } + // debug.Dump(i, field, dataType) + notNull := false + name := field.Name + dt, isArray, dims := parseType(dataType) + result.Columns = append(result.Columns, core.Column{ + Name: name, + OriginalName: field.Name, + DataType: dt, + NotNull: notNull, + IsArray: isArray, + ArrayDims: dims, + }) + } + } + + for i, oid := range desc.ParamOIDs { + dataType, err := a.formatType(ctx, oid, -1) + if err != nil { + return nil, err + } + notNull := false + dt, isArray, dims := parseType(dataType) + name := "" + if ps != nil { + name, _ = ps.NameFor(i + 1) + } + result.Params = append(result.Params, core.Parameter{ + Number: i + 1, + Column: &core.Column{ + Name: name, + DataType: dt, + IsArray: isArray, + ArrayDims: dims, + NotNull: notNull, + }, + }) + } + + return &result, nil +} + +func (a *Analyzer) Close(_ context.Context) error { + if a.pool != nil { + a.pool.Close() + } + return nil +} diff --git a/internal/engine/postgresql/pg_catalog.go b/internal/engine/postgresql/pg_catalog.go index 9000b592f4..7020c0ff14 100644 --- a/internal/engine/postgresql/pg_catalog.go +++ b/internal/engine/postgresql/pg_catalog.go @@ -29072,6 +29072,19 @@ var funcsgenPGCatalog = []*catalog.Function{ }, ReturnType: &ast.TypeName{Name: "anyelement"}, }, + { + Name: "unnest", + Args: []*catalog.Argument{ + { + Type: &ast.TypeName{Name: "anyarray"}, + }, + { + Type: &ast.TypeName{Name: "anyarray"}, + Mode: ast.FuncParamVariadic, + }, + }, + ReturnType: &ast.TypeName{Name: "anyelement"}, + }, { Name: "unnest", Args: []*catalog.Argument{ diff --git a/internal/sql/named/param_set.go b/internal/sql/named/param_set.go index b30de738b3..d47617a39e 100644 --- a/internal/sql/named/param_set.go +++ b/internal/sql/named/param_set.go @@ -14,6 +14,13 @@ type ParamSet struct { argn int } +// Return the name for a given parameter number and a boolean indicating if it +// was found. +func (p *ParamSet) NameFor(idx int) (string, bool) { + name, ok := p.positionToName[idx] + return name, ok +} + func (p *ParamSet) nextArgNum() int { for { if _, ok := p.positionToName[p.argn]; !ok { diff --git a/internal/sql/validate/cmd.go b/internal/sql/validate/cmd.go index 079c10c3f9..962e340dea 100644 --- a/internal/sql/validate/cmd.go +++ b/internal/sql/validate/cmd.go @@ -6,6 +6,8 @@ import ( "github.com/sqlc-dev/sqlc/internal/metadata" "github.com/sqlc-dev/sqlc/internal/sql/ast" + "github.com/sqlc-dev/sqlc/internal/sql/astutils" + "github.com/sqlc-dev/sqlc/internal/sql/named" ) func validateCopyfrom(n ast.Node) error { @@ -45,8 +47,13 @@ func validateCopyfrom(n ast.Node) error { } func validateBatch(n ast.Node) error { - nums, _, _ := ParamRef(n) - if len(nums) == 0 { + funcs := astutils.Search(n, named.IsParamFunc) + params := astutils.Search(n, named.IsParamSign) + args := astutils.Search(n, func(n ast.Node) bool { + _, ok := n.(*ast.ParamRef) + return ok + }) + if (len(params.Items) + len(funcs.Items) + len(args.Items)) == 0 { return errors.New(":batch* commands require parameters") } return nil diff --git a/internal/sql/validate/func_call.go b/internal/sql/validate/func_call.go index 383366c68f..75a2cd5d37 100644 --- a/internal/sql/validate/func_call.go +++ b/internal/sql/validate/func_call.go @@ -2,7 +2,6 @@ package validate import ( "errors" - "fmt" "github.com/sqlc-dev/sqlc/internal/config" "github.com/sqlc-dev/sqlc/internal/sql/ast" @@ -31,34 +30,8 @@ func (v *funcCallVisitor) Visit(node ast.Node) astutils.Visitor { return v } - // Custom validation for sqlc.arg, sqlc.narg and sqlc.slice - // TODO: Replace this once type-checking is implemented + // Maybe not necessary now? if fn.Schema == "sqlc" { - if !(fn.Name == "arg" || fn.Name == "narg" || fn.Name == "slice" || fn.Name == "embed") { - v.err = sqlerr.FunctionNotFound("sqlc." + fn.Name) - return nil - } - - if len(call.Args.Items) != 1 { - v.err = &sqlerr.Error{ - Message: fmt.Sprintf("expected 1 parameter to sqlc.%s; got %d", fn.Name, len(call.Args.Items)), - Location: call.Pos(), - } - return nil - } - switch n := call.Args.Items[0].(type) { - case *ast.A_Const: - case *ast.ColumnRef: - default: - v.err = &sqlerr.Error{ - Message: fmt.Sprintf("expected parameter to sqlc.%s to be string or reference; got %T", fn.Name, n), - Location: call.Pos(), - } - return nil - } - - // If we have sqlc.arg or sqlc.narg, there is no need to resolve the function call. - // It won't resolve anyway, sinc it is not a real function. return nil } diff --git a/internal/sql/validate/param_ref.go b/internal/sql/validate/param_ref.go index 1ee04bb5e7..ab9413f40f 100644 --- a/internal/sql/validate/param_ref.go +++ b/internal/sql/validate/param_ref.go @@ -38,7 +38,7 @@ func ParamRef(n ast.Node) (map[int]bool, bool, error) { } for i := 1; i <= len(seen); i += 1 { if _, ok := seen[i]; !ok { - return nil, false, &sqlerr.Error{ + return seen, !nodollar, &sqlerr.Error{ Code: "42P18", Message: fmt.Sprintf("could not determine data type of parameter $%d", i), } diff --git a/internal/sql/validate/param_style.go b/internal/sql/validate/param_style.go index 64f8bd9c87..1182051d20 100644 --- a/internal/sql/validate/param_style.go +++ b/internal/sql/validate/param_style.go @@ -1,48 +1,68 @@ package validate import ( + "fmt" + "github.com/sqlc-dev/sqlc/internal/sql/ast" "github.com/sqlc-dev/sqlc/internal/sql/astutils" - "github.com/sqlc-dev/sqlc/internal/sql/named" "github.com/sqlc-dev/sqlc/internal/sql/sqlerr" ) -// A query can use one (and only one) of the following formats: -// - positional parameters $1 -// - named parameter operator @param -// - named parameter function calls sqlc.arg(param) -func ParamStyle(n ast.Node) error { - namedFunc := astutils.Search(n, named.IsParamFunc) - for _, f := range namedFunc.Items { - if fc, ok := f.(*ast.FuncCall); ok { - args := fc.Args.Items - - if len(args) == 0 { - continue - } +type sqlcFuncVisitor struct { + err error +} + +func (v *sqlcFuncVisitor) Visit(node ast.Node) astutils.Visitor { + if v.err != nil { + return nil + } + + call, ok := node.(*ast.FuncCall) + if !ok { + return v + } + fn := call.Func + if fn == nil { + return v + } - switch val := args[0].(type) { - case *ast.FuncCall: - return &sqlerr.Error{ - Code: "", // TODO: Pick a new error code - Message: "Invalid argument to sqlc.arg()", - Location: val.Location, - } - case *ast.ParamRef: - return &sqlerr.Error{ - Code: "", // TODO: Pick a new error code - Message: "Invalid argument to sqlc.arg()", - Location: val.Location, - } - case *ast.A_Const, *ast.ColumnRef: - default: - return &sqlerr.Error{ - Code: "", // TODO: Pick a new error code - Message: "Invalid argument to sqlc.arg()", - } + // Custom validation for sqlc.arg, sqlc.narg and sqlc.slice + // TODO: Replace this once type-checking is implemented + if fn.Schema == "sqlc" { + if !(fn.Name == "arg" || fn.Name == "narg" || fn.Name == "slice" || fn.Name == "embed") { + v.err = sqlerr.FunctionNotFound("sqlc." + fn.Name) + return nil + } + + if len(call.Args.Items) != 1 { + v.err = &sqlerr.Error{ + Message: fmt.Sprintf("expected 1 parameter to sqlc.%s; got %d", fn.Name, len(call.Args.Items)), + Location: call.Pos(), + } + return nil + } + switch n := call.Args.Items[0].(type) { + case *ast.A_Const: + case *ast.ColumnRef: + default: + v.err = &sqlerr.Error{ + Message: fmt.Sprintf("expected parameter to sqlc.%s to be string or reference; got %T", fn.Name, n), + Location: call.Pos(), } + return nil } + + // If we have sqlc.arg or sqlc.narg, there is no need to resolve the function call. + // It won't resolve anyway, sinc it is not a real function. + return nil } + return nil } + +func SqlcFunctions(n ast.Node) error { + visitor := sqlcFuncVisitor{} + astutils.Walk(&visitor, n) + return visitor.err +} From 48f638b59f61be0a38afe0ac6d4e1e429a5afbbc Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Tue, 10 Oct 2023 16:47:32 -0700 Subject: [PATCH 2/9] test(analyzer): Update endtoend tests for new analyzer Add a `contexts` key to exec.json to opt certain tests into or out of database-backed analysis. Fix many incorrect test cases that didn't run against an actual database. --- examples/authors/sqlc.yaml | 1 + examples/booktest/sqlc.json | 3 +- examples/jets/sqlc.json | 1 + examples/ondeck/sqlc.json | 3 +- internal/endtoend/endtoend_test.go | 178 ++++++++++++------ .../alias/postgresql/stdlib/schema.sql | 3 +- .../postgresql/pganalyze/exec.json | 3 + .../postgresql/pganalyze}/go/db.go | 0 .../postgresql/pganalyze}/go/models.go | 6 +- .../postgresql/pganalyze/go/query.sql.go | 43 +++++ .../postgresql/pganalyze/query.sql | 4 + .../postgresql/pganalyze/schema.sql | 5 + .../postgresql/pganalyze/sqlc.json | 19 ++ .../coalesce_as/postgresql/pgx/v4/exec.json | 3 + .../coalesce_as/postgresql/pgx/v5/exec.json | 3 + .../coalesce_as/postgresql/stdlib/exec.json | 3 + .../endtoend/testdata/codegen_json/exec.json | 3 + .../stdlib/go/query.sql.go | 2 +- .../endtoend/testdata/cte_left_join/issue.md | 1 + .../cte_left_join/postgresql/pgx/exec.json | 3 + .../cte_left_join/postgresql/pgx/go/db.go | 32 ++++ .../cte_left_join/postgresql/pgx/go/models.go | 21 +++ .../postgresql/pgx/go/query.sql.go | 39 ++++ .../cte_left_join/postgresql/pgx/query.sql | 15 ++ .../cte_left_join/postgresql/pgx/schema.sql | 11 ++ .../cte_left_join/postgresql/pgx/sqlc.yaml | 10 + .../testdata/cte_multiple_alias/issue.md | 1 + .../postgresql/pgx/go/db.go | 32 ++++ .../postgresql/pgx/go/models.go | 21 +++ .../postgresql/pgx/go/query.sql.go | 48 +++++ .../postgresql/pgx/query.sql | 15 ++ .../postgresql/pgx/schema.sql | 11 ++ .../postgresql/pgx/sqlc.yaml | 10 + .../testdata/cte_recursive_employees/issue.md | 1 + .../postgresql/pgx/exec.json | 3 + .../postgresql/pgx/go/db.go | 32 ++++ .../postgresql/pgx/go/models.go | 15 ++ .../postgresql/pgx/go/query.sql.go | 56 ++++++ .../postgresql/pgx/query.sql | 22 +++ .../postgresql/pgx/schema.sql | 5 + .../postgresql/pgx/sqlc.yaml | 10 + .../testdata/cte_recursive_star/issue.md | 1 + .../postgresql/pgx/exec.json | 3 + .../postgresql/pgx/go/db.go | 32 ++++ .../postgresql/pgx/go/models.go | 27 +++ .../postgresql/pgx/go/query.sql.go | 59 ++++++ .../postgresql/pgx/query.sql | 7 + .../postgresql/pgx/schema.sql | 17 ++ .../postgresql/pgx/sqlc.yaml | 10 + .../endtoend/testdata/cte_select_one/issue.md | 1 + .../cte_select_one/postgresql/pgx/go/db.go | 32 ++++ .../postgresql/pgx/go/models.go | 7 + .../postgresql/pgx/go/query.sql.go | 24 +++ .../cte_select_one/postgresql/pgx/query.sql | 5 + .../cte_select_one/postgresql/pgx/schema.sql | 1 + .../cte_select_one/postgresql/pgx/sqlc.yaml | 10 + .../postgresql/pganalyze/exec.json | 3 + .../cte_with_in/postgresql/pganalyze/go/db.go | 32 ++++ .../postgresql/pganalyze/go/models.go | 20 ++ .../postgresql/pganalyze/go/query.sql.go | 164 ++++++++++++++++ .../postgresql/pganalyze/query.sql | 34 ++++ .../postgresql/pganalyze/schema.sql | 12 ++ .../postgresql/pganalyze/sqlc.json | 14 ++ .../enum/postgresql/pgx/v4/go/query.sql.go | 5 +- .../testdata/enum/postgresql/pgx/v4/query.sql | 3 +- .../enum/postgresql/pgx/v5/go/query.sql.go | 5 +- .../testdata/enum/postgresql/pgx/v5/query.sql | 5 +- .../enum/postgresql/stdlib/go/query.sql.go | 5 +- .../testdata/enum/postgresql/stdlib/query.sql | 5 +- .../func_aggregate/pganalyze/exec.json | 3 + .../func_aggregate/{ => pganalyze}/go/db.go | 0 .../{ => pganalyze}/go/models.go | 0 .../func_aggregate/pganalyze/go/query.sql.go | 22 +++ .../func_aggregate/{ => pganalyze}/query.sql | 0 .../func_aggregate/{ => pganalyze}/schema.sql | 0 .../func_aggregate/{ => pganalyze}/sqlc.json | 0 .../func_aggregate/postgresql/exec.json | 3 + .../postgresql}/go/db.go | 0 .../postgresql}/go/models.go | 7 +- .../{ => postgresql}/go/query.sql.go | 0 .../func_aggregate/postgresql/query.sql | 3 + .../func_aggregate/postgresql/schema.sql | 7 + .../func_aggregate/postgresql/sqlc.json | 11 ++ .../postgresql/pgx/v4/go/query.sql.go | 4 +- .../postgresql/pgx/v4/schema.sql | 1 + .../postgresql/pgx/v5/go/query.sql.go | 4 +- .../postgresql/pgx/v5/schema.sql | 1 + .../postgresql/stdlib/go/query.sql.go | 4 +- .../postgresql/stdlib/schema.sql | 1 + .../func_match_types/postgresql/go/models.go | 2 +- .../func_match_types/postgresql/schema.sql | 8 +- .../postgresql/pgx/v4/go/query.sql.go | 83 -------- .../func_return/postgresql/pgx/v4/query.sql | 13 -- .../func_return/postgresql/pgx/v4/schema.sql | 11 -- .../postgresql/pgx/v5/go/query.sql.go | 82 -------- .../func_return/postgresql/pgx/v5/query.sql | 13 -- .../func_return/postgresql/pgx/v5/schema.sql | 11 -- .../postgresql/stdlib/go/query.sql.go | 89 --------- .../func_return/postgresql/stdlib/query.sql | 13 -- .../func_return/postgresql/stdlib/schema.sql | 11 -- .../postgresql/pganalyze/exec.json | 3 + .../postgresql/pganalyze/go/db.go | 32 ++++ .../postgresql/pganalyze/go/models.go | 7 + .../postgresql/pganalyze/go/query.sql.go | 23 +++ .../postgresql/pganalyze/query.sql | 2 + .../postgresql/pganalyze/schema.sql | 0 .../postgresql/pganalyze}/sqlc.json | 0 .../postgresql/pgx/v5/exec.json | 3 + .../postgresql/pgx/v5/go/db.go | 32 ++++ .../postgresql/pgx/v5/go/models.go | 7 + .../postgresql/pgx/v5/go/query.sql.go | 24 +++ .../postgresql/pgx/v5/query.sql | 2 + .../postgresql/pgx/v5/schema.sql | 0 .../postgresql/pgx/v5/sqlc.json | 13 ++ .../postgresql/stdlib/exec.json | 3 + .../postgresql/stdlib/go/db.go | 31 +++ .../postgresql/stdlib/go/models.go | 7 + .../postgresql/stdlib/go/query.sql.go | 24 +++ .../postgresql/stdlib/query.sql | 2 + .../postgresql/stdlib/schema.sql | 0 .../postgresql/stdlib/sqlc.json | 0 .../postgresql/pgx/v4/go/db.go | 0 .../postgresql/pgx/v4/go/models.go | 7 + .../postgresql/pgx/v4/go/query.sql.go | 41 ++++ .../postgresql/pgx/v4/query.sql | 4 + .../postgresql/pgx/v4/schema.sql | 0 .../postgresql/pgx/v4/sqlc.json | 0 .../postgresql/pgx/v5/go/db.go | 32 ++++ .../postgresql/pgx/v5/go/models.go | 7 + .../postgresql/pgx/v5/go/query.sql.go | 41 ++++ .../postgresql/pgx/v5/query.sql | 4 + .../postgresql/pgx/v5/schema.sql | 0 .../postgresql/pgx/v5/sqlc.json | 13 ++ .../postgresql/stdlib/go/db.go | 31 +++ .../postgresql/stdlib/go/models.go | 7 + .../postgresql/stdlib/go/query.sql.go | 44 +++++ .../postgresql/stdlib/query.sql | 4 + .../postgresql/stdlib/schema.sql | 0 .../postgresql/stdlib/sqlc.json | 12 ++ .../postgresql/stdlib/go/query.sql.go | 20 +- .../func_variadic/postgresql/stdlib/query.sql | 2 +- .../postgresql/pgx/v4/query.sql | 4 +- .../postgresql/pgx/v4/schema.sql | 1 + .../postgresql/pgx/v4/sqlc.json | 2 +- .../postgresql/pgx/v4/stderr.txt | 5 +- .../postgresql/pgx/v5/query.sql | 4 +- .../postgresql/pgx/v5/schema.sql | 1 + .../postgresql/pgx/v5/sqlc.json | 2 +- .../postgresql/pgx/v5/stderr.txt | 5 +- .../postgresql/stdlib/query.sql | 4 +- .../postgresql/stdlib/schema.sql | 1 + .../postgresql/stdlib/sqlc.json | 2 +- .../postgresql/stdlib/stderr.txt | 5 +- .../testdata/insert_select_param/issue.md | 1 + .../postgresql/pgx/exec.json | 3 + .../postgresql/pgx/go/db.go | 32 ++++ .../postgresql/pgx/go/models.go | 15 ++ .../postgresql/pgx/go/query.sql.go | 29 +++ .../postgresql/pgx/query.sql | 5 + .../postgresql/pgx/schema.sql | 5 + .../postgresql/pgx/sqlc.yaml | 10 + .../testdata/insert_values_only/issue.md | 1 + .../postgresql/pgx/exec.json | 3 + .../postgresql/pgx/go/db.go | 32 ++++ .../postgresql/pgx/go/models.go | 12 ++ .../postgresql/pgx/go/query.sql.go | 26 +++ .../postgresql/pgx/query.sql | 2 + .../postgresql/pgx/schema.sql | 6 + .../postgresql/pgx/sqlc.yaml | 10 + .../testdata/interval/pgx/v4/exec.json | 3 + .../testdata/interval/pgx/v5/exec.json | 3 + .../testdata/interval/stdlib/exec.json | 3 + .../invalid_func_args/pgx/v4/schema.sql | 0 .../invalid_func_args/pgx/v4/sqlc.json | 2 +- .../invalid_func_args/pgx/v4/stderr.txt | 3 + .../invalid_func_args/pgx/v5/schema.sql | 0 .../invalid_func_args/pgx/v5/sqlc.json | 2 +- .../invalid_func_args/pgx/v5/stderr.txt | 3 + .../invalid_func_args/stdlib/schema.sql | 0 .../invalid_func_args/stdlib/sqlc.json | 2 +- .../invalid_func_args/stdlib/stderr.txt | 3 + .../postgresql/query.sql | 8 +- .../postgresql/schema.sql | 5 + .../postgresql/sqlc.json | 2 +- .../postgresql/stderr.txt | 5 +- .../invalid_insert_unknown_column/issue.md | 1 + .../postgresql/pgx/db/db.go | 32 ++++ .../postgresql/pgx/db/models.go | 15 ++ .../postgresql/pgx/db/query.sql.go | 33 ++++ .../postgresql/pgx/exec.json | 3 + .../postgresql/pgx/query.sql | 7 + .../postgresql/pgx/schema.sql | 5 + .../postgresql/pgx/sqlc.json | 19 ++ .../postgresql/pgx/stderr.txt | 2 + .../testdata/invalid_params/pgx/v4/query.sql | 4 +- .../testdata/invalid_params/pgx/v4/schema.sql | 1 + .../testdata/invalid_params/pgx/v4/sqlc.json | 2 +- .../testdata/invalid_params/pgx/v4/stderr.txt | 14 +- .../testdata/invalid_params/pgx/v5/query.sql | 4 +- .../testdata/invalid_params/pgx/v5/schema.sql | 1 + .../testdata/invalid_params/pgx/v5/sqlc.json | 2 +- .../testdata/invalid_params/pgx/v5/stderr.txt | 14 +- .../testdata/invalid_params/stdlib/query.sql | 4 +- .../testdata/invalid_params/stdlib/schema.sql | 1 + .../testdata/invalid_params/stdlib/sqlc.json | 2 +- .../testdata/invalid_params/stdlib/stderr.txt | 14 +- .../invalid_params_type_mismatch/issue.md | 1 + .../postgresql/pgx/exec.json | 3 + .../postgresql/pgx/query.sql | 4 + .../postgresql/pgx/schema.sql | 5 + .../postgresql/pgx/sqlc.json | 13 ++ .../postgresql/pgx/stderr.txt | 2 + .../invalid_queries_bar/pgx/v4/query.sql | 4 +- .../invalid_queries_bar/pgx/v4/schema.sql | 1 + .../invalid_queries_bar/pgx/v4/sqlc.json | 2 +- .../invalid_queries_bar/pgx/v4/stderr.txt | 8 +- .../invalid_queries_bar/pgx/v5/query.sql | 6 +- .../invalid_queries_bar/pgx/v5/schema.sql | 1 + .../invalid_queries_bar/pgx/v5/sqlc.json | 2 +- .../invalid_queries_bar/pgx/v5/stderr.txt | 8 +- .../invalid_queries_bar/stdlib/query.sql | 6 +- .../invalid_queries_bar/stdlib/schema.sql | 1 + .../invalid_queries_bar/stdlib/sqlc.json | 2 +- .../invalid_queries_bar/stdlib/stderr.txt | 8 +- .../invalid_queries_foo/pgx/v4/query.sql | 2 - .../invalid_queries_foo/pgx/v4/schema.sql | 1 + .../invalid_queries_foo/pgx/v4/sqlc.json | 2 +- .../invalid_queries_foo/pgx/v4/stderr.txt | 12 +- .../invalid_queries_foo/pgx/v5/query.sql | 2 - .../invalid_queries_foo/pgx/v5/schema.sql | 1 + .../invalid_queries_foo/pgx/v5/sqlc.json | 2 +- .../invalid_queries_foo/pgx/v5/stderr.txt | 12 +- .../invalid_queries_foo/stdlib/query.sql | 2 - .../invalid_queries_foo/stdlib/schema.sql | 1 + .../invalid_queries_foo/stdlib/sqlc.json | 2 +- .../invalid_queries_foo/stdlib/stderr.txt | 12 +- .../invalid_table_alias/postgresql/query.sql | 7 - .../invalid_table_alias/postgresql/schema.sql | 6 + .../invalid_table_alias/postgresql/sqlc.json | 2 +- .../invalid_table_alias/postgresql/stderr.txt | 5 +- .../invalid_update_unknown_column/issue.md | 1 + .../postgresql/pgx/exec.json | 3 + .../postgresql/pgx/query.sql | 7 + .../postgresql/pgx/schema.sql | 10 + .../postgresql/pgx/sqlc.yaml | 10 + .../postgresql/pgx/stderr.txt | 2 + .../testdata/join_left/postgresql/exec.json | 3 + .../testdata/join_validate_columns/issue.md | 1 + .../postgresql/pgx/exec.json | 3 + .../postgresql/pgx/query.sql | 2 + .../postgresql/pgx/schema.sql | 10 + .../postgresql/pgx/sqlc.yaml | 10 + .../postgresql/pgx/stderr.txt | 2 + .../testdata/json_param_type/issue.md | 1 + .../json_param_type/postgresql/pgx/exec.json | 3 + .../json_param_type/postgresql/pgx/go/db.go | 32 ++++ .../postgresql/pgx/go/models.go | 12 ++ .../postgresql/pgx/go/query.sql.go | 23 +++ .../json_param_type/postgresql/pgx/query.sql | 2 + .../json_param_type/postgresql/pgx/schema.sql | 4 + .../json_param_type/postgresql/pgx/sqlc.yaml | 10 + .../endtoend/testdata/limit/pgx/v4/exec.json | 3 + .../endtoend/testdata/limit/pgx/v5/exec.json | 3 + .../endtoend/testdata/limit/stdlib/exec.json | 3 + .../missing_semicolon/pgx/v4/query.sql | 2 - .../missing_semicolon/pgx/v4/schema.sql | 1 + .../missing_semicolon/pgx/v4/sqlc.json | 2 +- .../missing_semicolon/pgx/v4/stderr.txt | 2 +- .../missing_semicolon/pgx/v5/query.sql | 2 - .../missing_semicolon/pgx/v5/schema.sql | 1 + .../missing_semicolon/pgx/v5/sqlc.json | 2 +- .../missing_semicolon/pgx/v5/stderr.txt | 2 +- .../missing_semicolon/stdlib/query.sql | 2 - .../missing_semicolon/stdlib/schema.sql | 1 + .../missing_semicolon/stdlib/sqlc.json | 2 +- .../missing_semicolon/stdlib/stderr.txt | 2 +- .../mix_param_types/postgresql/exec.json | 3 + .../endtoend/testdata/nested_select/issue.md | 1 + .../nested_select/postgresql/pgx/exec.json | 3 + .../nested_select/postgresql/pgx/go/db.go | 32 ++++ .../nested_select/postgresql/pgx/go/models.go | 13 ++ .../postgresql/pgx/go/query.sql.go | 42 +++++ .../nested_select/postgresql/pgx/query.sql | 11 ++ .../nested_select/postgresql/pgx/schema.sql | 5 + .../nested_select/postgresql/pgx/sqlc.yaml | 14 ++ .../endtoend/testdata/null_if_type/issue.md | 1 + .../postgresql/pganalyzer/db/db.go | 31 +++ .../postgresql/pganalyzer/db/models.go | 11 ++ .../postgresql/pganalyzer/db/query.sql.go | 24 +++ .../postgresql/pganalyzer/exec.json | 3 + .../postgresql/pganalyzer/query.sql | 5 + .../postgresql/pganalyzer/schema.sql | 3 + .../postgresql/pganalyzer/sqlc.json | 12 ++ .../null_if_type/postgresql/stdlib/db/db.go | 31 +++ .../postgresql/stdlib/db/models.go | 11 ++ .../postgresql/stdlib/db/query.sql.go | 24 +++ .../null_if_type/postgresql/stdlib/exec.json | 3 + .../null_if_type/postgresql/stdlib/query.sql | 5 + .../null_if_type/postgresql/stdlib/schema.sql | 3 + .../null_if_type/postgresql/stdlib/sqlc.json | 12 ++ .../postgresql/pgx/v4/go/query.sql.go | 21 +-- .../postgresql/pgx/v4/query.sql | 8 +- .../postgresql/pgx/v5/go/query.sql.go | 22 +-- .../postgresql/pgx/v5/query.sql | 8 +- .../postgresql/stdlib/go/query.sql.go | 21 +-- .../postgresql/stdlib/query.sql | 8 +- .../order_by_binds/pganalyze/exec.json | 3 + .../order_by_binds/pganalyze/go/db.go | 31 +++ .../pganalyze}/go/models.go | 7 +- .../order_by_binds/pganalyze/go/query.sql.go | 74 ++++++++ .../order_by_binds/pganalyze/query.sql | 9 + .../order_by_binds/pganalyze/schema.sql | 6 + .../order_by_binds/pganalyze/sqlc.json | 12 ++ .../order_by_binds/postgresql/exec.json | 3 + .../mysql/query.sql | 8 - .../mysql/sqlc.yaml | 7 - .../mysql/stderr.txt | 2 - .../postgresql/query.sql | 5 - .../postgresql/schema.sql | 5 + .../postgresql/sqlc.yaml | 2 +- .../postgresql/stderr.txt | 5 +- .../sqlite/query.sql | 8 - .../sqlite/sqlc.yaml | 7 - .../sqlite/stderr.txt | 2 - .../postgresql/pgx/v4/exec.json | 3 + .../postgresql/pgx/v5/exec.json | 3 + .../postgresql/stdlib/exec.json | 3 + .../postgresql/exec.json | 3 + internal/endtoend/testdata/pg_dump/exec.json | 3 + .../postgresql/pgx/v4/exec.json | 3 + .../postgresql/pgx/v4/go/query.sql.go | 10 +- .../postgresql/pgx/v4/query.sql | 2 +- .../postgresql/pgx/v5/exec.json | 3 + .../postgresql/pgx/v5/go/query.sql.go | 8 +- .../postgresql/pgx/v5/query.sql | 2 +- .../postgresql/stdlib/exec.json | 3 + .../postgresql/stdlib/go/query.sql.go | 8 +- .../postgresql/stdlib/query.sql | 2 +- .../postgresql/pgx/v5/exec.json | 3 + .../process_plugin_sqlc_gen_json/exec.json | 2 +- .../-1/python_postgresql/query.sql | 2 - .../-1/python_postgresql/schema.sql | 1 + .../-1/python_postgresql/sqlc.json | 2 +- .../postgresql/schema.sql | 0 .../postgresql/sqlc.json | 2 +- .../postgresql/stderr.txt | 6 + .../select_limit/postgresql/pgx/v4/exec.json | 3 + .../select_limit/postgresql/pgx/v5/exec.json | 3 + .../select_limit/postgresql/stdlib/exec.json | 3 + .../select_union/postgres/pgx/v4/exec.json | 3 + .../select_union/postgres/pgx/v5/exec.json | 3 + .../select_union/postgres/stdlib/exec.json | 3 + .../postgresql/pgx/v4/go/query.sql.go | 2 +- .../postgresql/pgx/v4/query.sql | 2 +- .../postgresql/pgx/v5/go/query.sql.go | 2 +- .../postgresql/pgx/v5/query.sql | 2 +- .../postgresql/stdlib/go/query.sql.go | 2 +- .../postgresql/stdlib/query.sql | 2 +- .../sqlc_arg_invalid/mysql/stderr.txt | 4 +- .../sqlc_arg_invalid/postgresql/query.sql | 5 - .../sqlc_arg_invalid/postgresql/schema.sql | 4 + .../sqlc_arg_invalid/postgresql/sqlc.json | 2 +- .../sqlc_arg_invalid/postgresql/stderr.txt | 11 +- .../sqlc_arg_invalid/sqlite/stderr.txt | 4 +- .../postgresql/schema.sql | 0 .../postgresql/sqlc.json | 2 +- .../postgresql/stderr.txt | 3 + internal/endtoend/testdata/sum_type/issue.md | 1 + .../sum_type/postgresql/pgx/exec.json | 3 + .../testdata/sum_type/postgresql/pgx/go/db.go | 32 ++++ .../sum_type/postgresql/pgx/go/models.go | 15 ++ .../sum_type/postgresql/pgx/go/query.sql.go | 23 +++ .../sum_type/postgresql/pgx/query.sql | 2 + .../sum_type/postgresql/pgx/schema.sql | 5 + .../sum_type/postgresql/pgx/sqlc.yaml | 10 + .../postgresql/pgx/v4/go/models.go | 6 +- .../postgresql/pgx/v4/go/query.sql.go | 22 +-- .../postgresql/pgx/v4/query.sql | 15 +- .../postgresql/pgx/v4/schema.sql | 8 +- .../postgresql/pgx/v5/go/models.go | 2 +- .../postgresql/pgx/v5/go/query.sql.go | 20 +- .../postgresql/pgx/v5/query.sql | 15 +- .../postgresql/pgx/v5/schema.sql | 8 +- .../postgresql/stdlib/go/models.go | 6 +- .../postgresql/stdlib/go/query.sql.go | 21 +-- .../postgresql/stdlib/query.sql | 15 +- .../postgresql/stdlib/schema.sql | 8 +- .../testdata/unknown_func/pganalyze/exec.json | 3 + .../testdata/unknown_func/pganalyze/query.sql | 2 + .../unknown_func/pganalyze/schema.sql | 1 + .../testdata/unknown_func/pganalyze/sqlc.json | 13 ++ .../unknown_func/pganalyze/stderr.txt | 2 + .../testdata/unknown_func/pgx/v4/exec.json | 3 + .../testdata/unknown_func/pgx/v5/exec.json | 3 + .../testdata/unknown_func/stdlib/exec.json | 3 + .../endtoend/testdata/unnest_star/issue.md | 1 + .../unnest_star/postgresql/pgx/exec.json | 3 + .../unnest_star/postgresql/pgx/go/db.go | 32 ++++ .../unnest_star/postgresql/pgx/go/models.go | 21 +++ .../postgresql/pgx/go/query.sql.go | 57 ++++++ .../unnest_star/postgresql/pgx/query.sql | 12 ++ .../unnest_star/postgresql/pgx/schema.sql | 13 ++ .../unnest_star/postgresql/pgx/sqlc.yaml | 10 + .../testdata/update_set_on_conflict/issue.md | 1 + .../postgresql/pgx/exec.json | 3 + .../postgresql/pgx/query.sql | 4 + .../postgresql/pgx/schema.sql | 4 + .../postgresql/pgx/sqlc.yaml | 10 + .../postgresql/pgx/stderr.txt | 2 + .../pganalyzer/exec.json | 3 + .../pganalyzer/go/db.go | 31 +++ .../pganalyzer/go/models.go | 36 ++++ .../pganalyzer/go/query.sql.go | 105 +++++++++++ .../pganalyzer/query.sql | 14 ++ .../pganalyzer/schema.sql | 26 +++ .../pganalyzer/sqlc.json | 12 ++ .../postgresql/exec.json | 3 + .../postgresql/go/query.sql.go | 6 +- .../postgresql/query.sql | 8 +- internal/endtoend/vet_test.go | 6 +- 420 files changed, 3542 insertions(+), 786 deletions(-) create mode 100644 internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/exec.json rename internal/endtoend/testdata/{func_return/postgresql/pgx/v5 => coalesce_as/postgresql/pganalyze}/go/db.go (100%) rename internal/endtoend/testdata/{func_return/postgresql/pgx/v5 => coalesce_as/postgresql/pganalyze}/go/models.go (69%) create mode 100644 internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/go/query.sql.go create mode 100644 internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/query.sql create mode 100644 internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/schema.sql create mode 100644 internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/sqlc.json create mode 100644 internal/endtoend/testdata/coalesce_as/postgresql/pgx/v4/exec.json create mode 100644 internal/endtoend/testdata/coalesce_as/postgresql/pgx/v5/exec.json create mode 100644 internal/endtoend/testdata/coalesce_as/postgresql/stdlib/exec.json create mode 100644 internal/endtoend/testdata/codegen_json/exec.json create mode 100644 internal/endtoend/testdata/cte_left_join/issue.md create mode 100644 internal/endtoend/testdata/cte_left_join/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/cte_left_join/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/cte_left_join/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/cte_left_join/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/cte_multiple_alias/issue.md create mode 100644 internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/cte_recursive_employees/issue.md create mode 100644 internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/cte_recursive_star/issue.md create mode 100644 internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/cte_select_one/issue.md create mode 100644 internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/cte_select_one/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/cte_select_one/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/cte_select_one/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/exec.json create mode 100644 internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/db.go create mode 100644 internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/models.go create mode 100644 internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/query.sql.go create mode 100644 internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/query.sql create mode 100644 internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/schema.sql create mode 100644 internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/sqlc.json create mode 100644 internal/endtoend/testdata/func_aggregate/pganalyze/exec.json rename internal/endtoend/testdata/func_aggregate/{ => pganalyze}/go/db.go (100%) rename internal/endtoend/testdata/func_aggregate/{ => pganalyze}/go/models.go (100%) create mode 100644 internal/endtoend/testdata/func_aggregate/pganalyze/go/query.sql.go rename internal/endtoend/testdata/func_aggregate/{ => pganalyze}/query.sql (100%) rename internal/endtoend/testdata/func_aggregate/{ => pganalyze}/schema.sql (100%) rename internal/endtoend/testdata/func_aggregate/{ => pganalyze}/sqlc.json (100%) create mode 100644 internal/endtoend/testdata/func_aggregate/postgresql/exec.json rename internal/endtoend/testdata/{func_return/postgresql/stdlib => func_aggregate/postgresql}/go/db.go (100%) rename internal/endtoend/testdata/{func_return/postgresql/pgx/v4 => func_aggregate/postgresql}/go/models.go (64%) rename internal/endtoend/testdata/func_aggregate/{ => postgresql}/go/query.sql.go (100%) create mode 100644 internal/endtoend/testdata/func_aggregate/postgresql/query.sql create mode 100644 internal/endtoend/testdata/func_aggregate/postgresql/schema.sql create mode 100644 internal/endtoend/testdata/func_aggregate/postgresql/sqlc.json delete mode 100644 internal/endtoend/testdata/func_return/postgresql/pgx/v4/go/query.sql.go delete mode 100644 internal/endtoend/testdata/func_return/postgresql/pgx/v4/query.sql delete mode 100644 internal/endtoend/testdata/func_return/postgresql/pgx/v4/schema.sql delete mode 100644 internal/endtoend/testdata/func_return/postgresql/pgx/v5/go/query.sql.go delete mode 100644 internal/endtoend/testdata/func_return/postgresql/pgx/v5/query.sql delete mode 100644 internal/endtoend/testdata/func_return/postgresql/pgx/v5/schema.sql delete mode 100644 internal/endtoend/testdata/func_return/postgresql/stdlib/go/query.sql.go delete mode 100644 internal/endtoend/testdata/func_return/postgresql/stdlib/query.sql delete mode 100644 internal/endtoend/testdata/func_return/postgresql/stdlib/schema.sql create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pganalyze/exec.json create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/db.go create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/models.go create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/query.sql.go create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pganalyze/query.sql create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pganalyze/schema.sql rename internal/endtoend/testdata/{func_return/postgresql/pgx/v5 => func_return_date/postgresql/pganalyze}/sqlc.json (100%) create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/exec.json create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/db.go create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/models.go create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/query.sql.go create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/query.sql create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/schema.sql create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/sqlc.json create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/stdlib/exec.json create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/db.go create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/models.go create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/query.sql.go create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/stdlib/query.sql create mode 100644 internal/endtoend/testdata/func_return_date/postgresql/stdlib/schema.sql rename internal/endtoend/testdata/{func_return => func_return_date}/postgresql/stdlib/sqlc.json (100%) rename internal/endtoend/testdata/{func_return => func_return_series}/postgresql/pgx/v4/go/db.go (100%) create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/go/models.go create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/go/query.sql.go create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/query.sql create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/schema.sql rename internal/endtoend/testdata/{func_return => func_return_series}/postgresql/pgx/v4/sqlc.json (100%) create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/db.go create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/models.go create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/query.sql.go create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/query.sql create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/schema.sql create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/sqlc.json create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/db.go create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/models.go create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/query.sql.go create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/stdlib/query.sql create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/stdlib/schema.sql create mode 100644 internal/endtoend/testdata/func_return_series/postgresql/stdlib/sqlc.json create mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/schema.sql create mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/schema.sql create mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/schema.sql create mode 100644 internal/endtoend/testdata/insert_select_param/issue.md create mode 100644 internal/endtoend/testdata/insert_select_param/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/insert_select_param/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/insert_select_param/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/insert_select_param/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/insert_values_only/issue.md create mode 100644 internal/endtoend/testdata/insert_values_only/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/insert_values_only/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/insert_values_only/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/insert_values_only/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/interval/pgx/v4/exec.json create mode 100644 internal/endtoend/testdata/interval/pgx/v5/exec.json create mode 100644 internal/endtoend/testdata/interval/stdlib/exec.json create mode 100644 internal/endtoend/testdata/invalid_func_args/pgx/v4/schema.sql create mode 100644 internal/endtoend/testdata/invalid_func_args/pgx/v5/schema.sql create mode 100644 internal/endtoend/testdata/invalid_func_args/stdlib/schema.sql create mode 100644 internal/endtoend/testdata/invalid_group_by_reference/postgresql/schema.sql create mode 100644 internal/endtoend/testdata/invalid_insert_unknown_column/issue.md create mode 100644 internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/db.go create mode 100644 internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/models.go create mode 100644 internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/query.sql.go create mode 100644 internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/sqlc.json create mode 100644 internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/stderr.txt create mode 100644 internal/endtoend/testdata/invalid_params/pgx/v4/schema.sql create mode 100644 internal/endtoend/testdata/invalid_params/pgx/v5/schema.sql create mode 100644 internal/endtoend/testdata/invalid_params/stdlib/schema.sql create mode 100644 internal/endtoend/testdata/invalid_params_type_mismatch/issue.md create mode 100644 internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/sqlc.json create mode 100644 internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/stderr.txt create mode 100644 internal/endtoend/testdata/invalid_queries_bar/pgx/v4/schema.sql create mode 100644 internal/endtoend/testdata/invalid_queries_bar/pgx/v5/schema.sql create mode 100644 internal/endtoend/testdata/invalid_queries_bar/stdlib/schema.sql create mode 100644 internal/endtoend/testdata/invalid_queries_foo/pgx/v4/schema.sql create mode 100644 internal/endtoend/testdata/invalid_queries_foo/pgx/v5/schema.sql create mode 100644 internal/endtoend/testdata/invalid_queries_foo/stdlib/schema.sql create mode 100644 internal/endtoend/testdata/invalid_table_alias/postgresql/schema.sql create mode 100644 internal/endtoend/testdata/invalid_update_unknown_column/issue.md create mode 100644 internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/stderr.txt create mode 100644 internal/endtoend/testdata/join_left/postgresql/exec.json create mode 100644 internal/endtoend/testdata/join_validate_columns/issue.md create mode 100644 internal/endtoend/testdata/join_validate_columns/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/join_validate_columns/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/join_validate_columns/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/join_validate_columns/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/join_validate_columns/postgresql/pgx/stderr.txt create mode 100644 internal/endtoend/testdata/json_param_type/issue.md create mode 100644 internal/endtoend/testdata/json_param_type/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/json_param_type/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/json_param_type/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/json_param_type/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/json_param_type/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/json_param_type/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/json_param_type/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/limit/pgx/v4/exec.json create mode 100644 internal/endtoend/testdata/limit/pgx/v5/exec.json create mode 100644 internal/endtoend/testdata/limit/stdlib/exec.json create mode 100644 internal/endtoend/testdata/missing_semicolon/pgx/v4/schema.sql create mode 100644 internal/endtoend/testdata/missing_semicolon/pgx/v5/schema.sql create mode 100644 internal/endtoend/testdata/missing_semicolon/stdlib/schema.sql create mode 100644 internal/endtoend/testdata/mix_param_types/postgresql/exec.json create mode 100644 internal/endtoend/testdata/nested_select/issue.md create mode 100644 internal/endtoend/testdata/nested_select/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/nested_select/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/nested_select/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/nested_select/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/nested_select/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/nested_select/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/nested_select/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/null_if_type/issue.md create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/db.go create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/models.go create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/query.sql.go create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/exec.json create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/query.sql create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/schema.sql create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/sqlc.json create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/db.go create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/models.go create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/query.sql.go create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/stdlib/exec.json create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/stdlib/query.sql create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/stdlib/schema.sql create mode 100644 internal/endtoend/testdata/null_if_type/postgresql/stdlib/sqlc.json create mode 100644 internal/endtoend/testdata/order_by_binds/pganalyze/exec.json create mode 100644 internal/endtoend/testdata/order_by_binds/pganalyze/go/db.go rename internal/endtoend/testdata/{func_return/postgresql/stdlib => order_by_binds/pganalyze}/go/models.go (64%) create mode 100644 internal/endtoend/testdata/order_by_binds/pganalyze/go/query.sql.go create mode 100644 internal/endtoend/testdata/order_by_binds/pganalyze/query.sql create mode 100644 internal/endtoend/testdata/order_by_binds/pganalyze/schema.sql create mode 100644 internal/endtoend/testdata/order_by_binds/pganalyze/sqlc.json create mode 100644 internal/endtoend/testdata/order_by_binds/postgresql/exec.json delete mode 100644 internal/endtoend/testdata/order_by_non_existing_column/mysql/query.sql delete mode 100644 internal/endtoend/testdata/order_by_non_existing_column/mysql/sqlc.yaml delete mode 100644 internal/endtoend/testdata/order_by_non_existing_column/mysql/stderr.txt create mode 100644 internal/endtoend/testdata/order_by_non_existing_column/postgresql/schema.sql delete mode 100644 internal/endtoend/testdata/order_by_non_existing_column/sqlite/query.sql delete mode 100644 internal/endtoend/testdata/order_by_non_existing_column/sqlite/sqlc.yaml delete mode 100644 internal/endtoend/testdata/order_by_non_existing_column/sqlite/stderr.txt create mode 100644 internal/endtoend/testdata/params_location/postgresql/pgx/v4/exec.json create mode 100644 internal/endtoend/testdata/params_location/postgresql/pgx/v5/exec.json create mode 100644 internal/endtoend/testdata/params_location/postgresql/stdlib/exec.json create mode 100644 internal/endtoend/testdata/params_placeholder_in_left_expr/postgresql/exec.json create mode 100644 internal/endtoend/testdata/pg_dump/exec.json create mode 100644 internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/exec.json create mode 100644 internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/exec.json create mode 100644 internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/exec.json create mode 100644 internal/endtoend/testdata/pointer_type_import/postgresql/pgx/v5/exec.json create mode 100644 internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/schema.sql create mode 100644 internal/endtoend/testdata/relation_does_not_exist/postgresql/schema.sql create mode 100644 internal/endtoend/testdata/select_limit/postgresql/pgx/v4/exec.json create mode 100644 internal/endtoend/testdata/select_limit/postgresql/pgx/v5/exec.json create mode 100644 internal/endtoend/testdata/select_limit/postgresql/stdlib/exec.json create mode 100644 internal/endtoend/testdata/select_union/postgres/pgx/v4/exec.json create mode 100644 internal/endtoend/testdata/select_union/postgres/pgx/v5/exec.json create mode 100644 internal/endtoend/testdata/select_union/postgres/stdlib/exec.json create mode 100644 internal/endtoend/testdata/sqlc_arg_invalid/postgresql/schema.sql create mode 100644 internal/endtoend/testdata/strict_function_checks/postgresql/schema.sql create mode 100644 internal/endtoend/testdata/sum_type/issue.md create mode 100644 internal/endtoend/testdata/sum_type/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/sum_type/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/sum_type/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/sum_type/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/sum_type/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/sum_type/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/sum_type/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/unknown_func/pganalyze/exec.json create mode 100644 internal/endtoend/testdata/unknown_func/pganalyze/query.sql create mode 100644 internal/endtoend/testdata/unknown_func/pganalyze/schema.sql create mode 100644 internal/endtoend/testdata/unknown_func/pganalyze/sqlc.json create mode 100644 internal/endtoend/testdata/unknown_func/pganalyze/stderr.txt create mode 100644 internal/endtoend/testdata/unknown_func/pgx/v4/exec.json create mode 100644 internal/endtoend/testdata/unknown_func/pgx/v5/exec.json create mode 100644 internal/endtoend/testdata/unknown_func/stdlib/exec.json create mode 100644 internal/endtoend/testdata/unnest_star/issue.md create mode 100644 internal/endtoend/testdata/unnest_star/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/unnest_star/postgresql/pgx/go/db.go create mode 100644 internal/endtoend/testdata/unnest_star/postgresql/pgx/go/models.go create mode 100644 internal/endtoend/testdata/unnest_star/postgresql/pgx/go/query.sql.go create mode 100644 internal/endtoend/testdata/unnest_star/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/unnest_star/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/unnest_star/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/update_set_on_conflict/issue.md create mode 100644 internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/exec.json create mode 100644 internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/query.sql create mode 100644 internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/schema.sql create mode 100644 internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/sqlc.yaml create mode 100644 internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/stderr.txt create mode 100644 internal/endtoend/testdata/valid_group_by_reference/pganalyzer/exec.json create mode 100644 internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/db.go create mode 100644 internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/models.go create mode 100644 internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/query.sql.go create mode 100644 internal/endtoend/testdata/valid_group_by_reference/pganalyzer/query.sql create mode 100644 internal/endtoend/testdata/valid_group_by_reference/pganalyzer/schema.sql create mode 100644 internal/endtoend/testdata/valid_group_by_reference/pganalyzer/sqlc.json create mode 100644 internal/endtoend/testdata/valid_group_by_reference/postgresql/exec.json diff --git a/examples/authors/sqlc.yaml b/examples/authors/sqlc.yaml index 8270782edd..f3b5c6586c 100644 --- a/examples/authors/sqlc.yaml +++ b/examples/authors/sqlc.yaml @@ -6,6 +6,7 @@ sql: queries: postgresql/query.sql engine: postgresql database: + analyzer: false managed: true rules: - sqlc/db-prepare diff --git a/examples/booktest/sqlc.json b/examples/booktest/sqlc.json index 72cd08936d..af2722bdd0 100644 --- a/examples/booktest/sqlc.json +++ b/examples/booktest/sqlc.json @@ -11,7 +11,8 @@ "queries": "postgresql/query.sql", "engine": "postgresql", "database": { - "managed": true + "managed": true, + "analyzer": false }, "rules": [ "sqlc/db-prepare" diff --git a/examples/jets/sqlc.json b/examples/jets/sqlc.json index 85a35a4f7a..441ad0eb6c 100644 --- a/examples/jets/sqlc.json +++ b/examples/jets/sqlc.json @@ -11,6 +11,7 @@ "queries": "postgresql/query-building.sql", "engine": "postgresql", "database": { + "analyzer": false, "managed": true }, "rules": [ diff --git a/examples/ondeck/sqlc.json b/examples/ondeck/sqlc.json index c9290db568..9fceb5e3ad 100644 --- a/examples/ondeck/sqlc.json +++ b/examples/ondeck/sqlc.json @@ -11,7 +11,8 @@ "queries": "postgresql/query", "engine": "postgresql", "database": { - "managed": true + "managed": true, + "analyzer": false }, "rules": [ "sqlc/db-prepare" diff --git a/internal/endtoend/endtoend_test.go b/internal/endtoend/endtoend_test.go index e91e9f9c56..3e4c7cbc1f 100644 --- a/internal/endtoend/endtoend_test.go +++ b/internal/endtoend/endtoend_test.go @@ -12,13 +12,15 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "golang.org/x/exp/slices" "github.com/sqlc-dev/sqlc/internal/cmd" + "github.com/sqlc-dev/sqlc/internal/config" "github.com/sqlc-dev/sqlc/internal/opts" ) func TestExamples(t *testing.T) { - t.Parallel() + // t.Parallel() ctx := context.Background() examples, err := filepath.Abs(filepath.Join("..", "..", "examples")) @@ -37,10 +39,14 @@ func TestExamples(t *testing.T) { } tc := replay.Name() t.Run(tc, func(t *testing.T) { - t.Parallel() + // t.Parallel() path := filepath.Join(examples, tc) var stderr bytes.Buffer - output, err := cmd.Generate(ctx, cmd.Env{}, path, "", &stderr) + opts := &cmd.Options{ + Env: cmd.Env{}, + Stderr: &stderr, + } + output, err := cmd.Generate(ctx, path, "", opts) if err != nil { t.Fatalf("sqlc generate failed: %s", stderr.String()) } @@ -68,18 +74,27 @@ func BenchmarkExamples(b *testing.B) { path := filepath.Join(examples, tc) for i := 0; i < b.N; i++ { var stderr bytes.Buffer - cmd.Generate(ctx, cmd.Env{}, path, "", &stderr) + opts := &cmd.Options{ + Env: cmd.Env{}, + Stderr: &stderr, + } + cmd.Generate(ctx, path, "", opts) } }) } } +type textContext struct { + Mutate func(*config.Config) + Enabled func() bool +} + func TestReplay(t *testing.T) { // Ensure that this environment variable is always set to true when running // end-to-end tests os.Setenv("SQLC_DUMMY_VALUE", "true") - t.Parallel() + // t.Parallel() ctx := context.Background() var dirs []string err := filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error { @@ -95,52 +110,103 @@ func TestReplay(t *testing.T) { if err != nil { t.Fatal(err) } + + contexts := map[string]textContext{ + "base": { + Mutate: func(c *config.Config) {}, + Enabled: func() bool { return true }, + }, + "managed-db": { + Mutate: func(c *config.Config) { + c.Cloud.Project = "01HAQMMECEYQYKFJN8MP16QC41" // TODO: Read from environment + for i := range c.SQL { + c.SQL[i].Database = &config.Database{ + Managed: true, + } + } + }, + Enabled: func() bool { + if len(os.Getenv("CI")) > 0 { + return false + } + return len(os.Getenv("SQLC_AUTH_TOKEN")) > 0 + }, + }, + } + for _, replay := range dirs { tc := replay - t.Run(tc, func(t *testing.T) { - t.Parallel() + for name, testctx := range contexts { + name := name + testctx := testctx - var stderr bytes.Buffer - var output map[string]string - var err error + if !testctx.Enabled() { + continue + } - path, _ := filepath.Abs(tc) - args := parseExec(t, path) - expected := expectedStderr(t, path) + t.Run(filepath.Join(name, tc), func(t *testing.T) { + t.Parallel() + var stderr bytes.Buffer + var output map[string]string + var err error - if args.Process != "" { - _, err := osexec.LookPath(args.Process) - if err != nil { - t.Skipf("executable not found: %s %s", args.Process, err) + path, _ := filepath.Abs(tc) + args := parseExec(t, path) + + if args.Process != "" { + _, err := osexec.LookPath(args.Process) + if err != nil { + t.Skipf("executable not found: %s %s", args.Process, err) + } } - } - env := cmd.Env{ - Debug: opts.DebugFromString(args.Env["SQLCDEBUG"]), - NoRemote: true, - } - switch args.Command { - case "diff": - err = cmd.Diff(ctx, env, path, "", &stderr) - case "generate": - output, err = cmd.Generate(ctx, env, path, "", &stderr) - if err == nil { - cmpDirectory(t, path, output) + if len(args.Contexts) > 0 { + if !slices.Contains(args.Contexts, name) { + t.Skipf("unsupported context: %s", name) + } } - case "vet": - err = cmd.Vet(ctx, env, path, "", &stderr) - default: - t.Fatalf("unknown command") - } - if len(expected) == 0 && err != nil { - t.Fatalf("sqlc %s failed: %s", args.Command, stderr.String()) - } + expected := expectedStderr(t, path) + opts := cmd.Options{ + Env: cmd.Env{ + Debug: opts.DebugFromString(args.Env["SQLCDEBUG"]), + NoRemote: true, + }, + Stderr: &stderr, + MutateConfig: testctx.Mutate, + } - if diff := cmp.Diff(expected, stderr.String()); diff != "" { - t.Errorf("stderr differed (-want +got):\n%s", diff) - } - }) + switch args.Command { + case "diff": + err = cmd.Diff(ctx, path, "", &opts) + case "generate": + output, err = cmd.Generate(ctx, path, "", &opts) + if err == nil { + cmpDirectory(t, path, output) + } + case "vet": + err = cmd.Vet(ctx, path, "", &opts) + default: + t.Fatalf("unknown command") + } + + if len(expected) == 0 && err != nil { + t.Fatalf("sqlc %s failed: %s", args.Command, stderr.String()) + } + + var diff string + for _, expectedErr := range strings.Split(expected, "---\n") { + diff = cmp.Diff(strings.TrimSpace(expectedErr), strings.TrimSpace(stderr.String())) + if diff == "" { + break + } + } + if diff != "" { + t.Log(stderr.String()) // TODO: Remove + t.Fatalf("stderr differed (-want +got):\n%s", diff) + } + }) + } } } @@ -192,16 +258,13 @@ func cmpDirectory(t *testing.T, dir string, actual map[string]string) { t.Errorf("%s contents differ", dir) for name, contents := range expected { name := name - tn := strings.Replace(name, dir+"/", "", -1) - t.Run(tn, func(t *testing.T) { - if actual[name] == "" { - t.Errorf("%s is empty", name) - return - } - if diff := cmp.Diff(contents, actual[name]); diff != "" { - t.Errorf("%s differed (-want +got):\n%s", name, diff) - } - }) + if actual[name] == "" { + t.Errorf("%s is empty", name) + return + } + if diff := cmp.Diff(contents, actual[name]); diff != "" { + t.Errorf("%s differed (-want +got):\n%s", name, diff) + } } } } @@ -220,9 +283,10 @@ func expectedStderr(t *testing.T, dir string) string { } type exec struct { - Command string `json:"command"` - Process string `json:"process"` - Env map[string]string `json:"env"` + Command string `json:"command"` + Process string `json:"process"` + Contexts []string `json:"contexts"` + Env map[string]string `json:"env"` } func parseExec(t *testing.T, dir string) exec { @@ -266,7 +330,11 @@ func BenchmarkReplay(b *testing.B) { path, _ := filepath.Abs(tc) for i := 0; i < b.N; i++ { var stderr bytes.Buffer - cmd.Generate(ctx, cmd.Env{}, path, "", &stderr) + opts := &cmd.Options{ + Env: cmd.Env{}, + Stderr: &stderr, + } + cmd.Generate(ctx, path, "", opts) } }) } diff --git a/internal/endtoend/testdata/alias/postgresql/stdlib/schema.sql b/internal/endtoend/testdata/alias/postgresql/stdlib/schema.sql index 638370ab15..b7ee888d47 100644 --- a/internal/endtoend/testdata/alias/postgresql/stdlib/schema.sql +++ b/internal/endtoend/testdata/alias/postgresql/stdlib/schema.sql @@ -1,2 +1 @@ -CREATE TABLE bar (id serial not null); - +CREATE TABLE bar (id serial not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/exec.json b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v5/go/db.go b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/go/db.go similarity index 100% rename from internal/endtoend/testdata/func_return/postgresql/pgx/v5/go/db.go rename to internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/go/db.go diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v5/go/models.go b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/go/models.go similarity index 69% rename from internal/endtoend/testdata/func_return/postgresql/pgx/v5/go/models.go rename to internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/go/models.go index 950971b7c2..fcb8c8cb65 100644 --- a/internal/endtoend/testdata/func_return/postgresql/pgx/v5/go/models.go +++ b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/go/models.go @@ -8,7 +8,7 @@ import ( "github.com/jackc/pgx/v5/pgtype" ) -type User struct { - ID pgtype.Int4 - FirstName string +type Foo struct { + Bar pgtype.Text + Baz pgtype.Int8 } diff --git a/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/go/query.sql.go b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/go/query.sql.go new file mode 100644 index 0000000000..b3288a3529 --- /dev/null +++ b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/go/query.sql.go @@ -0,0 +1,43 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const sumBaz = `-- name: SumBaz :many +SELECT bar, coalesce(sum(baz), 0) as quantity +FROM foo +GROUP BY 1 +` + +type SumBazRow struct { + Bar pgtype.Text + Quantity pgtype.Numeric +} + +func (q *Queries) SumBaz(ctx context.Context) ([]SumBazRow, error) { + rows, err := q.db.Query(ctx, sumBaz) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SumBazRow + for rows.Next() { + var i SumBazRow + if err := rows.Scan(&i.Bar, &i.Quantity); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/query.sql b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/query.sql new file mode 100644 index 0000000000..3f51061f8b --- /dev/null +++ b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/query.sql @@ -0,0 +1,4 @@ +-- name: SumBaz :many +SELECT bar, coalesce(sum(baz), 0) as quantity +FROM foo +GROUP BY 1; diff --git a/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/schema.sql b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/schema.sql new file mode 100644 index 0000000000..b7a16c0e28 --- /dev/null +++ b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE foo ( + bar text, + baz bigint +); + diff --git a/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/sqlc.json b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/sqlc.json new file mode 100644 index 0000000000..f5e265377f --- /dev/null +++ b/internal/endtoend/testdata/coalesce_as/postgresql/pganalyze/sqlc.json @@ -0,0 +1,19 @@ +{ + "version": "1", + "cloud": { + "project": "01HAQMMECEYQYKFJN8MP16QC41" + }, + "packages": [ + { + "path": "go", + "engine": "postgresql", + "sql_package": "pgx/v5", + "database": { + "managed": true + }, + "name": "querytest", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/coalesce_as/postgresql/pgx/v4/exec.json b/internal/endtoend/testdata/coalesce_as/postgresql/pgx/v4/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/coalesce_as/postgresql/pgx/v4/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/coalesce_as/postgresql/pgx/v5/exec.json b/internal/endtoend/testdata/coalesce_as/postgresql/pgx/v5/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/coalesce_as/postgresql/pgx/v5/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/coalesce_as/postgresql/stdlib/exec.json b/internal/endtoend/testdata/coalesce_as/postgresql/stdlib/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/coalesce_as/postgresql/stdlib/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/codegen_json/exec.json b/internal/endtoend/testdata/codegen_json/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/codegen_json/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/query.sql.go b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/query.sql.go index 1cda1616eb..e9e1b43553 100644 --- a/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/codegen_struct_field_names/stdlib/go/query.sql.go @@ -10,7 +10,7 @@ import ( ) const test = `-- name: test :one -SELECT id, !!!nobody,_,-would-believe---this-...?!, parent id from bar limit 1 +SELECT id, "!!!nobody,_,-would-believe---this-...?!", "parent id" from bar limit 1 ` func (q *Queries) test(ctx context.Context) (Bar, error) { diff --git a/internal/endtoend/testdata/cte_left_join/issue.md b/internal/endtoend/testdata/cte_left_join/issue.md new file mode 100644 index 0000000000..6027f3c6a8 --- /dev/null +++ b/internal/endtoend/testdata/cte_left_join/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1236 \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_left_join/postgresql/pgx/exec.json b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/db.go b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/models.go b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..0744a36cde --- /dev/null +++ b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/models.go @@ -0,0 +1,21 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type Author struct { + ID int64 + Name string + Bio pgtype.Text +} + +type Fake struct { + ID int64 + Name string + Bio pgtype.Text +} diff --git a/internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..98e03ba495 --- /dev/null +++ b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/go/query.sql.go @@ -0,0 +1,39 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const badQuery = `-- name: BadQuery :exec +WITH + q + AS ( + SELECT + authors.name, authors.bio + FROM + authors + LEFT JOIN fake ON authors.name = fake.name + ) +SELECT + name, bio +FROM + q AS c1 +WHERE c1.name = $1 +` + +type BadQueryRow struct { + Name string + Bio pgtype.Text +} + +func (q *Queries) BadQuery(ctx context.Context, dollar_1 pgtype.Text) error { + _, err := q.db.Exec(ctx, badQuery, dollar_1) + return err +} diff --git a/internal/endtoend/testdata/cte_left_join/postgresql/pgx/query.sql b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/query.sql new file mode 100644 index 0000000000..d201807360 --- /dev/null +++ b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/query.sql @@ -0,0 +1,15 @@ +-- name: BadQuery :exec +WITH + q + AS ( + SELECT + authors.name, authors.bio + FROM + authors + LEFT JOIN fake ON authors.name = fake.name + ) +SELECT + * +FROM + q AS c1 +WHERE c1.name = $1; \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_left_join/postgresql/pgx/schema.sql b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..3d2f5be610 --- /dev/null +++ b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/schema.sql @@ -0,0 +1,11 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); + +CREATE TABLE fake ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_left_join/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/cte_left_join/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_multiple_alias/issue.md b/internal/endtoend/testdata/cte_multiple_alias/issue.md new file mode 100644 index 0000000000..5e4ec565bb --- /dev/null +++ b/internal/endtoend/testdata/cte_multiple_alias/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1237 \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/db.go b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/models.go b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..0744a36cde --- /dev/null +++ b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/models.go @@ -0,0 +1,21 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type Author struct { + ID int64 + Name string + Bio pgtype.Text +} + +type Fake struct { + ID int64 + Name string + Bio pgtype.Text +} diff --git a/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..b6e66ed0be --- /dev/null +++ b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/go/query.sql.go @@ -0,0 +1,48 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const badQuery = `-- name: BadQuery :one +WITH + q + AS ( + SELECT + authors.name, authors.bio + FROM + authors + LEFT JOIN fake ON authors.name = fake.name + ) +SELECT + c1.name, c1.bio, c2.name, c2.bio +FROM + q AS c1, + q as c2 +` + +type BadQueryRow struct { + Name string + Bio pgtype.Text + Name_2 string + Bio_2 pgtype.Text +} + +func (q *Queries) BadQuery(ctx context.Context) (BadQueryRow, error) { + row := q.db.QueryRow(ctx, badQuery) + var i BadQueryRow + err := row.Scan( + &i.Name, + &i.Bio, + &i.Name_2, + &i.Bio_2, + ) + return i, err +} diff --git a/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/query.sql b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/query.sql new file mode 100644 index 0000000000..75d770582f --- /dev/null +++ b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/query.sql @@ -0,0 +1,15 @@ +-- name: BadQuery :one +WITH + q + AS ( + SELECT + authors.name, authors.bio + FROM + authors + LEFT JOIN fake ON authors.name = fake.name + ) +SELECT + * +FROM + q AS c1, + q as c2; \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/schema.sql b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..3d2f5be610 --- /dev/null +++ b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/schema.sql @@ -0,0 +1,11 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); + +CREATE TABLE fake ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/cte_multiple_alias/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_recursive_employees/issue.md b/internal/endtoend/testdata/cte_recursive_employees/issue.md new file mode 100644 index 0000000000..2bc033582e --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_employees/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1219 \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/exec.json b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/db.go b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/models.go b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..5e503d675f --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/models.go @@ -0,0 +1,15 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type Employee struct { + ID int64 + Name string + Manager pgtype.Text +} diff --git a/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..e81ce16986 --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/go/query.sql.go @@ -0,0 +1,56 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const getSubordinates = `-- name: GetSubordinates :many +WITH RECURSIVE subordinates(name, manager) AS ( + SELECT + NULL, $1::TEXT + UNION + SELECT + s.manager, e.name + FROM + subordinates AS s + LEFT OUTER JOIN + employees AS e + ON + e.manager = s.manager + WHERE + s.manager IS NOT NULL +) +SELECT + s.name +FROM + subordinates AS s +WHERE + s.name != $1 +` + +func (q *Queries) GetSubordinates(ctx context.Context, name pgtype.Text) ([]pgtype.Text, error) { + rows, err := q.db.Query(ctx, getSubordinates, name) + if err != nil { + return nil, err + } + defer rows.Close() + var items []pgtype.Text + for rows.Next() { + var name pgtype.Text + if err := rows.Scan(&name); err != nil { + return nil, err + } + items = append(items, name) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/query.sql b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/query.sql new file mode 100644 index 0000000000..00d490a4b9 --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/query.sql @@ -0,0 +1,22 @@ +-- name: GetSubordinates :many +WITH RECURSIVE subordinates(name, manager) AS ( + SELECT + NULL, sqlc.arg(name)::TEXT + UNION + SELECT + s.manager, e.name + FROM + subordinates AS s + LEFT OUTER JOIN + employees AS e + ON + e.manager = s.manager + WHERE + s.manager IS NOT NULL +) +SELECT + s.name +FROM + subordinates AS s +WHERE + s.name != sqlc.arg(name); \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/schema.sql b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..b95effb369 --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE employees ( + id BIGSERIAL PRIMARY KEY, + name text UNIQUE NOT NULL, + manager text REFERENCES employees(name) +); \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_employees/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_recursive_star/issue.md b/internal/endtoend/testdata/cte_recursive_star/issue.md new file mode 100644 index 0000000000..2bc033582e --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_star/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1219 \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/exec.json b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/db.go b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/models.go b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..962822a87a --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/models.go @@ -0,0 +1,27 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type Dict struct { + ID string + AppID string + Code pgtype.Text + ParentCode string + Label string + Value pgtype.Text + Weight int32 + IsDefault bool + IsVirtual bool + Status int16 + CreateAt pgtype.Timestamptz + CreateBy string + UpdateAt pgtype.Timestamptz + UpdateBy pgtype.Text + IsDelete bool +} diff --git a/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..d96dd07b08 --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/go/query.sql.go @@ -0,0 +1,59 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const getDictTree = `-- name: GetDictTree :many +with recursive dictTree(id, code, parent_code, label, value, path, depth) AS ( + select id, code, parent_code, label, value, ARRAY[COALESCE((select id from dict where code=''),'virtual_root'), id], 1 as depth from dict where app_id = '1' and parent_code = '' and is_delete=false + union + select d.id, d.code, d.parent_code, d.label, d.value, t.path || ARRAY[d.id], t.depth+1 as depth from dict d join dictTree t on d.parent_code = t.code and not d.id = ANY(t.path) and d.is_delete=false +) +select id, code, parent_code, label, value, path, depth from dictTree d order by depth, parent_code +` + +type GetDictTreeRow struct { + ID string + Code pgtype.Text + ParentCode string + Label string + Value pgtype.Text + Path pgtype.Text + Depth int32 +} + +func (q *Queries) GetDictTree(ctx context.Context) ([]GetDictTreeRow, error) { + rows, err := q.db.Query(ctx, getDictTree) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetDictTreeRow + for rows.Next() { + var i GetDictTreeRow + if err := rows.Scan( + &i.ID, + &i.Code, + &i.ParentCode, + &i.Label, + &i.Value, + &i.Path, + &i.Depth, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/query.sql b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/query.sql new file mode 100644 index 0000000000..a48253d0ab --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/query.sql @@ -0,0 +1,7 @@ +-- name: GetDictTree :many +with recursive dictTree(id, code, parent_code, label, value, path, depth) AS ( + select id, code, parent_code, label, value, ARRAY[COALESCE((select id from dict where code=''),'virtual_root'), id], 1 as depth from dict where app_id = '1' and parent_code = '' and is_delete=false + union + select d.id, d.code, d.parent_code, d.label, d.value, t.path || ARRAY[d.id], t.depth+1 as depth from dict d join dictTree t on d.parent_code = t.code and not d.id = ANY(t.path) and d.is_delete=false +) +select * from dictTree d order by depth, parent_code; \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/schema.sql b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..c4257ab8bb --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/schema.sql @@ -0,0 +1,17 @@ +create table dict( + id VARCHAR(36) PRIMARY KEY DEFAULT gen_random_uuid(), + app_id VARCHAR(36) NOT NULL, + code VARCHAR(64), + parent_code VARCHAR(64) NOT NULL, + label TEXT NOT NULL DEFAULT '', + value TEXT NULL, + weight INT NOT NULL DEFAULT 0, + is_default BOOLEAN NOT NULL DEFAULT false, + is_virtual BOOLEAN NOT NULL DEFAULT false, + status SMALLINT NOT NULL DEFAULT 1, + create_at TIMESTAMPTZ(0) NOT NULL DEFAULT now(), + create_by VARCHAR(36) NOT NULL DEFAULT '', + update_at TIMESTAMPTZ(0), + update_by VARCHAR(36), + is_delete BOOLEAN NOT NULL DEFAULT false +); diff --git a/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/cte_recursive_star/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_select_one/issue.md b/internal/endtoend/testdata/cte_select_one/issue.md new file mode 100644 index 0000000000..f87f5c14cb --- /dev/null +++ b/internal/endtoend/testdata/cte_select_one/issue.md @@ -0,0 +1 @@ +# TODO \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/db.go b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/models.go b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..172574ab22 --- /dev/null +++ b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/models.go @@ -0,0 +1,7 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () diff --git a/internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..de69b77ccc --- /dev/null +++ b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/go/query.sql.go @@ -0,0 +1,24 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const testRecursive = `-- name: TestRecursive :one +WITH t1 AS ( + select 1 as foo +) +SELECT foo FROM t1 +` + +func (q *Queries) TestRecursive(ctx context.Context) (int32, error) { + row := q.db.QueryRow(ctx, testRecursive) + var foo int32 + err := row.Scan(&foo) + return foo, err +} diff --git a/internal/endtoend/testdata/cte_select_one/postgresql/pgx/query.sql b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/query.sql new file mode 100644 index 0000000000..9f4fdf08de --- /dev/null +++ b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/query.sql @@ -0,0 +1,5 @@ +-- name: TestRecursive :one +WITH t1 AS ( + select 1 as foo +) +SELECT * FROM t1; \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_select_one/postgresql/pgx/schema.sql b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..af3b9497d9 --- /dev/null +++ b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/schema.sql @@ -0,0 +1 @@ +-- TODO \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_select_one/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/cte_select_one/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/exec.json b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/db.go b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/models.go b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/models.go new file mode 100644 index 0000000000..6b81cce5f3 --- /dev/null +++ b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/models.go @@ -0,0 +1,20 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type L struct { + ID int64 + ParentID pgtype.Int4 +} + +type T struct { + ID int64 + LID pgtype.Int4 + F pgtype.Text +} diff --git a/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/query.sql.go b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/query.sql.go new file mode 100644 index 0000000000..2cfc581465 --- /dev/null +++ b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/go/query.sql.go @@ -0,0 +1,164 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const getAll = `-- name: GetAll :many +SELECT id, parent_id FROM L +` + +func (q *Queries) GetAll(ctx context.Context) ([]L, error) { + rows, err := q.db.Query(ctx, getAll) + if err != nil { + return nil, err + } + defer rows.Close() + var items []L + for rows.Next() { + var i L + if err := rows.Scan(&i.ID, &i.ParentID); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getAll1 = `-- name: GetAll1 :many +with recursive cte as ( + select id, L_ID, F from T + union all + select c.id, c.L_ID, c.F from T as c where c.L_ID = $1 +) select id, l_id, f from cte +` + +type GetAll1Row struct { + ID int64 + LID pgtype.Int4 + F pgtype.Text +} + +func (q *Queries) GetAll1(ctx context.Context, lID pgtype.Int4) ([]GetAll1Row, error) { + rows, err := q.db.Query(ctx, getAll1, lID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetAll1Row + for rows.Next() { + var i GetAll1Row + if err := rows.Scan(&i.ID, &i.LID, &i.F); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getAll2 = `-- name: GetAll2 :many +with recursive cte as ( + select id, L_ID, F from T where T.ID=2 + union all + select c.id, c.L_ID, c.F from T as c where c.L_ID = $1 +) select id, l_id, f from cte +` + +type GetAll2Row struct { + ID int64 + LID pgtype.Int4 + F pgtype.Text +} + +func (q *Queries) GetAll2(ctx context.Context, lID pgtype.Int4) ([]GetAll2Row, error) { + rows, err := q.db.Query(ctx, getAll2, lID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetAll2Row + for rows.Next() { + var i GetAll2Row + if err := rows.Scan(&i.ID, &i.LID, &i.F); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getAll3 = `-- name: GetAll3 :many +select id from T where L_ID in( + with recursive cte as ( + select id, L_ID, F from T where T.ID =2 + union all + select c.id, c.L_ID, c.F from T as c where c.L_ID = $1 + ) select l_id from cte +) +` + +func (q *Queries) GetAll3(ctx context.Context, dollar_1 pgtype.Int4) ([]int64, error) { + rows, err := q.db.Query(ctx, getAll3, dollar_1) + if err != nil { + return nil, err + } + defer rows.Close() + var items []int64 + for rows.Next() { + var id int64 + if err := rows.Scan(&id); err != nil { + return nil, err + } + items = append(items, id) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getAll4 = `-- name: GetAll4 :many +select id from T where L_ID in( + with recursive L as ( + select id, L_ID, F from T where T.ID =2 + union all + select c.id, c.L_ID, c.F from T as c where c.L_ID = $1 + ) select l_id from L +) +` + +func (q *Queries) GetAll4(ctx context.Context, lID pgtype.Int4) ([]int64, error) { + rows, err := q.db.Query(ctx, getAll4, lID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []int64 + for rows.Next() { + var id int64 + if err := rows.Scan(&id); err != nil { + return nil, err + } + items = append(items, id) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/query.sql b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/query.sql new file mode 100644 index 0000000000..4a27713beb --- /dev/null +++ b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/query.sql @@ -0,0 +1,34 @@ +-- name: GetAll :many +SELECT * FROM L; + +-- name: GetAll1 :many +with recursive cte as ( + select id, L_ID, F from T + union all + select c.id, c.L_ID, c.F from T as c where c.L_ID = $1 +) select id, l_id, f from cte; + +-- name: GetAll2 :many +with recursive cte as ( + select id, L_ID, F from T where T.ID=2 + union all + select c.id, c.L_ID, c.F from T as c where c.L_ID = $1 +) select id, l_id, f from cte; + +-- name: GetAll4 :many +select id from T where L_ID in( + with recursive L as ( + select id, L_ID, F from T where T.ID =2 + union all + select c.id, c.L_ID, c.F from T as c where c.L_ID = $1 + ) select l_id from L +); + +-- name: GetAll3 :many +select id from T where L_ID in( + with recursive cte as ( + select id, L_ID, F from T where T.ID =2 + union all + select c.id, c.L_ID, c.F from T as c where c.L_ID = $1 + ) select l_id from cte +); diff --git a/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/schema.sql b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/schema.sql new file mode 100644 index 0000000000..cf970e3331 --- /dev/null +++ b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/schema.sql @@ -0,0 +1,12 @@ +-- https://github.com/sqlc-dev/sqlc/issues/2153 + +CREATE TABLE L ( + id BIGSERIAL PRIMARY KEY, + parent_id int null +); + +CREATE TABLE T ( + id BIGSERIAL PRIMARY KEY, + L_ID int, + F varchar(256) +); diff --git a/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/sqlc.json b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/sqlc.json new file mode 100644 index 0000000000..4905a64003 --- /dev/null +++ b/internal/endtoend/testdata/cte_with_in/postgresql/pganalyze/sqlc.json @@ -0,0 +1,14 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "name": "querytest", + "engine": "postgresql", + "schema": "schema.sql", + "queries": "query.sql", + "sql_package": "pgx/v5" + } + ] +} + diff --git a/internal/endtoend/testdata/enum/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/enum/postgresql/pgx/v4/go/query.sql.go index 03d3d94c31..3d89ba41e9 100644 --- a/internal/endtoend/testdata/enum/postgresql/pgx/v4/go/query.sql.go +++ b/internal/endtoend/testdata/enum/postgresql/pgx/v4/go/query.sql.go @@ -58,18 +58,16 @@ func (q *Queries) GetAll(ctx context.Context, db DBTX) ([]User, error) { const newUser = `-- name: NewUser :exec INSERT INTO users ( - id, first_name, last_name, age, shoe_size, shirt_size ) VALUES -($1, $2, $3, $4, $5, $6) +($1, $2, $3, $4, $5) ` type NewUserParams struct { - ID int32 FirstName string LastName sql.NullString Age int32 @@ -79,7 +77,6 @@ type NewUserParams struct { func (q *Queries) NewUser(ctx context.Context, db DBTX, arg NewUserParams) error { _, err := db.Exec(ctx, newUser, - arg.ID, arg.FirstName, arg.LastName, arg.Age, diff --git a/internal/endtoend/testdata/enum/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/enum/postgresql/pgx/v4/query.sql index 5b7ed159f9..818eafd10d 100644 --- a/internal/endtoend/testdata/enum/postgresql/pgx/v4/query.sql +++ b/internal/endtoend/testdata/enum/postgresql/pgx/v4/query.sql @@ -3,14 +3,13 @@ SELECT * FROM users; -- name: NewUser :exec INSERT INTO users ( - id, first_name, last_name, age, shoe_size, shirt_size ) VALUES -($1, $2, $3, $4, $5, $6); +($1, $2, $3, $4, $5); -- name: UpdateSizes :exec UPDATE users diff --git a/internal/endtoend/testdata/enum/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/enum/postgresql/pgx/v5/go/query.sql.go index 7e3b425e15..d3b28468ad 100644 --- a/internal/endtoend/testdata/enum/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/enum/postgresql/pgx/v5/go/query.sql.go @@ -59,18 +59,16 @@ func (q *Queries) GetAll(ctx context.Context, db DBTX) ([]User, error) { const newUser = `-- name: NewUser :exec INSERT INTO users ( - id, first_name, last_name, age, shoe_size, shirt_size ) VALUES -($1, $2, $3, $4, $5, $6) +($1, $2, $3, $4, $5) ` type NewUserParams struct { - ID int32 FirstName string LastName pgtype.Text Age int32 @@ -80,7 +78,6 @@ type NewUserParams struct { func (q *Queries) NewUser(ctx context.Context, db DBTX, arg NewUserParams) error { _, err := db.Exec(ctx, newUser, - arg.ID, arg.FirstName, arg.LastName, arg.Age, diff --git a/internal/endtoend/testdata/enum/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/enum/postgresql/pgx/v5/query.sql index 5b7ed159f9..1902312c1a 100644 --- a/internal/endtoend/testdata/enum/postgresql/pgx/v5/query.sql +++ b/internal/endtoend/testdata/enum/postgresql/pgx/v5/query.sql @@ -3,14 +3,13 @@ SELECT * FROM users; -- name: NewUser :exec INSERT INTO users ( - id, first_name, last_name, age, shoe_size, shirt_size ) VALUES -($1, $2, $3, $4, $5, $6); +($1, $2, $3, $4, $5); -- name: UpdateSizes :exec UPDATE users @@ -19,4 +18,4 @@ WHERE id = $1; -- name: DeleteBySize :exec DELETE FROM users -WHERE shoe_size = $1 AND shirt_size = $2; \ No newline at end of file +WHERE shoe_size = $1 AND shirt_size = $2; diff --git a/internal/endtoend/testdata/enum/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/enum/postgresql/stdlib/go/query.sql.go index 037574c405..ef7aab07c0 100644 --- a/internal/endtoend/testdata/enum/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/enum/postgresql/stdlib/go/query.sql.go @@ -61,18 +61,16 @@ func (q *Queries) GetAll(ctx context.Context, db DBTX) ([]User, error) { const newUser = `-- name: NewUser :exec INSERT INTO users ( - id, first_name, last_name, age, shoe_size, shirt_size ) VALUES -($1, $2, $3, $4, $5, $6) +($1, $2, $3, $4, $5) ` type NewUserParams struct { - ID int32 FirstName string LastName sql.NullString Age int32 @@ -82,7 +80,6 @@ type NewUserParams struct { func (q *Queries) NewUser(ctx context.Context, db DBTX, arg NewUserParams) error { _, err := db.ExecContext(ctx, newUser, - arg.ID, arg.FirstName, arg.LastName, arg.Age, diff --git a/internal/endtoend/testdata/enum/postgresql/stdlib/query.sql b/internal/endtoend/testdata/enum/postgresql/stdlib/query.sql index 5b7ed159f9..1902312c1a 100644 --- a/internal/endtoend/testdata/enum/postgresql/stdlib/query.sql +++ b/internal/endtoend/testdata/enum/postgresql/stdlib/query.sql @@ -3,14 +3,13 @@ SELECT * FROM users; -- name: NewUser :exec INSERT INTO users ( - id, first_name, last_name, age, shoe_size, shirt_size ) VALUES -($1, $2, $3, $4, $5, $6); +($1, $2, $3, $4, $5); -- name: UpdateSizes :exec UPDATE users @@ -19,4 +18,4 @@ WHERE id = $1; -- name: DeleteBySize :exec DELETE FROM users -WHERE shoe_size = $1 AND shirt_size = $2; \ No newline at end of file +WHERE shoe_size = $1 AND shirt_size = $2; diff --git a/internal/endtoend/testdata/func_aggregate/pganalyze/exec.json b/internal/endtoend/testdata/func_aggregate/pganalyze/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/func_aggregate/pganalyze/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/func_aggregate/go/db.go b/internal/endtoend/testdata/func_aggregate/pganalyze/go/db.go similarity index 100% rename from internal/endtoend/testdata/func_aggregate/go/db.go rename to internal/endtoend/testdata/func_aggregate/pganalyze/go/db.go diff --git a/internal/endtoend/testdata/func_aggregate/go/models.go b/internal/endtoend/testdata/func_aggregate/pganalyze/go/models.go similarity index 100% rename from internal/endtoend/testdata/func_aggregate/go/models.go rename to internal/endtoend/testdata/func_aggregate/pganalyze/go/models.go diff --git a/internal/endtoend/testdata/func_aggregate/pganalyze/go/query.sql.go b/internal/endtoend/testdata/func_aggregate/pganalyze/go/query.sql.go new file mode 100644 index 0000000000..ab5777dd4e --- /dev/null +++ b/internal/endtoend/testdata/func_aggregate/pganalyze/go/query.sql.go @@ -0,0 +1,22 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const percentile = `-- name: Percentile :one +select percentile_disc(0.5) within group (order by authors.name) +from authors +` + +func (q *Queries) Percentile(ctx context.Context) (string, error) { + row := q.db.QueryRowContext(ctx, percentile) + var percentile_disc string + err := row.Scan(&percentile_disc) + return percentile_disc, err +} diff --git a/internal/endtoend/testdata/func_aggregate/query.sql b/internal/endtoend/testdata/func_aggregate/pganalyze/query.sql similarity index 100% rename from internal/endtoend/testdata/func_aggregate/query.sql rename to internal/endtoend/testdata/func_aggregate/pganalyze/query.sql diff --git a/internal/endtoend/testdata/func_aggregate/schema.sql b/internal/endtoend/testdata/func_aggregate/pganalyze/schema.sql similarity index 100% rename from internal/endtoend/testdata/func_aggregate/schema.sql rename to internal/endtoend/testdata/func_aggregate/pganalyze/schema.sql diff --git a/internal/endtoend/testdata/func_aggregate/sqlc.json b/internal/endtoend/testdata/func_aggregate/pganalyze/sqlc.json similarity index 100% rename from internal/endtoend/testdata/func_aggregate/sqlc.json rename to internal/endtoend/testdata/func_aggregate/pganalyze/sqlc.json diff --git a/internal/endtoend/testdata/func_aggregate/postgresql/exec.json b/internal/endtoend/testdata/func_aggregate/postgresql/exec.json new file mode 100644 index 0000000000..c16f123ce3 --- /dev/null +++ b/internal/endtoend/testdata/func_aggregate/postgresql/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} \ No newline at end of file diff --git a/internal/endtoend/testdata/func_return/postgresql/stdlib/go/db.go b/internal/endtoend/testdata/func_aggregate/postgresql/go/db.go similarity index 100% rename from internal/endtoend/testdata/func_return/postgresql/stdlib/go/db.go rename to internal/endtoend/testdata/func_aggregate/postgresql/go/db.go diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v4/go/models.go b/internal/endtoend/testdata/func_aggregate/postgresql/go/models.go similarity index 64% rename from internal/endtoend/testdata/func_return/postgresql/pgx/v4/go/models.go rename to internal/endtoend/testdata/func_aggregate/postgresql/go/models.go index 18a0ebb3e7..2727f2e2de 100644 --- a/internal/endtoend/testdata/func_return/postgresql/pgx/v4/go/models.go +++ b/internal/endtoend/testdata/func_aggregate/postgresql/go/models.go @@ -8,7 +8,8 @@ import ( "database/sql" ) -type User struct { - ID sql.NullInt32 - FirstName string +type Author struct { + ID int64 + Name string + Bio sql.NullString } diff --git a/internal/endtoend/testdata/func_aggregate/go/query.sql.go b/internal/endtoend/testdata/func_aggregate/postgresql/go/query.sql.go similarity index 100% rename from internal/endtoend/testdata/func_aggregate/go/query.sql.go rename to internal/endtoend/testdata/func_aggregate/postgresql/go/query.sql.go diff --git a/internal/endtoend/testdata/func_aggregate/postgresql/query.sql b/internal/endtoend/testdata/func_aggregate/postgresql/query.sql new file mode 100644 index 0000000000..cdda8237c9 --- /dev/null +++ b/internal/endtoend/testdata/func_aggregate/postgresql/query.sql @@ -0,0 +1,3 @@ +-- name: Percentile :one +select percentile_disc(0.5) within group (order by authors.name) +from authors; diff --git a/internal/endtoend/testdata/func_aggregate/postgresql/schema.sql b/internal/endtoend/testdata/func_aggregate/postgresql/schema.sql new file mode 100644 index 0000000000..290bbe1642 --- /dev/null +++ b/internal/endtoend/testdata/func_aggregate/postgresql/schema.sql @@ -0,0 +1,7 @@ +-- Example queries for sqlc +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); + diff --git a/internal/endtoend/testdata/func_aggregate/postgresql/sqlc.json b/internal/endtoend/testdata/func_aggregate/postgresql/sqlc.json new file mode 100644 index 0000000000..dbe55e66a6 --- /dev/null +++ b/internal/endtoend/testdata/func_aggregate/postgresql/sqlc.json @@ -0,0 +1,11 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "name": "querytest", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v4/go/query.sql.go index b5d079a8b9..d1d80d7fa1 100644 --- a/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v4/go/query.sql.go +++ b/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v4/go/query.sql.go @@ -15,8 +15,8 @@ const demo = `-- name: Demo :one SELECT uuid_generate_v5('7c4597a0-8cfa-4c19-8da0-b8474a36440d', $1)::uuid as col1 ` -func (q *Queries) Demo(ctx context.Context, uuidGenerateV5 interface{}) (uuid.UUID, error) { - row := q.db.QueryRow(ctx, demo, uuidGenerateV5) +func (q *Queries) Demo(ctx context.Context, name string) (uuid.UUID, error) { + row := q.db.QueryRow(ctx, demo, name) var col1 uuid.UUID err := row.Scan(&col1) return col1, err diff --git a/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v4/schema.sql b/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v4/schema.sql index e69de29bb2..682131d3bf 100644 --- a/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v4/schema.sql +++ b/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v4/schema.sql @@ -0,0 +1 @@ +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; \ No newline at end of file diff --git a/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v5/go/query.sql.go index 973118c2bb..e32d8a6983 100644 --- a/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v5/go/query.sql.go @@ -15,8 +15,8 @@ const demo = `-- name: Demo :one SELECT uuid_generate_v5('7c4597a0-8cfa-4c19-8da0-b8474a36440d', $1)::uuid as col1 ` -func (q *Queries) Demo(ctx context.Context, uuidGenerateV5 interface{}) (pgtype.UUID, error) { - row := q.db.QueryRow(ctx, demo, uuidGenerateV5) +func (q *Queries) Demo(ctx context.Context, name string) (pgtype.UUID, error) { + row := q.db.QueryRow(ctx, demo, name) var col1 pgtype.UUID err := row.Scan(&col1) return col1, err diff --git a/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v5/schema.sql b/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v5/schema.sql index e69de29bb2..682131d3bf 100644 --- a/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v5/schema.sql +++ b/internal/endtoend/testdata/func_call_cast/postgresql/pgx/v5/schema.sql @@ -0,0 +1 @@ +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; \ No newline at end of file diff --git a/internal/endtoend/testdata/func_call_cast/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/func_call_cast/postgresql/stdlib/go/query.sql.go index 55b1e9432b..0d22c19e45 100644 --- a/internal/endtoend/testdata/func_call_cast/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/func_call_cast/postgresql/stdlib/go/query.sql.go @@ -15,8 +15,8 @@ const demo = `-- name: Demo :one SELECT uuid_generate_v5('7c4597a0-8cfa-4c19-8da0-b8474a36440d', $1)::uuid as col1 ` -func (q *Queries) Demo(ctx context.Context, uuidGenerateV5 interface{}) (uuid.UUID, error) { - row := q.db.QueryRowContext(ctx, demo, uuidGenerateV5) +func (q *Queries) Demo(ctx context.Context, name string) (uuid.UUID, error) { + row := q.db.QueryRowContext(ctx, demo, name) var col1 uuid.UUID err := row.Scan(&col1) return col1, err diff --git a/internal/endtoend/testdata/func_call_cast/postgresql/stdlib/schema.sql b/internal/endtoend/testdata/func_call_cast/postgresql/stdlib/schema.sql index e69de29bb2..682131d3bf 100644 --- a/internal/endtoend/testdata/func_call_cast/postgresql/stdlib/schema.sql +++ b/internal/endtoend/testdata/func_call_cast/postgresql/stdlib/schema.sql @@ -0,0 +1 @@ +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; \ No newline at end of file diff --git a/internal/endtoend/testdata/func_match_types/postgresql/go/models.go b/internal/endtoend/testdata/func_match_types/postgresql/go/models.go index 4d16f82923..315221c85b 100644 --- a/internal/endtoend/testdata/func_match_types/postgresql/go/models.go +++ b/internal/endtoend/testdata/func_match_types/postgresql/go/models.go @@ -10,5 +10,5 @@ type Book struct { ID int32 Title string Author string - Pages string + Pages int32 } diff --git a/internal/endtoend/testdata/func_match_types/postgresql/schema.sql b/internal/endtoend/testdata/func_match_types/postgresql/schema.sql index db9215b088..cf91381e3f 100644 --- a/internal/endtoend/testdata/func_match_types/postgresql/schema.sql +++ b/internal/endtoend/testdata/func_match_types/postgresql/schema.sql @@ -1,6 +1,6 @@ CREATE TABLE books ( - id integer PRIMARY KEY, - title text NOT NULL, - author text NOT NULL, - pages numeric NOT NULL + id integer PRIMARY KEY, + title text NOT NULL, + author text NOT NULL, + pages integer NOT NULL ); diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/func_return/postgresql/pgx/v4/go/query.sql.go deleted file mode 100644 index 4bca42ab68..0000000000 --- a/internal/endtoend/testdata/func_return/postgresql/pgx/v4/go/query.sql.go +++ /dev/null @@ -1,83 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.22.0 -// source: query.sql - -package querytest - -import ( - "context" - - "github.com/jackc/pgtype" -) - -const generateSeries = `-- name: GenerateSeries :many -SELECT ($1::inet) + i -FROM generate_series(0, $2::int) AS i -LIMIT 1 -` - -type GenerateSeriesParams struct { - Column1 pgtype.Inet - Column2 int32 -} - -func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]int32, error) { - rows, err := q.db.Query(ctx, generateSeries, arg.Column1, arg.Column2) - if err != nil { - return nil, err - } - defer rows.Close() - var items []int32 - for rows.Next() { - var column_1 int32 - if err := rows.Scan(&column_1); err != nil { - return nil, err - } - items = append(items, column_1) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const getDate = `-- name: GetDate :one -SELECT from CURRENT_DATE -` - -type GetDateRow struct { -} - -func (q *Queries) GetDate(ctx context.Context) (GetDateRow, error) { - row := q.db.QueryRow(ctx, getDate) - var i GetDateRow - err := row.Scan() - return i, err -} - -const getUsers = `-- name: GetUsers :many -SELECT id, first_name -FROM users_func() -WHERE first_name != '' -` - -func (q *Queries) GetUsers(ctx context.Context) ([]User, error) { - rows, err := q.db.Query(ctx, getUsers) - if err != nil { - return nil, err - } - defer rows.Close() - var items []User - for rows.Next() { - var i User - if err := rows.Scan(&i.ID, &i.FirstName); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/func_return/postgresql/pgx/v4/query.sql deleted file mode 100644 index c2fe0b941b..0000000000 --- a/internal/endtoend/testdata/func_return/postgresql/pgx/v4/query.sql +++ /dev/null @@ -1,13 +0,0 @@ - -/* name: GetUsers :many */ -SELECT * -FROM users_func() -WHERE first_name != ''; - -/* name: GenerateSeries :many */ -SELECT ($1::inet) + i -FROM generate_series(0, $2::int) AS i -LIMIT 1; - -/* name: GetDate :one */ -SELECT * from CURRENT_DATE; \ No newline at end of file diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v4/schema.sql b/internal/endtoend/testdata/func_return/postgresql/pgx/v4/schema.sql deleted file mode 100644 index adc43acdb6..0000000000 --- a/internal/endtoend/testdata/func_return/postgresql/pgx/v4/schema.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE users ( - id integer, - first_name varchar(255) NOT NULL -); - -CREATE FUNCTION users_func() RETURNS SETOF users AS $func$ - BEGIN - SELECT * - FROM users; - END; -$func$ LANGUAGE plpgsql; diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/func_return/postgresql/pgx/v5/go/query.sql.go deleted file mode 100644 index 19f4053aa9..0000000000 --- a/internal/endtoend/testdata/func_return/postgresql/pgx/v5/go/query.sql.go +++ /dev/null @@ -1,82 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.22.0 -// source: query.sql - -package querytest - -import ( - "context" - "net/netip" -) - -const generateSeries = `-- name: GenerateSeries :many -SELECT ($1::inet) + i -FROM generate_series(0, $2::int) AS i -LIMIT 1 -` - -type GenerateSeriesParams struct { - Column1 netip.Addr - Column2 int32 -} - -func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]int32, error) { - rows, err := q.db.Query(ctx, generateSeries, arg.Column1, arg.Column2) - if err != nil { - return nil, err - } - defer rows.Close() - var items []int32 - for rows.Next() { - var column_1 int32 - if err := rows.Scan(&column_1); err != nil { - return nil, err - } - items = append(items, column_1) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const getDate = `-- name: GetDate :one -SELECT from CURRENT_DATE -` - -type GetDateRow struct { -} - -func (q *Queries) GetDate(ctx context.Context) (GetDateRow, error) { - row := q.db.QueryRow(ctx, getDate) - var i GetDateRow - err := row.Scan() - return i, err -} - -const getUsers = `-- name: GetUsers :many -SELECT id, first_name -FROM users_func() -WHERE first_name != '' -` - -func (q *Queries) GetUsers(ctx context.Context) ([]User, error) { - rows, err := q.db.Query(ctx, getUsers) - if err != nil { - return nil, err - } - defer rows.Close() - var items []User - for rows.Next() { - var i User - if err := rows.Scan(&i.ID, &i.FirstName); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/func_return/postgresql/pgx/v5/query.sql deleted file mode 100644 index c2fe0b941b..0000000000 --- a/internal/endtoend/testdata/func_return/postgresql/pgx/v5/query.sql +++ /dev/null @@ -1,13 +0,0 @@ - -/* name: GetUsers :many */ -SELECT * -FROM users_func() -WHERE first_name != ''; - -/* name: GenerateSeries :many */ -SELECT ($1::inet) + i -FROM generate_series(0, $2::int) AS i -LIMIT 1; - -/* name: GetDate :one */ -SELECT * from CURRENT_DATE; \ No newline at end of file diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v5/schema.sql b/internal/endtoend/testdata/func_return/postgresql/pgx/v5/schema.sql deleted file mode 100644 index adc43acdb6..0000000000 --- a/internal/endtoend/testdata/func_return/postgresql/pgx/v5/schema.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE users ( - id integer, - first_name varchar(255) NOT NULL -); - -CREATE FUNCTION users_func() RETURNS SETOF users AS $func$ - BEGIN - SELECT * - FROM users; - END; -$func$ LANGUAGE plpgsql; diff --git a/internal/endtoend/testdata/func_return/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/func_return/postgresql/stdlib/go/query.sql.go deleted file mode 100644 index 5bda0df50d..0000000000 --- a/internal/endtoend/testdata/func_return/postgresql/stdlib/go/query.sql.go +++ /dev/null @@ -1,89 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.22.0 -// source: query.sql - -package querytest - -import ( - "context" - - "github.com/sqlc-dev/pqtype" -) - -const generateSeries = `-- name: GenerateSeries :many -SELECT ($1::inet) + i -FROM generate_series(0, $2::int) AS i -LIMIT 1 -` - -type GenerateSeriesParams struct { - Column1 pqtype.Inet - Column2 int32 -} - -func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]int32, error) { - rows, err := q.db.QueryContext(ctx, generateSeries, arg.Column1, arg.Column2) - if err != nil { - return nil, err - } - defer rows.Close() - var items []int32 - for rows.Next() { - var column_1 int32 - if err := rows.Scan(&column_1); err != nil { - return nil, err - } - items = append(items, column_1) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const getDate = `-- name: GetDate :one -SELECT from CURRENT_DATE -` - -type GetDateRow struct { -} - -func (q *Queries) GetDate(ctx context.Context) (GetDateRow, error) { - row := q.db.QueryRowContext(ctx, getDate) - var i GetDateRow - err := row.Scan() - return i, err -} - -const getUsers = `-- name: GetUsers :many -SELECT id, first_name -FROM users_func() -WHERE first_name != '' -` - -func (q *Queries) GetUsers(ctx context.Context) ([]User, error) { - rows, err := q.db.QueryContext(ctx, getUsers) - if err != nil { - return nil, err - } - defer rows.Close() - var items []User - for rows.Next() { - var i User - if err := rows.Scan(&i.ID, &i.FirstName); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} diff --git a/internal/endtoend/testdata/func_return/postgresql/stdlib/query.sql b/internal/endtoend/testdata/func_return/postgresql/stdlib/query.sql deleted file mode 100644 index c2fe0b941b..0000000000 --- a/internal/endtoend/testdata/func_return/postgresql/stdlib/query.sql +++ /dev/null @@ -1,13 +0,0 @@ - -/* name: GetUsers :many */ -SELECT * -FROM users_func() -WHERE first_name != ''; - -/* name: GenerateSeries :many */ -SELECT ($1::inet) + i -FROM generate_series(0, $2::int) AS i -LIMIT 1; - -/* name: GetDate :one */ -SELECT * from CURRENT_DATE; \ No newline at end of file diff --git a/internal/endtoend/testdata/func_return/postgresql/stdlib/schema.sql b/internal/endtoend/testdata/func_return/postgresql/stdlib/schema.sql deleted file mode 100644 index adc43acdb6..0000000000 --- a/internal/endtoend/testdata/func_return/postgresql/stdlib/schema.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE users ( - id integer, - first_name varchar(255) NOT NULL -); - -CREATE FUNCTION users_func() RETURNS SETOF users AS $func$ - BEGIN - SELECT * - FROM users; - END; -$func$ LANGUAGE plpgsql; diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/exec.json b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/db.go b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/models.go b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/models.go new file mode 100644 index 0000000000..172574ab22 --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/models.go @@ -0,0 +1,7 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/query.sql.go b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/query.sql.go new file mode 100644 index 0000000000..9597c2cdeb --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/go/query.sql.go @@ -0,0 +1,23 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const getDate = `-- name: GetDate :one +SELECT now from NOW() +` + +func (q *Queries) GetDate(ctx context.Context) (pgtype.Timestamptz, error) { + row := q.db.QueryRow(ctx, getDate) + var now pgtype.Timestamptz + err := row.Scan(&now) + return now, err +} diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/query.sql b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/query.sql new file mode 100644 index 0000000000..8f71309953 --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/query.sql @@ -0,0 +1,2 @@ +/* name: GetDate :one */ +SELECT * from NOW(); \ No newline at end of file diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/schema.sql b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v5/sqlc.json b/internal/endtoend/testdata/func_return_date/postgresql/pganalyze/sqlc.json similarity index 100% rename from internal/endtoend/testdata/func_return/postgresql/pgx/v5/sqlc.json rename to internal/endtoend/testdata/func_return_date/postgresql/pganalyze/sqlc.json diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/exec.json b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/db.go b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/models.go b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/models.go new file mode 100644 index 0000000000..172574ab22 --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/models.go @@ -0,0 +1,7 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/query.sql.go new file mode 100644 index 0000000000..092a37679b --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/go/query.sql.go @@ -0,0 +1,24 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const getDate = `-- name: GetDate :one +SELECT from CURRENT_DATE +` + +type GetDateRow struct { +} + +func (q *Queries) GetDate(ctx context.Context) (GetDateRow, error) { + row := q.db.QueryRow(ctx, getDate) + var i GetDateRow + err := row.Scan() + return i, err +} diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/query.sql new file mode 100644 index 0000000000..b5696a969e --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/query.sql @@ -0,0 +1,2 @@ +/* name: GetDate :one */ +SELECT * from CURRENT_DATE; diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/schema.sql b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/sqlc.json b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/sqlc.json new file mode 100644 index 0000000000..32ede07158 --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/pgx/v5/sqlc.json @@ -0,0 +1,13 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "sql_package": "pgx/v5", + "name": "querytest", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/func_return_date/postgresql/stdlib/exec.json b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/db.go b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/db.go new file mode 100644 index 0000000000..a457fb76b2 --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/models.go b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/models.go new file mode 100644 index 0000000000..172574ab22 --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/models.go @@ -0,0 +1,7 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () diff --git a/internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/query.sql.go new file mode 100644 index 0000000000..e6f9c7e038 --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/go/query.sql.go @@ -0,0 +1,24 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const getDate = `-- name: GetDate :one +SELECT from CURRENT_DATE +` + +type GetDateRow struct { +} + +func (q *Queries) GetDate(ctx context.Context) (GetDateRow, error) { + row := q.db.QueryRowContext(ctx, getDate) + var i GetDateRow + err := row.Scan() + return i, err +} diff --git a/internal/endtoend/testdata/func_return_date/postgresql/stdlib/query.sql b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/query.sql new file mode 100644 index 0000000000..b5696a969e --- /dev/null +++ b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/query.sql @@ -0,0 +1,2 @@ +/* name: GetDate :one */ +SELECT * from CURRENT_DATE; diff --git a/internal/endtoend/testdata/func_return_date/postgresql/stdlib/schema.sql b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/func_return/postgresql/stdlib/sqlc.json b/internal/endtoend/testdata/func_return_date/postgresql/stdlib/sqlc.json similarity index 100% rename from internal/endtoend/testdata/func_return/postgresql/stdlib/sqlc.json rename to internal/endtoend/testdata/func_return_date/postgresql/stdlib/sqlc.json diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v4/go/db.go b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/go/db.go similarity index 100% rename from internal/endtoend/testdata/func_return/postgresql/pgx/v4/go/db.go rename to internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/go/db.go diff --git a/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/go/models.go b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/go/models.go new file mode 100644 index 0000000000..172574ab22 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/go/models.go @@ -0,0 +1,7 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () diff --git a/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/go/query.sql.go new file mode 100644 index 0000000000..7167ba9f5b --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/go/query.sql.go @@ -0,0 +1,41 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const generateSeries = `-- name: GenerateSeries :many +SELECT ($1::int) + i +FROM generate_series(0, $2::int) AS i +LIMIT 1 +` + +type GenerateSeriesParams struct { + Column1 int32 + Column2 int32 +} + +func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]int32, error) { + rows, err := q.db.Query(ctx, generateSeries, arg.Column1, arg.Column2) + if err != nil { + return nil, err + } + defer rows.Close() + var items []int32 + for rows.Next() { + var column_1 int32 + if err := rows.Scan(&column_1); err != nil { + return nil, err + } + items = append(items, column_1) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/query.sql new file mode 100644 index 0000000000..ac5a434493 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/query.sql @@ -0,0 +1,4 @@ +/* name: GenerateSeries :many */ +SELECT ($1::int) + i +FROM generate_series(0, $2::int) AS i +LIMIT 1; diff --git a/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/schema.sql b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/func_return/postgresql/pgx/v4/sqlc.json b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/sqlc.json similarity index 100% rename from internal/endtoend/testdata/func_return/postgresql/pgx/v4/sqlc.json rename to internal/endtoend/testdata/func_return_series/postgresql/pgx/v4/sqlc.json diff --git a/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/db.go b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/models.go b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/models.go new file mode 100644 index 0000000000..172574ab22 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/models.go @@ -0,0 +1,7 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () diff --git a/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/query.sql.go new file mode 100644 index 0000000000..7167ba9f5b --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/go/query.sql.go @@ -0,0 +1,41 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const generateSeries = `-- name: GenerateSeries :many +SELECT ($1::int) + i +FROM generate_series(0, $2::int) AS i +LIMIT 1 +` + +type GenerateSeriesParams struct { + Column1 int32 + Column2 int32 +} + +func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]int32, error) { + rows, err := q.db.Query(ctx, generateSeries, arg.Column1, arg.Column2) + if err != nil { + return nil, err + } + defer rows.Close() + var items []int32 + for rows.Next() { + var column_1 int32 + if err := rows.Scan(&column_1); err != nil { + return nil, err + } + items = append(items, column_1) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/query.sql new file mode 100644 index 0000000000..ac5a434493 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/query.sql @@ -0,0 +1,4 @@ +/* name: GenerateSeries :many */ +SELECT ($1::int) + i +FROM generate_series(0, $2::int) AS i +LIMIT 1; diff --git a/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/schema.sql b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/sqlc.json b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/sqlc.json new file mode 100644 index 0000000000..32ede07158 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/pgx/v5/sqlc.json @@ -0,0 +1,13 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "sql_package": "pgx/v5", + "name": "querytest", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/db.go b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/db.go new file mode 100644 index 0000000000..a457fb76b2 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/models.go b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/models.go new file mode 100644 index 0000000000..172574ab22 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/models.go @@ -0,0 +1,7 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () diff --git a/internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/query.sql.go new file mode 100644 index 0000000000..563fd9df33 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/go/query.sql.go @@ -0,0 +1,44 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const generateSeries = `-- name: GenerateSeries :many +SELECT ($1::int) + i +FROM generate_series(0, $2::int) AS i +LIMIT 1 +` + +type GenerateSeriesParams struct { + Column1 int32 + Column2 int32 +} + +func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]int32, error) { + rows, err := q.db.QueryContext(ctx, generateSeries, arg.Column1, arg.Column2) + if err != nil { + return nil, err + } + defer rows.Close() + var items []int32 + for rows.Next() { + var column_1 int32 + if err := rows.Scan(&column_1); err != nil { + return nil, err + } + items = append(items, column_1) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/func_return_series/postgresql/stdlib/query.sql b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/query.sql new file mode 100644 index 0000000000..ac5a434493 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/query.sql @@ -0,0 +1,4 @@ +/* name: GenerateSeries :many */ +SELECT ($1::int) + i +FROM generate_series(0, $2::int) AS i +LIMIT 1; diff --git a/internal/endtoend/testdata/func_return_series/postgresql/stdlib/schema.sql b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/func_return_series/postgresql/stdlib/sqlc.json b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/sqlc.json new file mode 100644 index 0000000000..f717ca2e66 --- /dev/null +++ b/internal/endtoend/testdata/func_return_series/postgresql/stdlib/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "name": "querytest", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/func_variadic/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/func_variadic/postgresql/stdlib/go/query.sql.go index 5ad9d9edda..07cd383acf 100644 --- a/internal/endtoend/testdata/func_variadic/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/func_variadic/postgresql/stdlib/go/query.sql.go @@ -14,25 +14,25 @@ const updateJ = `-- name: UpdateJ :exec UPDATE test SET - j = jsonb_build_object($1, $2, $3, $4) + j = jsonb_build_object($1::text, $2::text, $3::text, $4::text) WHERE id = $5 ` type UpdateJParams struct { - JsonbBuildObject interface{} - JsonbBuildObject_2 interface{} - JsonbBuildObject_3 interface{} - JsonbBuildObject_4 interface{} - ID sql.NullInt32 + Column1 string + Column2 string + Column3 string + Column4 string + ID sql.NullInt32 } func (q *Queries) UpdateJ(ctx context.Context, arg UpdateJParams) error { _, err := q.db.ExecContext(ctx, updateJ, - arg.JsonbBuildObject, - arg.JsonbBuildObject_2, - arg.JsonbBuildObject_3, - arg.JsonbBuildObject_4, + arg.Column1, + arg.Column2, + arg.Column3, + arg.Column4, arg.ID, ) return err diff --git a/internal/endtoend/testdata/func_variadic/postgresql/stdlib/query.sql b/internal/endtoend/testdata/func_variadic/postgresql/stdlib/query.sql index c3f9b32b36..235e7cbb90 100644 --- a/internal/endtoend/testdata/func_variadic/postgresql/stdlib/query.sql +++ b/internal/endtoend/testdata/func_variadic/postgresql/stdlib/query.sql @@ -2,6 +2,6 @@ UPDATE test SET - j = jsonb_build_object($1, $2, $3, $4) + j = jsonb_build_object($1::text, $2::text, $3::text, $4::text) WHERE id = $5; \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/query.sql index 41b0289d23..fad60fef89 100644 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/query.sql +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/query.sql @@ -1,5 +1,3 @@ -CREATE TABLE foo (bar text); - -- name: InsertFoo :exec INSERT INTO foo (bar) -SELECT 1, $1, $2; +SELECT 1, $1, $2; \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/schema.sql b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/schema.sql new file mode 100644 index 0000000000..be35e943bd --- /dev/null +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (bar text); \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/sqlc.json b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/sqlc.json index 9403bd0279..d1244c9e7a 100644 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/sqlc.json +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v4", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr.txt index 063b2a149a..8463ed03b8 100644 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr.txt +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr.txt @@ -1,2 +1,5 @@ # package querytest -query.sql:4:1: INSERT has more expressions than target columns +query.sql:1:1: INSERT has more expressions than target columns +--- +# package querytest +query.sql:3:11: INSERT has more expressions than target columns \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/query.sql index 41b0289d23..fad60fef89 100644 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/query.sql +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/query.sql @@ -1,5 +1,3 @@ -CREATE TABLE foo (bar text); - -- name: InsertFoo :exec INSERT INTO foo (bar) -SELECT 1, $1, $2; +SELECT 1, $1, $2; \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/schema.sql b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/schema.sql new file mode 100644 index 0000000000..be35e943bd --- /dev/null +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (bar text); \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/sqlc.json b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/sqlc.json index 6645ccbd1b..32ede07158 100644 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/sqlc.json +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v5", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr.txt index 063b2a149a..8463ed03b8 100644 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr.txt +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr.txt @@ -1,2 +1,5 @@ # package querytest -query.sql:4:1: INSERT has more expressions than target columns +query.sql:1:1: INSERT has more expressions than target columns +--- +# package querytest +query.sql:3:11: INSERT has more expressions than target columns \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/query.sql b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/query.sql index 41b0289d23..fad60fef89 100644 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/query.sql +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/query.sql @@ -1,5 +1,3 @@ -CREATE TABLE foo (bar text); - -- name: InsertFoo :exec INSERT INTO foo (bar) -SELECT 1, $1, $2; +SELECT 1, $1, $2; \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/schema.sql b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/schema.sql new file mode 100644 index 0000000000..be35e943bd --- /dev/null +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (bar text); \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/sqlc.json b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/sqlc.json index de427d069f..cd518671ac 100644 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/sqlc.json +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/sqlc.json @@ -5,7 +5,7 @@ "engine": "postgresql", "path": "go", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr.txt index 063b2a149a..3f3bfe37f5 100644 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr.txt +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr.txt @@ -1,2 +1,5 @@ # package querytest -query.sql:4:1: INSERT has more expressions than target columns +query.sql:1:1: INSERT has more expressions than target columns +--- +# package querytest +query.sql:3:11: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/insert_select_param/issue.md b/internal/endtoend/testdata/insert_select_param/issue.md new file mode 100644 index 0000000000..bbb421e88d --- /dev/null +++ b/internal/endtoend/testdata/insert_select_param/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1328 \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_param/postgresql/pgx/exec.json b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/db.go b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/models.go b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..b320134bd5 --- /dev/null +++ b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/models.go @@ -0,0 +1,15 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type Author struct { + ID int64 + Name string + Bio pgtype.Text +} diff --git a/internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..7bee61fcc9 --- /dev/null +++ b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/go/query.sql.go @@ -0,0 +1,29 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const insertSelect = `-- name: InsertSelect :exec +INSERT INTO authors (id, name, bio) +SELECT $1, name, bio +FROM authors +WHERE name = $2 +` + +type InsertSelectParams struct { + ID pgtype.Int8 + Name pgtype.Text +} + +func (q *Queries) InsertSelect(ctx context.Context, arg InsertSelectParams) error { + _, err := q.db.Exec(ctx, insertSelect, arg.ID, arg.Name) + return err +} diff --git a/internal/endtoend/testdata/insert_select_param/postgresql/pgx/query.sql b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/query.sql new file mode 100644 index 0000000000..ab990b0339 --- /dev/null +++ b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/query.sql @@ -0,0 +1,5 @@ +-- name: InsertSelect :exec +INSERT INTO authors (id, name, bio) +SELECT @id, name, bio +FROM authors +WHERE name = @name; \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_param/postgresql/pgx/schema.sql b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..6684317695 --- /dev/null +++ b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_param/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/insert_select_param/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_values_only/issue.md b/internal/endtoend/testdata/insert_values_only/issue.md new file mode 100644 index 0000000000..a7ea8fc1ac --- /dev/null +++ b/internal/endtoend/testdata/insert_values_only/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/938 \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_values_only/postgresql/pgx/exec.json b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/db.go b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/models.go b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..84227cc11f --- /dev/null +++ b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/models.go @@ -0,0 +1,12 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () + +type Status struct { + ID int32 + Name string +} diff --git a/internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..69ef568232 --- /dev/null +++ b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/go/query.sql.go @@ -0,0 +1,26 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const insertStatus = `-- name: InsertStatus :exec +INSERT INTO status VALUES ($1, $2) +` + +type InsertStatusParams struct { + Column1 pgtype.Int4 + Column2 pgtype.Text +} + +func (q *Queries) InsertStatus(ctx context.Context, arg InsertStatusParams) error { + _, err := q.db.Exec(ctx, insertStatus, arg.Column1, arg.Column2) + return err +} diff --git a/internal/endtoend/testdata/insert_values_only/postgresql/pgx/query.sql b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/query.sql new file mode 100644 index 0000000000..97313e7b17 --- /dev/null +++ b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/query.sql @@ -0,0 +1,2 @@ +-- name: InsertStatus :exec +INSERT INTO status VALUES ($1, $2); \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_values_only/postgresql/pgx/schema.sql b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..fc8f305d1e --- /dev/null +++ b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/schema.sql @@ -0,0 +1,6 @@ +CREATE TABLE status +( + id integer, + name varchar(100) NOT NULL, + PRIMARY KEY(id) +); \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_values_only/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..5dc63e3f91 --- /dev/null +++ b/internal/endtoend/testdata/insert_values_only/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" diff --git a/internal/endtoend/testdata/interval/pgx/v4/exec.json b/internal/endtoend/testdata/interval/pgx/v4/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/interval/pgx/v4/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/interval/pgx/v5/exec.json b/internal/endtoend/testdata/interval/pgx/v5/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/interval/pgx/v5/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/interval/stdlib/exec.json b/internal/endtoend/testdata/interval/stdlib/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/interval/stdlib/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v4/schema.sql b/internal/endtoend/testdata/invalid_func_args/pgx/v4/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v4/sqlc.json b/internal/endtoend/testdata/invalid_func_args/pgx/v4/sqlc.json index 9403bd0279..d1244c9e7a 100644 --- a/internal/endtoend/testdata/invalid_func_args/pgx/v4/sqlc.json +++ b/internal/endtoend/testdata/invalid_func_args/pgx/v4/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v4", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr.txt b/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr.txt index 09d46d1f95..a243664087 100644 --- a/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr.txt +++ b/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr.txt @@ -1,2 +1,5 @@ # package querytest query.sql:1:8: function random(unknown) does not exist +--- +# package querytest +query.sql:1:8: function random(integer) does not exist \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v5/schema.sql b/internal/endtoend/testdata/invalid_func_args/pgx/v5/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v5/sqlc.json b/internal/endtoend/testdata/invalid_func_args/pgx/v5/sqlc.json index 6645ccbd1b..32ede07158 100644 --- a/internal/endtoend/testdata/invalid_func_args/pgx/v5/sqlc.json +++ b/internal/endtoend/testdata/invalid_func_args/pgx/v5/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v5", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr.txt b/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr.txt index 09d46d1f95..eb2957c1b9 100644 --- a/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr.txt +++ b/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr.txt @@ -1,2 +1,5 @@ # package querytest query.sql:1:8: function random(unknown) does not exist +--- +# package querytest +query.sql:1:8: function random(integer) does not exist diff --git a/internal/endtoend/testdata/invalid_func_args/stdlib/schema.sql b/internal/endtoend/testdata/invalid_func_args/stdlib/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/invalid_func_args/stdlib/sqlc.json b/internal/endtoend/testdata/invalid_func_args/stdlib/sqlc.json index ac7c2ed829..dbe55e66a6 100644 --- a/internal/endtoend/testdata/invalid_func_args/stdlib/sqlc.json +++ b/internal/endtoend/testdata/invalid_func_args/stdlib/sqlc.json @@ -4,7 +4,7 @@ { "path": "go", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_func_args/stdlib/stderr.txt b/internal/endtoend/testdata/invalid_func_args/stdlib/stderr.txt index 09d46d1f95..eb2957c1b9 100644 --- a/internal/endtoend/testdata/invalid_func_args/stdlib/stderr.txt +++ b/internal/endtoend/testdata/invalid_func_args/stdlib/stderr.txt @@ -1,2 +1,5 @@ # package querytest query.sql:1:8: function random(unknown) does not exist +--- +# package querytest +query.sql:1:8: function random(integer) does not exist diff --git a/internal/endtoend/testdata/invalid_group_by_reference/postgresql/query.sql b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/query.sql index fdfa7e4e05..8275f8cfe1 100644 --- a/internal/endtoend/testdata/invalid_group_by_reference/postgresql/query.sql +++ b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/query.sql @@ -1,10 +1,4 @@ -CREATE TABLE authors ( - id BIGSERIAL PRIMARY KEY, - name text NOT NULL, - bio text -); - -- name: ListAuthors :many SELECT * FROM authors -GROUP BY invalid_reference; +GROUP BY invalid_reference; \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_group_by_reference/postgresql/schema.sql b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/schema.sql new file mode 100644 index 0000000000..69b607d902 --- /dev/null +++ b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); diff --git a/internal/endtoend/testdata/invalid_group_by_reference/postgresql/sqlc.json b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/sqlc.json index af57681f66..a590361309 100644 --- a/internal/endtoend/testdata/invalid_group_by_reference/postgresql/sqlc.json +++ b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/sqlc.json @@ -5,7 +5,7 @@ "path": "go", "engine": "postgresql", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr.txt b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr.txt index e9dd12bc6f..3981cb4a1e 100644 --- a/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr.txt +++ b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr.txt @@ -1,2 +1,5 @@ # package querytest -query.sql:10:10: column reference "invalid_reference" not found +query.sql:4:10: column reference "invalid_reference" not found +--- +# package querytest +query.sql:4:22: column "invalid_reference" does not exist diff --git a/internal/endtoend/testdata/invalid_insert_unknown_column/issue.md b/internal/endtoend/testdata/invalid_insert_unknown_column/issue.md new file mode 100644 index 0000000000..70cc5f22a5 --- /dev/null +++ b/internal/endtoend/testdata/invalid_insert_unknown_column/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/381 diff --git a/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/db.go b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/db.go new file mode 100644 index 0000000000..bcfcc9d2f4 --- /dev/null +++ b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package db + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/models.go b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/models.go new file mode 100644 index 0000000000..62f0b05e93 --- /dev/null +++ b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/models.go @@ -0,0 +1,15 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package db + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type Author struct { + ID int64 + Name string + Bio pgtype.Text +} diff --git a/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/query.sql.go b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/query.sql.go new file mode 100644 index 0000000000..ebde66829e --- /dev/null +++ b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/db/query.sql.go @@ -0,0 +1,33 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package db + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const createAuthor = `-- name: CreateAuthor :one +INSERT INTO authors ( + name, bio, missing_column +) VALUES ( + $1, $2, true +) +RETURNING id, name, bio +` + +type CreateAuthorParams struct { + Name string + Bio pgtype.Text +} + +func (q *Queries) CreateAuthor(ctx context.Context, arg CreateAuthorParams) (Author, error) { + row := q.db.QueryRow(ctx, createAuthor, arg.Name, arg.Bio) + var i Author + err := row.Scan(&i.ID, &i.Name, &i.Bio) + return i, err +} diff --git a/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/exec.json b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/query.sql b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/query.sql new file mode 100644 index 0000000000..db75df36e8 --- /dev/null +++ b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/query.sql @@ -0,0 +1,7 @@ +-- name: CreateAuthor :one +INSERT INTO authors ( + name, bio, missing_column +) VALUES ( + $1, $2, true +) +RETURNING *; diff --git a/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/schema.sql b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..69b607d902 --- /dev/null +++ b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); diff --git a/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/sqlc.json b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/sqlc.json new file mode 100644 index 0000000000..7b7c623e56 --- /dev/null +++ b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/sqlc.json @@ -0,0 +1,19 @@ +{ + "version": "1", + "cloud": { + "project": "01HAQMMECEYQYKFJN8MP16QC41" + }, + "packages": [ + { + "path": "db", + "engine": "postgresql", + "database": { + "managed": true + }, + "sql_package": "pgx/v5", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} + diff --git a/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/stderr.txt b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/stderr.txt new file mode 100644 index 0000000000..60421d56bd --- /dev/null +++ b/internal/endtoend/testdata/invalid_insert_unknown_column/postgresql/pgx/stderr.txt @@ -0,0 +1,2 @@ +# package db +query.sql:3:14: column "missing_column" of relation "authors" does not exist \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_params/pgx/v4/query.sql b/internal/endtoend/testdata/invalid_params/pgx/v4/query.sql index e65eb9970d..8a798cbb8c 100644 --- a/internal/endtoend/testdata/invalid_params/pgx/v4/query.sql +++ b/internal/endtoend/testdata/invalid_params/pgx/v4/query.sql @@ -1,9 +1,7 @@ -CREATE TABLE bar (id serial not null); - -- name: baz :one SELECT foo FROM bar WHERE baz = $4; --- name: bar +-- name: bar :one SELECT foo FROM bar WHERE baz = $1 AND baz = $3; -- name: foo :one diff --git a/internal/endtoend/testdata/invalid_params/pgx/v4/schema.sql b/internal/endtoend/testdata/invalid_params/pgx/v4/schema.sql new file mode 100644 index 0000000000..b7ee888d47 --- /dev/null +++ b/internal/endtoend/testdata/invalid_params/pgx/v4/schema.sql @@ -0,0 +1 @@ +CREATE TABLE bar (id serial not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_params/pgx/v4/sqlc.json b/internal/endtoend/testdata/invalid_params/pgx/v4/sqlc.json index ac7c2ed829..dbe55e66a6 100644 --- a/internal/endtoend/testdata/invalid_params/pgx/v4/sqlc.json +++ b/internal/endtoend/testdata/invalid_params/pgx/v4/sqlc.json @@ -4,7 +4,7 @@ { "path": "go", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_params/pgx/v4/stderr.txt b/internal/endtoend/testdata/invalid_params/pgx/v4/stderr.txt index 722c3e2408..89d645ff49 100644 --- a/internal/endtoend/testdata/invalid_params/pgx/v4/stderr.txt +++ b/internal/endtoend/testdata/invalid_params/pgx/v4/stderr.txt @@ -1,5 +1,11 @@ # package querytest -query.sql:4:1: could not determine data type of parameter $1 -query.sql:7:1: could not determine data type of parameter $2 -query.sql:10:8: column "foo" does not exist -query.sql:13:1: could not determine data type of parameter $2 +query.sql:1:1: could not determine data type of parameter $1 +query.sql:5:1: could not determine data type of parameter $2 +query.sql:8:8: column "foo" does not exist +query.sql:11:1: could not determine data type of parameter $2 +--- +# package querytest +query.sql:2:8: column "foo" does not exist +query.sql:5:8: column "foo" does not exist +query.sql:8:8: column "foo" does not exist +query.sql:8:20: could not determine data type of parameter $3 \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_params/pgx/v5/query.sql b/internal/endtoend/testdata/invalid_params/pgx/v5/query.sql index e65eb9970d..8a798cbb8c 100644 --- a/internal/endtoend/testdata/invalid_params/pgx/v5/query.sql +++ b/internal/endtoend/testdata/invalid_params/pgx/v5/query.sql @@ -1,9 +1,7 @@ -CREATE TABLE bar (id serial not null); - -- name: baz :one SELECT foo FROM bar WHERE baz = $4; --- name: bar +-- name: bar :one SELECT foo FROM bar WHERE baz = $1 AND baz = $3; -- name: foo :one diff --git a/internal/endtoend/testdata/invalid_params/pgx/v5/schema.sql b/internal/endtoend/testdata/invalid_params/pgx/v5/schema.sql new file mode 100644 index 0000000000..b7ee888d47 --- /dev/null +++ b/internal/endtoend/testdata/invalid_params/pgx/v5/schema.sql @@ -0,0 +1 @@ +CREATE TABLE bar (id serial not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_params/pgx/v5/sqlc.json b/internal/endtoend/testdata/invalid_params/pgx/v5/sqlc.json index ac7c2ed829..dbe55e66a6 100644 --- a/internal/endtoend/testdata/invalid_params/pgx/v5/sqlc.json +++ b/internal/endtoend/testdata/invalid_params/pgx/v5/sqlc.json @@ -4,7 +4,7 @@ { "path": "go", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_params/pgx/v5/stderr.txt b/internal/endtoend/testdata/invalid_params/pgx/v5/stderr.txt index 722c3e2408..89d645ff49 100644 --- a/internal/endtoend/testdata/invalid_params/pgx/v5/stderr.txt +++ b/internal/endtoend/testdata/invalid_params/pgx/v5/stderr.txt @@ -1,5 +1,11 @@ # package querytest -query.sql:4:1: could not determine data type of parameter $1 -query.sql:7:1: could not determine data type of parameter $2 -query.sql:10:8: column "foo" does not exist -query.sql:13:1: could not determine data type of parameter $2 +query.sql:1:1: could not determine data type of parameter $1 +query.sql:5:1: could not determine data type of parameter $2 +query.sql:8:8: column "foo" does not exist +query.sql:11:1: could not determine data type of parameter $2 +--- +# package querytest +query.sql:2:8: column "foo" does not exist +query.sql:5:8: column "foo" does not exist +query.sql:8:8: column "foo" does not exist +query.sql:8:20: could not determine data type of parameter $3 \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_params/stdlib/query.sql b/internal/endtoend/testdata/invalid_params/stdlib/query.sql index e65eb9970d..8a798cbb8c 100644 --- a/internal/endtoend/testdata/invalid_params/stdlib/query.sql +++ b/internal/endtoend/testdata/invalid_params/stdlib/query.sql @@ -1,9 +1,7 @@ -CREATE TABLE bar (id serial not null); - -- name: baz :one SELECT foo FROM bar WHERE baz = $4; --- name: bar +-- name: bar :one SELECT foo FROM bar WHERE baz = $1 AND baz = $3; -- name: foo :one diff --git a/internal/endtoend/testdata/invalid_params/stdlib/schema.sql b/internal/endtoend/testdata/invalid_params/stdlib/schema.sql new file mode 100644 index 0000000000..b7ee888d47 --- /dev/null +++ b/internal/endtoend/testdata/invalid_params/stdlib/schema.sql @@ -0,0 +1 @@ +CREATE TABLE bar (id serial not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_params/stdlib/sqlc.json b/internal/endtoend/testdata/invalid_params/stdlib/sqlc.json index 9403bd0279..d1244c9e7a 100644 --- a/internal/endtoend/testdata/invalid_params/stdlib/sqlc.json +++ b/internal/endtoend/testdata/invalid_params/stdlib/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v4", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_params/stdlib/stderr.txt b/internal/endtoend/testdata/invalid_params/stdlib/stderr.txt index 722c3e2408..89d645ff49 100644 --- a/internal/endtoend/testdata/invalid_params/stdlib/stderr.txt +++ b/internal/endtoend/testdata/invalid_params/stdlib/stderr.txt @@ -1,5 +1,11 @@ # package querytest -query.sql:4:1: could not determine data type of parameter $1 -query.sql:7:1: could not determine data type of parameter $2 -query.sql:10:8: column "foo" does not exist -query.sql:13:1: could not determine data type of parameter $2 +query.sql:1:1: could not determine data type of parameter $1 +query.sql:5:1: could not determine data type of parameter $2 +query.sql:8:8: column "foo" does not exist +query.sql:11:1: could not determine data type of parameter $2 +--- +# package querytest +query.sql:2:8: column "foo" does not exist +query.sql:5:8: column "foo" does not exist +query.sql:8:8: column "foo" does not exist +query.sql:8:20: could not determine data type of parameter $3 \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_params_type_mismatch/issue.md b/internal/endtoend/testdata/invalid_params_type_mismatch/issue.md new file mode 100644 index 0000000000..93fc67215f --- /dev/null +++ b/internal/endtoend/testdata/invalid_params_type_mismatch/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/297 diff --git a/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/exec.json b/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/query.sql b/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/query.sql new file mode 100644 index 0000000000..c00d547905 --- /dev/null +++ b/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/query.sql @@ -0,0 +1,4 @@ +-- name: UpdateAuthor :exec +UPDATE authors +SET name = $1 +WHERE id = $1; diff --git a/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/schema.sql b/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..e37a99f69f --- /dev/null +++ b/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name boolean NOT NULL, + bio text +); diff --git a/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/sqlc.json b/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/sqlc.json new file mode 100644 index 0000000000..14bbe813d1 --- /dev/null +++ b/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/sqlc.json @@ -0,0 +1,13 @@ +{ + "version": "1", + "packages": [ + { + "path": "db", + "engine": "postgresql", + "sql_package": "pgx/v5", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} + diff --git a/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/stderr.txt b/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/stderr.txt new file mode 100644 index 0000000000..459c2d432f --- /dev/null +++ b/internal/endtoend/testdata/invalid_params_type_mismatch/postgresql/pgx/stderr.txt @@ -0,0 +1,2 @@ +# package db +query.sql:3:12: column "name" is of type boolean but expression is of type bigint diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/query.sql b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/query.sql index 49d9d60f1f..19aaf34061 100644 --- a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/query.sql +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/query.sql @@ -1,3 +1,5 @@ -CREATE TABLE foo (bar text not null, baz text not null); +-- name: InsertBarBaz :exec INSERT INTO foo (bar, baz) VALUES ($1); + +-- name: InsertBar :exec INSERT INTO foo (bar) VALUES ($1, $2); diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/schema.sql b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/schema.sql new file mode 100644 index 0000000000..4904704639 --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (bar text not null, baz text not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/sqlc.json b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/sqlc.json index 9403bd0279..d1244c9e7a 100644 --- a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/sqlc.json +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v4", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr.txt b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr.txt index a496038cd1..fe8035b775 100644 --- a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr.txt +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr.txt @@ -1,3 +1,7 @@ # package querytest -query.sql:2:1: INSERT has more target columns than expressions -query.sql:3:1: INSERT has more expressions than target columns +query.sql:1:1: INSERT has more target columns than expressions +query.sql:5:1: INSERT has more expressions than target columns +--- +# package querytest +query.sql:2:23: INSERT has more target columns than expressions +query.sql:5:35: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/query.sql b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/query.sql index 49d9d60f1f..ef02b5e99c 100644 --- a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/query.sql +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/query.sql @@ -1,3 +1,5 @@ -CREATE TABLE foo (bar text not null, baz text not null); +-- name: InsertBarBaz :exec INSERT INTO foo (bar, baz) VALUES ($1); -INSERT INTO foo (bar) VALUES ($1, $2); + +-- name: InsertBar :exec +INSERT INTO foo (bar) VALUES ($1, $2); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/schema.sql b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/schema.sql new file mode 100644 index 0000000000..4904704639 --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (bar text not null, baz text not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/sqlc.json b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/sqlc.json index 6645ccbd1b..32ede07158 100644 --- a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/sqlc.json +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v5", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr.txt b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr.txt index a496038cd1..fe8035b775 100644 --- a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr.txt +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr.txt @@ -1,3 +1,7 @@ # package querytest -query.sql:2:1: INSERT has more target columns than expressions -query.sql:3:1: INSERT has more expressions than target columns +query.sql:1:1: INSERT has more target columns than expressions +query.sql:5:1: INSERT has more expressions than target columns +--- +# package querytest +query.sql:2:23: INSERT has more target columns than expressions +query.sql:5:35: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_bar/stdlib/query.sql b/internal/endtoend/testdata/invalid_queries_bar/stdlib/query.sql index 49d9d60f1f..ef02b5e99c 100644 --- a/internal/endtoend/testdata/invalid_queries_bar/stdlib/query.sql +++ b/internal/endtoend/testdata/invalid_queries_bar/stdlib/query.sql @@ -1,3 +1,5 @@ -CREATE TABLE foo (bar text not null, baz text not null); +-- name: InsertBarBaz :exec INSERT INTO foo (bar, baz) VALUES ($1); -INSERT INTO foo (bar) VALUES ($1, $2); + +-- name: InsertBar :exec +INSERT INTO foo (bar) VALUES ($1, $2); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_queries_bar/stdlib/schema.sql b/internal/endtoend/testdata/invalid_queries_bar/stdlib/schema.sql new file mode 100644 index 0000000000..4904704639 --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_bar/stdlib/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (bar text not null, baz text not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_queries_bar/stdlib/sqlc.json b/internal/endtoend/testdata/invalid_queries_bar/stdlib/sqlc.json index ac7c2ed829..dbe55e66a6 100644 --- a/internal/endtoend/testdata/invalid_queries_bar/stdlib/sqlc.json +++ b/internal/endtoend/testdata/invalid_queries_bar/stdlib/sqlc.json @@ -4,7 +4,7 @@ { "path": "go", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr.txt b/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr.txt index a496038cd1..fe8035b775 100644 --- a/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr.txt +++ b/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr.txt @@ -1,3 +1,7 @@ # package querytest -query.sql:2:1: INSERT has more target columns than expressions -query.sql:3:1: INSERT has more expressions than target columns +query.sql:1:1: INSERT has more target columns than expressions +query.sql:5:1: INSERT has more expressions than target columns +--- +# package querytest +query.sql:2:23: INSERT has more target columns than expressions +query.sql:5:35: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/query.sql b/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/query.sql index ef84ae740c..0e98fb622d 100644 --- a/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/query.sql +++ b/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/query.sql @@ -1,5 +1,3 @@ -CREATE TABLE foo (id text not null); - -- name: ListFoos SELECT id FROM foo; diff --git a/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/schema.sql b/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/schema.sql new file mode 100644 index 0000000000..de835103e1 --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (id text not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/sqlc.json b/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/sqlc.json index 9403bd0279..d1244c9e7a 100644 --- a/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/sqlc.json +++ b/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v4", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/stderr.txt b/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/stderr.txt index cbe1df4446..6b0840fc37 100644 --- a/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/stderr.txt +++ b/internal/endtoend/testdata/invalid_queries_foo/pgx/v4/stderr.txt @@ -1,7 +1,7 @@ # package querytest -query.sql:4:1: invalid query comment: -- name: ListFoos -query.sql:7:1: invalid query comment: -- name: ListFoos :one :many -query.sql:10:1: invalid query type: :two -query.sql:13:1: query "DeleteFoo" specifies parameter ":one" without containing a RETURNING clause -query.sql:16:1: query "UpdateFoo" specifies parameter ":one" without containing a RETURNING clause -query.sql:19:1: query "InsertFoo" specifies parameter ":one" without containing a RETURNING clause +query.sql:1:1: invalid query comment: -- name: ListFoos +query.sql:5:1: invalid query comment: -- name: ListFoos :one :many +query.sql:8:1: invalid query type: :two +query.sql:11:1: query "DeleteFoo" specifies parameter ":one" without containing a RETURNING clause +query.sql:14:1: query "UpdateFoo" specifies parameter ":one" without containing a RETURNING clause +query.sql:17:1: query "InsertFoo" specifies parameter ":one" without containing a RETURNING clause \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/query.sql b/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/query.sql index ef84ae740c..0e98fb622d 100644 --- a/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/query.sql +++ b/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/query.sql @@ -1,5 +1,3 @@ -CREATE TABLE foo (id text not null); - -- name: ListFoos SELECT id FROM foo; diff --git a/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/schema.sql b/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/schema.sql new file mode 100644 index 0000000000..de835103e1 --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (id text not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/sqlc.json b/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/sqlc.json index 6645ccbd1b..32ede07158 100644 --- a/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/sqlc.json +++ b/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v5", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/stderr.txt b/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/stderr.txt index cbe1df4446..6b0840fc37 100644 --- a/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/stderr.txt +++ b/internal/endtoend/testdata/invalid_queries_foo/pgx/v5/stderr.txt @@ -1,7 +1,7 @@ # package querytest -query.sql:4:1: invalid query comment: -- name: ListFoos -query.sql:7:1: invalid query comment: -- name: ListFoos :one :many -query.sql:10:1: invalid query type: :two -query.sql:13:1: query "DeleteFoo" specifies parameter ":one" without containing a RETURNING clause -query.sql:16:1: query "UpdateFoo" specifies parameter ":one" without containing a RETURNING clause -query.sql:19:1: query "InsertFoo" specifies parameter ":one" without containing a RETURNING clause +query.sql:1:1: invalid query comment: -- name: ListFoos +query.sql:5:1: invalid query comment: -- name: ListFoos :one :many +query.sql:8:1: invalid query type: :two +query.sql:11:1: query "DeleteFoo" specifies parameter ":one" without containing a RETURNING clause +query.sql:14:1: query "UpdateFoo" specifies parameter ":one" without containing a RETURNING clause +query.sql:17:1: query "InsertFoo" specifies parameter ":one" without containing a RETURNING clause \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_queries_foo/stdlib/query.sql b/internal/endtoend/testdata/invalid_queries_foo/stdlib/query.sql index ef84ae740c..0e98fb622d 100644 --- a/internal/endtoend/testdata/invalid_queries_foo/stdlib/query.sql +++ b/internal/endtoend/testdata/invalid_queries_foo/stdlib/query.sql @@ -1,5 +1,3 @@ -CREATE TABLE foo (id text not null); - -- name: ListFoos SELECT id FROM foo; diff --git a/internal/endtoend/testdata/invalid_queries_foo/stdlib/schema.sql b/internal/endtoend/testdata/invalid_queries_foo/stdlib/schema.sql new file mode 100644 index 0000000000..de835103e1 --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_foo/stdlib/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (id text not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_queries_foo/stdlib/sqlc.json b/internal/endtoend/testdata/invalid_queries_foo/stdlib/sqlc.json index ac7c2ed829..dbe55e66a6 100644 --- a/internal/endtoend/testdata/invalid_queries_foo/stdlib/sqlc.json +++ b/internal/endtoend/testdata/invalid_queries_foo/stdlib/sqlc.json @@ -4,7 +4,7 @@ { "path": "go", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_queries_foo/stdlib/stderr.txt b/internal/endtoend/testdata/invalid_queries_foo/stdlib/stderr.txt index cbe1df4446..6b0840fc37 100644 --- a/internal/endtoend/testdata/invalid_queries_foo/stdlib/stderr.txt +++ b/internal/endtoend/testdata/invalid_queries_foo/stdlib/stderr.txt @@ -1,7 +1,7 @@ # package querytest -query.sql:4:1: invalid query comment: -- name: ListFoos -query.sql:7:1: invalid query comment: -- name: ListFoos :one :many -query.sql:10:1: invalid query type: :two -query.sql:13:1: query "DeleteFoo" specifies parameter ":one" without containing a RETURNING clause -query.sql:16:1: query "UpdateFoo" specifies parameter ":one" without containing a RETURNING clause -query.sql:19:1: query "InsertFoo" specifies parameter ":one" without containing a RETURNING clause +query.sql:1:1: invalid query comment: -- name: ListFoos +query.sql:5:1: invalid query comment: -- name: ListFoos :one :many +query.sql:8:1: invalid query type: :two +query.sql:11:1: query "DeleteFoo" specifies parameter ":one" without containing a RETURNING clause +query.sql:14:1: query "UpdateFoo" specifies parameter ":one" without containing a RETURNING clause +query.sql:17:1: query "InsertFoo" specifies parameter ":one" without containing a RETURNING clause \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_table_alias/postgresql/query.sql b/internal/endtoend/testdata/invalid_table_alias/postgresql/query.sql index 76e872ab65..f09a94b585 100644 --- a/internal/endtoend/testdata/invalid_table_alias/postgresql/query.sql +++ b/internal/endtoend/testdata/invalid_table_alias/postgresql/query.sql @@ -1,10 +1,3 @@ --- https://github.com/sqlc-dev/sqlc/issues/437 -CREATE TABLE authors ( - id BIGSERIAL PRIMARY KEY, - name text NOT NULL, - bio text -); - -- name: GetAuthor :one SELECT * FROM authors a diff --git a/internal/endtoend/testdata/invalid_table_alias/postgresql/schema.sql b/internal/endtoend/testdata/invalid_table_alias/postgresql/schema.sql new file mode 100644 index 0000000000..9c4b796adb --- /dev/null +++ b/internal/endtoend/testdata/invalid_table_alias/postgresql/schema.sql @@ -0,0 +1,6 @@ +-- https://github.com/sqlc-dev/sqlc/issues/437 +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_table_alias/postgresql/sqlc.json b/internal/endtoend/testdata/invalid_table_alias/postgresql/sqlc.json index af57681f66..a590361309 100644 --- a/internal/endtoend/testdata/invalid_table_alias/postgresql/sqlc.json +++ b/internal/endtoend/testdata/invalid_table_alias/postgresql/sqlc.json @@ -5,7 +5,7 @@ "path": "go", "engine": "postgresql", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr.txt b/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr.txt index 810c893a70..896058296f 100644 --- a/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr.txt +++ b/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr.txt @@ -1,2 +1,5 @@ # package querytest -query.sql:11:9: table alias "p" does not exist +query.sql:4:9: table alias "p" does not exist +--- +# package querytest +query.sql:5:3: missing FROM-clause entry for table "p" diff --git a/internal/endtoend/testdata/invalid_update_unknown_column/issue.md b/internal/endtoend/testdata/invalid_update_unknown_column/issue.md new file mode 100644 index 0000000000..822c605060 --- /dev/null +++ b/internal/endtoend/testdata/invalid_update_unknown_column/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/884 \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/exec.json b/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/query.sql b/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/query.sql new file mode 100644 index 0000000000..59d42df34b --- /dev/null +++ b/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/query.sql @@ -0,0 +1,7 @@ +-- name: UpdateArticles :exec +UPDATE + public.articles +SET + is_deleted = TRUE +WHERE + id = $1; \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/schema.sql b/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..6f94b60c66 --- /dev/null +++ b/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE public.articles ( + id integer NOT NULL, + company integer NOT NULL, + name text NOT NULL, + sort_order integer DEFAULT 0 NOT NULL, + object_type smallint NOT NULL, + image text, + "group" integer, + notes text DEFAULT ''::text NOT NULL +); \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/stderr.txt b/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/stderr.txt new file mode 100644 index 0000000000..8260c8f792 --- /dev/null +++ b/internal/endtoend/testdata/invalid_update_unknown_column/postgresql/pgx/stderr.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:5:2: column "is_deleted" of relation "articles" does not exist \ No newline at end of file diff --git a/internal/endtoend/testdata/join_left/postgresql/exec.json b/internal/endtoend/testdata/join_left/postgresql/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/join_left/postgresql/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/join_validate_columns/issue.md b/internal/endtoend/testdata/join_validate_columns/issue.md new file mode 100644 index 0000000000..0050218dca --- /dev/null +++ b/internal/endtoend/testdata/join_validate_columns/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1239 \ No newline at end of file diff --git a/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/exec.json b/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/query.sql b/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/query.sql new file mode 100644 index 0000000000..8fe51af829 --- /dev/null +++ b/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/query.sql @@ -0,0 +1,2 @@ +-- name: ListAuthors :many +SELECT * FROM authors JOIN books ON authors.id = book.author_id1; \ No newline at end of file diff --git a/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/schema.sql b/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..d322893016 --- /dev/null +++ b/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL +); + +CREATE TABLE books ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + author_id BIGSERIAL REFERENCES authors(id) +); \ No newline at end of file diff --git a/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..5dc63e3f91 --- /dev/null +++ b/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" diff --git a/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/stderr.txt b/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/stderr.txt new file mode 100644 index 0000000000..0dfd315960 --- /dev/null +++ b/internal/endtoend/testdata/join_validate_columns/postgresql/pgx/stderr.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:2:65: missing FROM-clause entry for table "book" \ No newline at end of file diff --git a/internal/endtoend/testdata/json_param_type/issue.md b/internal/endtoend/testdata/json_param_type/issue.md new file mode 100644 index 0000000000..a04d7dab14 --- /dev/null +++ b/internal/endtoend/testdata/json_param_type/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/743 \ No newline at end of file diff --git a/internal/endtoend/testdata/json_param_type/postgresql/pgx/exec.json b/internal/endtoend/testdata/json_param_type/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/json_param_type/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/json_param_type/postgresql/pgx/go/db.go b/internal/endtoend/testdata/json_param_type/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/json_param_type/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/json_param_type/postgresql/pgx/go/models.go b/internal/endtoend/testdata/json_param_type/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..ecdaf1e0a2 --- /dev/null +++ b/internal/endtoend/testdata/json_param_type/postgresql/pgx/go/models.go @@ -0,0 +1,12 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () + +type User struct { + ID int32 + Metadata []byte +} diff --git a/internal/endtoend/testdata/json_param_type/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/json_param_type/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..850280d5b2 --- /dev/null +++ b/internal/endtoend/testdata/json_param_type/postgresql/pgx/go/query.sql.go @@ -0,0 +1,23 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const findByAddress = `-- name: FindByAddress :one +SELECT id, metadata FROM "user" WHERE "metadata"->>'address1' = $1 LIMIT 1 +` + +func (q *Queries) FindByAddress(ctx context.Context, metadata pgtype.Text) (User, error) { + row := q.db.QueryRow(ctx, findByAddress, metadata) + var i User + err := row.Scan(&i.ID, &i.Metadata) + return i, err +} diff --git a/internal/endtoend/testdata/json_param_type/postgresql/pgx/query.sql b/internal/endtoend/testdata/json_param_type/postgresql/pgx/query.sql new file mode 100644 index 0000000000..61da05b8ec --- /dev/null +++ b/internal/endtoend/testdata/json_param_type/postgresql/pgx/query.sql @@ -0,0 +1,2 @@ +-- name: FindByAddress :one +SELECT * FROM "user" WHERE "metadata"->>'address1' = $1 LIMIT 1; diff --git a/internal/endtoend/testdata/json_param_type/postgresql/pgx/schema.sql b/internal/endtoend/testdata/json_param_type/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..9d2499cf7c --- /dev/null +++ b/internal/endtoend/testdata/json_param_type/postgresql/pgx/schema.sql @@ -0,0 +1,4 @@ +CREATE TABLE "user" ( + "id" INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + "metadata" JSONB +); diff --git a/internal/endtoend/testdata/json_param_type/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/json_param_type/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/json_param_type/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/limit/pgx/v4/exec.json b/internal/endtoend/testdata/limit/pgx/v4/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/limit/pgx/v4/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/limit/pgx/v5/exec.json b/internal/endtoend/testdata/limit/pgx/v5/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/limit/pgx/v5/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/limit/stdlib/exec.json b/internal/endtoend/testdata/limit/stdlib/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/limit/stdlib/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/missing_semicolon/pgx/v4/query.sql b/internal/endtoend/testdata/missing_semicolon/pgx/v4/query.sql index cdd62d5ad7..80c83545ce 100644 --- a/internal/endtoend/testdata/missing_semicolon/pgx/v4/query.sql +++ b/internal/endtoend/testdata/missing_semicolon/pgx/v4/query.sql @@ -1,5 +1,3 @@ -CREATE TABLE foo (email text not null); - -- name: FirstQuery :many SELECT * FROM foo; diff --git a/internal/endtoend/testdata/missing_semicolon/pgx/v4/schema.sql b/internal/endtoend/testdata/missing_semicolon/pgx/v4/schema.sql new file mode 100644 index 0000000000..e2b1d89074 --- /dev/null +++ b/internal/endtoend/testdata/missing_semicolon/pgx/v4/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (email text not null); diff --git a/internal/endtoend/testdata/missing_semicolon/pgx/v4/sqlc.json b/internal/endtoend/testdata/missing_semicolon/pgx/v4/sqlc.json index 9403bd0279..d1244c9e7a 100644 --- a/internal/endtoend/testdata/missing_semicolon/pgx/v4/sqlc.json +++ b/internal/endtoend/testdata/missing_semicolon/pgx/v4/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v4", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/missing_semicolon/pgx/v4/stderr.txt b/internal/endtoend/testdata/missing_semicolon/pgx/v4/stderr.txt index 5cd2f160b8..7544904cf6 100644 --- a/internal/endtoend/testdata/missing_semicolon/pgx/v4/stderr.txt +++ b/internal/endtoend/testdata/missing_semicolon/pgx/v4/stderr.txt @@ -1,2 +1,2 @@ # package querytest -query.sql:7:1: missing semicolon at end of file +query.sql:5:1: missing semicolon at end of file diff --git a/internal/endtoend/testdata/missing_semicolon/pgx/v5/query.sql b/internal/endtoend/testdata/missing_semicolon/pgx/v5/query.sql index cdd62d5ad7..80c83545ce 100644 --- a/internal/endtoend/testdata/missing_semicolon/pgx/v5/query.sql +++ b/internal/endtoend/testdata/missing_semicolon/pgx/v5/query.sql @@ -1,5 +1,3 @@ -CREATE TABLE foo (email text not null); - -- name: FirstQuery :many SELECT * FROM foo; diff --git a/internal/endtoend/testdata/missing_semicolon/pgx/v5/schema.sql b/internal/endtoend/testdata/missing_semicolon/pgx/v5/schema.sql new file mode 100644 index 0000000000..28f5b2d13e --- /dev/null +++ b/internal/endtoend/testdata/missing_semicolon/pgx/v5/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (email text not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/missing_semicolon/pgx/v5/sqlc.json b/internal/endtoend/testdata/missing_semicolon/pgx/v5/sqlc.json index 6645ccbd1b..32ede07158 100644 --- a/internal/endtoend/testdata/missing_semicolon/pgx/v5/sqlc.json +++ b/internal/endtoend/testdata/missing_semicolon/pgx/v5/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v5", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/missing_semicolon/pgx/v5/stderr.txt b/internal/endtoend/testdata/missing_semicolon/pgx/v5/stderr.txt index 5cd2f160b8..7544904cf6 100644 --- a/internal/endtoend/testdata/missing_semicolon/pgx/v5/stderr.txt +++ b/internal/endtoend/testdata/missing_semicolon/pgx/v5/stderr.txt @@ -1,2 +1,2 @@ # package querytest -query.sql:7:1: missing semicolon at end of file +query.sql:5:1: missing semicolon at end of file diff --git a/internal/endtoend/testdata/missing_semicolon/stdlib/query.sql b/internal/endtoend/testdata/missing_semicolon/stdlib/query.sql index cdd62d5ad7..80c83545ce 100644 --- a/internal/endtoend/testdata/missing_semicolon/stdlib/query.sql +++ b/internal/endtoend/testdata/missing_semicolon/stdlib/query.sql @@ -1,5 +1,3 @@ -CREATE TABLE foo (email text not null); - -- name: FirstQuery :many SELECT * FROM foo; diff --git a/internal/endtoend/testdata/missing_semicolon/stdlib/schema.sql b/internal/endtoend/testdata/missing_semicolon/stdlib/schema.sql new file mode 100644 index 0000000000..28f5b2d13e --- /dev/null +++ b/internal/endtoend/testdata/missing_semicolon/stdlib/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (email text not null); \ No newline at end of file diff --git a/internal/endtoend/testdata/missing_semicolon/stdlib/sqlc.json b/internal/endtoend/testdata/missing_semicolon/stdlib/sqlc.json index ac7c2ed829..dbe55e66a6 100644 --- a/internal/endtoend/testdata/missing_semicolon/stdlib/sqlc.json +++ b/internal/endtoend/testdata/missing_semicolon/stdlib/sqlc.json @@ -4,7 +4,7 @@ { "path": "go", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/missing_semicolon/stdlib/stderr.txt b/internal/endtoend/testdata/missing_semicolon/stdlib/stderr.txt index 5cd2f160b8..7544904cf6 100644 --- a/internal/endtoend/testdata/missing_semicolon/stdlib/stderr.txt +++ b/internal/endtoend/testdata/missing_semicolon/stdlib/stderr.txt @@ -1,2 +1,2 @@ # package querytest -query.sql:7:1: missing semicolon at end of file +query.sql:5:1: missing semicolon at end of file diff --git a/internal/endtoend/testdata/mix_param_types/postgresql/exec.json b/internal/endtoend/testdata/mix_param_types/postgresql/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/mix_param_types/postgresql/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/nested_select/issue.md b/internal/endtoend/testdata/nested_select/issue.md new file mode 100644 index 0000000000..2c10d6d8fe --- /dev/null +++ b/internal/endtoend/testdata/nested_select/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/708 diff --git a/internal/endtoend/testdata/nested_select/postgresql/pgx/exec.json b/internal/endtoend/testdata/nested_select/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/nested_select/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/nested_select/postgresql/pgx/go/db.go b/internal/endtoend/testdata/nested_select/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/nested_select/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/nested_select/postgresql/pgx/go/models.go b/internal/endtoend/testdata/nested_select/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..3cb0ee9c81 --- /dev/null +++ b/internal/endtoend/testdata/nested_select/postgresql/pgx/go/models.go @@ -0,0 +1,13 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () + +type Test struct { + ID int64 + UpdateTime int64 + Count int64 +} diff --git a/internal/endtoend/testdata/nested_select/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/nested_select/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..2a46b8800d --- /dev/null +++ b/internal/endtoend/testdata/nested_select/postgresql/pgx/go/query.sql.go @@ -0,0 +1,42 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const nestedSelect = `-- name: NestedSelect :one +SELECT latest.id, t.count +FROM ( + SELECT id, max(update_time) AS update_time + FROM test + WHERE id = ANY ($1::bigint[]) + -- ERROR HERE on update_time + AND update_time >= $2 + GROUP BY id +) latest +INNER JOIN test t USING (id, update_time) +` + +type NestedSelectParams struct { + IDs []int64 + StartTime pgtype.Int8 +} + +type NestedSelectRow struct { + ID int64 + Count int64 +} + +func (q *Queries) NestedSelect(ctx context.Context, arg NestedSelectParams) (NestedSelectRow, error) { + row := q.db.QueryRow(ctx, nestedSelect, arg.IDs, arg.StartTime) + var i NestedSelectRow + err := row.Scan(&i.ID, &i.Count) + return i, err +} diff --git a/internal/endtoend/testdata/nested_select/postgresql/pgx/query.sql b/internal/endtoend/testdata/nested_select/postgresql/pgx/query.sql new file mode 100644 index 0000000000..755521fa4a --- /dev/null +++ b/internal/endtoend/testdata/nested_select/postgresql/pgx/query.sql @@ -0,0 +1,11 @@ +-- name: NestedSelect :one +SELECT latest.id, t.count +FROM ( + SELECT id, max(update_time) AS update_time + FROM test + WHERE id = ANY (sqlc.arg('IDs')::bigint[]) + -- ERROR HERE on update_time + AND update_time >= sqlc.arg('StartTime') + GROUP BY id +) latest +INNER JOIN test t USING (id, update_time); diff --git a/internal/endtoend/testdata/nested_select/postgresql/pgx/schema.sql b/internal/endtoend/testdata/nested_select/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..02f5f8203c --- /dev/null +++ b/internal/endtoend/testdata/nested_select/postgresql/pgx/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE test ( + id bigint NOT NULL, + update_time bigint NOT NULL, + count bigint NOT NULL +); diff --git a/internal/endtoend/testdata/nested_select/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/nested_select/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..2f12715923 --- /dev/null +++ b/internal/endtoend/testdata/nested_select/postgresql/pgx/sqlc.yaml @@ -0,0 +1,14 @@ +version: "2" +cloud: + project: "01HAQMMECEYQYKFJN8MP16QC41" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" + database: + managed: true diff --git a/internal/endtoend/testdata/null_if_type/issue.md b/internal/endtoend/testdata/null_if_type/issue.md new file mode 100644 index 0000000000..c83cc42660 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/133 diff --git a/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/db.go b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/db.go new file mode 100644 index 0000000000..3d2b5bf3a3 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package db + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/models.go b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/models.go new file mode 100644 index 0000000000..e3c353f521 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/models.go @@ -0,0 +1,11 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package db + +import () + +type Author struct { + ID int64 +} diff --git a/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/query.sql.go b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/query.sql.go new file mode 100644 index 0000000000..62a6229d99 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/db/query.sql.go @@ -0,0 +1,24 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package db + +import ( + "context" +) + +const getRestrictedId = `-- name: GetRestrictedId :one +SELECT + NULLIF(id, $1) restricted_id +FROM + author +` + +func (q *Queries) GetRestrictedId(ctx context.Context, id int64) (int64, error) { + row := q.db.QueryRowContext(ctx, getRestrictedId, id) + var restricted_id int64 + err := row.Scan(&restricted_id) + return restricted_id, err +} diff --git a/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/exec.json b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/query.sql b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/query.sql new file mode 100644 index 0000000000..fc800b4f6d --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/query.sql @@ -0,0 +1,5 @@ +-- name: GetRestrictedId :one +SELECT + NULLIF(id, $1) restricted_id +FROM + author; diff --git a/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/schema.sql b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/schema.sql new file mode 100644 index 0000000000..c1afecad09 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/schema.sql @@ -0,0 +1,3 @@ +CREATE TABLE author ( + id bigserial NOT NULL +); diff --git a/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/sqlc.json b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/sqlc.json new file mode 100644 index 0000000000..a682c52d42 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/pganalyzer/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "db", + "engine": "postgresql", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} + diff --git a/internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/db.go b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/db.go new file mode 100644 index 0000000000..3d2b5bf3a3 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package db + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/models.go b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/models.go new file mode 100644 index 0000000000..e3c353f521 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/models.go @@ -0,0 +1,11 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package db + +import () + +type Author struct { + ID int64 +} diff --git a/internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/query.sql.go b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/query.sql.go new file mode 100644 index 0000000000..0c377bcb16 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/db/query.sql.go @@ -0,0 +1,24 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package db + +import ( + "context" +) + +const getRestrictedId = `-- name: GetRestrictedId :one +SELECT + NULLIF(id, $1) restricted_id +FROM + author +` + +func (q *Queries) GetRestrictedId(ctx context.Context, id int64) (bool, error) { + row := q.db.QueryRowContext(ctx, getRestrictedId, id) + var restricted_id bool + err := row.Scan(&restricted_id) + return restricted_id, err +} diff --git a/internal/endtoend/testdata/null_if_type/postgresql/stdlib/exec.json b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/null_if_type/postgresql/stdlib/query.sql b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/query.sql new file mode 100644 index 0000000000..fc800b4f6d --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/query.sql @@ -0,0 +1,5 @@ +-- name: GetRestrictedId :one +SELECT + NULLIF(id, $1) restricted_id +FROM + author; diff --git a/internal/endtoend/testdata/null_if_type/postgresql/stdlib/schema.sql b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/schema.sql new file mode 100644 index 0000000000..c1afecad09 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/schema.sql @@ -0,0 +1,3 @@ +CREATE TABLE author ( + id bigserial NOT NULL +); diff --git a/internal/endtoend/testdata/null_if_type/postgresql/stdlib/sqlc.json b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/sqlc.json new file mode 100644 index 0000000000..a682c52d42 --- /dev/null +++ b/internal/endtoend/testdata/null_if_type/postgresql/stdlib/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "db", + "engine": "postgresql", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} + diff --git a/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v4/go/query.sql.go index 6b8e361255..5225c21e02 100644 --- a/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v4/go/query.sql.go +++ b/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v4/go/query.sql.go @@ -7,27 +7,14 @@ package querytest import ( "context" - "database/sql" ) -const test = `-- name: Test :one -select txt from Demo -where txt ~~ '%' || $1 || '%' -` - -func (q *Queries) Test(ctx context.Context, val string) (string, error) { - row := q.db.QueryRow(ctx, test, val) - var txt string - err := row.Scan(&txt) - return txt, err -} - const test2 = `-- name: Test2 :one select txt from Demo -where txt like '%' || $1 || '%' +where txt like '%' || $1::text || '%' ` -func (q *Queries) Test2(ctx context.Context, val sql.NullString) (string, error) { +func (q *Queries) Test2(ctx context.Context, val string) (string, error) { row := q.db.QueryRow(ctx, test2, val) var txt string err := row.Scan(&txt) @@ -36,10 +23,10 @@ func (q *Queries) Test2(ctx context.Context, val sql.NullString) (string, error) const test3 = `-- name: Test3 :one select txt from Demo -where txt like concat('%', $1, '%') +where txt like concat('%', $1::text, '%') ` -func (q *Queries) Test3(ctx context.Context, val interface{}) (string, error) { +func (q *Queries) Test3(ctx context.Context, val string) (string, error) { row := q.db.QueryRow(ctx, test3, val) var txt string err := row.Scan(&txt) diff --git a/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v4/query.sql index c4a088508c..3133d4c299 100644 --- a/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v4/query.sql +++ b/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v4/query.sql @@ -1,11 +1,7 @@ --- name: Test :one -select * from Demo -where txt ~~ '%' || sqlc.arg('val') || '%'; - -- name: Test2 :one select * from Demo -where txt like '%' || sqlc.arg('val') || '%'; +where txt like '%' || sqlc.arg('val')::text || '%'; -- name: Test3 :one select * from Demo -where txt like concat('%', sqlc.arg('val'), '%'); +where txt like concat('%', sqlc.arg('val')::text, '%'); diff --git a/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v5/go/query.sql.go index 33d2f3cefc..5225c21e02 100644 --- a/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v5/go/query.sql.go @@ -7,28 +7,14 @@ package querytest import ( "context" - - "github.com/jackc/pgx/v5/pgtype" ) -const test = `-- name: Test :one -select txt from Demo -where txt ~~ '%' || $1 || '%' -` - -func (q *Queries) Test(ctx context.Context, val string) (string, error) { - row := q.db.QueryRow(ctx, test, val) - var txt string - err := row.Scan(&txt) - return txt, err -} - const test2 = `-- name: Test2 :one select txt from Demo -where txt like '%' || $1 || '%' +where txt like '%' || $1::text || '%' ` -func (q *Queries) Test2(ctx context.Context, val pgtype.Text) (string, error) { +func (q *Queries) Test2(ctx context.Context, val string) (string, error) { row := q.db.QueryRow(ctx, test2, val) var txt string err := row.Scan(&txt) @@ -37,10 +23,10 @@ func (q *Queries) Test2(ctx context.Context, val pgtype.Text) (string, error) { const test3 = `-- name: Test3 :one select txt from Demo -where txt like concat('%', $1, '%') +where txt like concat('%', $1::text, '%') ` -func (q *Queries) Test3(ctx context.Context, val interface{}) (string, error) { +func (q *Queries) Test3(ctx context.Context, val string) (string, error) { row := q.db.QueryRow(ctx, test3, val) var txt string err := row.Scan(&txt) diff --git a/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v5/query.sql index c4a088508c..3133d4c299 100644 --- a/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v5/query.sql +++ b/internal/endtoend/testdata/operator_string_concat/postgresql/pgx/v5/query.sql @@ -1,11 +1,7 @@ --- name: Test :one -select * from Demo -where txt ~~ '%' || sqlc.arg('val') || '%'; - -- name: Test2 :one select * from Demo -where txt like '%' || sqlc.arg('val') || '%'; +where txt like '%' || sqlc.arg('val')::text || '%'; -- name: Test3 :one select * from Demo -where txt like concat('%', sqlc.arg('val'), '%'); +where txt like concat('%', sqlc.arg('val')::text, '%'); diff --git a/internal/endtoend/testdata/operator_string_concat/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/operator_string_concat/postgresql/stdlib/go/query.sql.go index de8b4f6f9c..0b72579e02 100644 --- a/internal/endtoend/testdata/operator_string_concat/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/operator_string_concat/postgresql/stdlib/go/query.sql.go @@ -7,27 +7,14 @@ package querytest import ( "context" - "database/sql" ) -const test = `-- name: Test :one -select txt from Demo -where txt ~~ '%' || $1 || '%' -` - -func (q *Queries) Test(ctx context.Context, val string) (string, error) { - row := q.db.QueryRowContext(ctx, test, val) - var txt string - err := row.Scan(&txt) - return txt, err -} - const test2 = `-- name: Test2 :one select txt from Demo -where txt like '%' || $1 || '%' +where txt like '%' || $1::text || '%' ` -func (q *Queries) Test2(ctx context.Context, val sql.NullString) (string, error) { +func (q *Queries) Test2(ctx context.Context, val string) (string, error) { row := q.db.QueryRowContext(ctx, test2, val) var txt string err := row.Scan(&txt) @@ -36,10 +23,10 @@ func (q *Queries) Test2(ctx context.Context, val sql.NullString) (string, error) const test3 = `-- name: Test3 :one select txt from Demo -where txt like concat('%', $1, '%') +where txt like concat('%', $1::text, '%') ` -func (q *Queries) Test3(ctx context.Context, val interface{}) (string, error) { +func (q *Queries) Test3(ctx context.Context, val string) (string, error) { row := q.db.QueryRowContext(ctx, test3, val) var txt string err := row.Scan(&txt) diff --git a/internal/endtoend/testdata/operator_string_concat/postgresql/stdlib/query.sql b/internal/endtoend/testdata/operator_string_concat/postgresql/stdlib/query.sql index c4a088508c..3133d4c299 100644 --- a/internal/endtoend/testdata/operator_string_concat/postgresql/stdlib/query.sql +++ b/internal/endtoend/testdata/operator_string_concat/postgresql/stdlib/query.sql @@ -1,11 +1,7 @@ --- name: Test :one -select * from Demo -where txt ~~ '%' || sqlc.arg('val') || '%'; - -- name: Test2 :one select * from Demo -where txt like '%' || sqlc.arg('val') || '%'; +where txt like '%' || sqlc.arg('val')::text || '%'; -- name: Test3 :one select * from Demo -where txt like concat('%', sqlc.arg('val'), '%'); +where txt like concat('%', sqlc.arg('val')::text, '%'); diff --git a/internal/endtoend/testdata/order_by_binds/pganalyze/exec.json b/internal/endtoend/testdata/order_by_binds/pganalyze/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/order_by_binds/pganalyze/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/order_by_binds/pganalyze/go/db.go b/internal/endtoend/testdata/order_by_binds/pganalyze/go/db.go new file mode 100644 index 0000000000..a457fb76b2 --- /dev/null +++ b/internal/endtoend/testdata/order_by_binds/pganalyze/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/func_return/postgresql/stdlib/go/models.go b/internal/endtoend/testdata/order_by_binds/pganalyze/go/models.go similarity index 64% rename from internal/endtoend/testdata/func_return/postgresql/stdlib/go/models.go rename to internal/endtoend/testdata/order_by_binds/pganalyze/go/models.go index 18a0ebb3e7..2727f2e2de 100644 --- a/internal/endtoend/testdata/func_return/postgresql/stdlib/go/models.go +++ b/internal/endtoend/testdata/order_by_binds/pganalyze/go/models.go @@ -8,7 +8,8 @@ import ( "database/sql" ) -type User struct { - ID sql.NullInt32 - FirstName string +type Author struct { + ID int64 + Name string + Bio sql.NullString } diff --git a/internal/endtoend/testdata/order_by_binds/pganalyze/go/query.sql.go b/internal/endtoend/testdata/order_by_binds/pganalyze/go/query.sql.go new file mode 100644 index 0000000000..f3d1c12b6c --- /dev/null +++ b/internal/endtoend/testdata/order_by_binds/pganalyze/go/query.sql.go @@ -0,0 +1,74 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + "database/sql" +) + +const listAuthorsColumnSort = `-- name: ListAuthorsColumnSort :many +SELECT id, name, bio FROM authors +WHERE id > $1 +ORDER BY CASE WHEN $2 = 'name' THEN name END +` + +type ListAuthorsColumnSortParams struct { + MinID int64 + SortColumn sql.NullString +} + +func (q *Queries) ListAuthorsColumnSort(ctx context.Context, arg ListAuthorsColumnSortParams) ([]Author, error) { + rows, err := q.db.QueryContext(ctx, listAuthorsColumnSort, arg.MinID, arg.SortColumn) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Author + for rows.Next() { + var i Author + if err := rows.Scan(&i.ID, &i.Name, &i.Bio); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listAuthorsNameSort = `-- name: ListAuthorsNameSort :many +SELECT id, name, bio FROM authors +WHERE id > $1 +ORDER BY name ASC +` + +func (q *Queries) ListAuthorsNameSort(ctx context.Context, minID int64) ([]Author, error) { + rows, err := q.db.QueryContext(ctx, listAuthorsNameSort, minID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Author + for rows.Next() { + var i Author + if err := rows.Scan(&i.ID, &i.Name, &i.Bio); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/order_by_binds/pganalyze/query.sql b/internal/endtoend/testdata/order_by_binds/pganalyze/query.sql new file mode 100644 index 0000000000..e662d8f06a --- /dev/null +++ b/internal/endtoend/testdata/order_by_binds/pganalyze/query.sql @@ -0,0 +1,9 @@ +-- name: ListAuthorsColumnSort :many +SELECT * FROM authors +WHERE id > sqlc.arg(min_id) +ORDER BY CASE WHEN sqlc.arg(sort_column) = 'name' THEN name END; + +-- name: ListAuthorsNameSort :many +SELECT * FROM authors +WHERE id > sqlc.arg(min_id) +ORDER BY name ASC; diff --git a/internal/endtoend/testdata/order_by_binds/pganalyze/schema.sql b/internal/endtoend/testdata/order_by_binds/pganalyze/schema.sql new file mode 100644 index 0000000000..f388f86c34 --- /dev/null +++ b/internal/endtoend/testdata/order_by_binds/pganalyze/schema.sql @@ -0,0 +1,6 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); + diff --git a/internal/endtoend/testdata/order_by_binds/pganalyze/sqlc.json b/internal/endtoend/testdata/order_by_binds/pganalyze/sqlc.json new file mode 100644 index 0000000000..a590361309 --- /dev/null +++ b/internal/endtoend/testdata/order_by_binds/pganalyze/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "name": "querytest", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/order_by_binds/postgresql/exec.json b/internal/endtoend/testdata/order_by_binds/postgresql/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/order_by_binds/postgresql/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/order_by_non_existing_column/mysql/query.sql b/internal/endtoend/testdata/order_by_non_existing_column/mysql/query.sql deleted file mode 100644 index b1a4b4f638..0000000000 --- a/internal/endtoend/testdata/order_by_non_existing_column/mysql/query.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Example queries for sqlc -CREATE TABLE authors ( - id INT -); - --- name: ListAuthors :many -SELECT id FROM authors -ORDER BY adfadsf; \ No newline at end of file diff --git a/internal/endtoend/testdata/order_by_non_existing_column/mysql/sqlc.yaml b/internal/endtoend/testdata/order_by_non_existing_column/mysql/sqlc.yaml deleted file mode 100644 index c4b3831631..0000000000 --- a/internal/endtoend/testdata/order_by_non_existing_column/mysql/sqlc.yaml +++ /dev/null @@ -1,7 +0,0 @@ -version: 1 -packages: - - path: "go" - name: "querytest" - engine: "postgresql" - schema: "query.sql" - queries: "query.sql" \ No newline at end of file diff --git a/internal/endtoend/testdata/order_by_non_existing_column/mysql/stderr.txt b/internal/endtoend/testdata/order_by_non_existing_column/mysql/stderr.txt deleted file mode 100644 index 166178156e..0000000000 --- a/internal/endtoend/testdata/order_by_non_existing_column/mysql/stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -# package querytest -query.sql:7:1: column reference "adfadsf" not found: if you want to skip this validation, set 'strict_order_by' to false diff --git a/internal/endtoend/testdata/order_by_non_existing_column/postgresql/query.sql b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/query.sql index b1a4b4f638..ba81cfdbc5 100644 --- a/internal/endtoend/testdata/order_by_non_existing_column/postgresql/query.sql +++ b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/query.sql @@ -1,8 +1,3 @@ --- Example queries for sqlc -CREATE TABLE authors ( - id INT -); - -- name: ListAuthors :many SELECT id FROM authors ORDER BY adfadsf; \ No newline at end of file diff --git a/internal/endtoend/testdata/order_by_non_existing_column/postgresql/schema.sql b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/schema.sql new file mode 100644 index 0000000000..acba948a66 --- /dev/null +++ b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/schema.sql @@ -0,0 +1,5 @@ +-- Example queries for sqlc +CREATE TABLE authors ( + id INT +); + diff --git a/internal/endtoend/testdata/order_by_non_existing_column/postgresql/sqlc.yaml b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/sqlc.yaml index c4b3831631..9ae3fc0cae 100644 --- a/internal/endtoend/testdata/order_by_non_existing_column/postgresql/sqlc.yaml +++ b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/sqlc.yaml @@ -3,5 +3,5 @@ packages: - path: "go" name: "querytest" engine: "postgresql" - schema: "query.sql" + schema: "schema.sql" queries: "query.sql" \ No newline at end of file diff --git a/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr.txt b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr.txt index 166178156e..cfdfa539cc 100644 --- a/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr.txt +++ b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr.txt @@ -1,2 +1,5 @@ # package querytest -query.sql:7:1: column reference "adfadsf" not found: if you want to skip this validation, set 'strict_order_by' to false +query.sql:1:1: column reference "adfadsf" not found: if you want to skip this validation, set 'strict_order_by' to false +--- +# package querytest +query.sql:3:10: column "adfadsf" does not exist \ No newline at end of file diff --git a/internal/endtoend/testdata/order_by_non_existing_column/sqlite/query.sql b/internal/endtoend/testdata/order_by_non_existing_column/sqlite/query.sql deleted file mode 100644 index b1a4b4f638..0000000000 --- a/internal/endtoend/testdata/order_by_non_existing_column/sqlite/query.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Example queries for sqlc -CREATE TABLE authors ( - id INT -); - --- name: ListAuthors :many -SELECT id FROM authors -ORDER BY adfadsf; \ No newline at end of file diff --git a/internal/endtoend/testdata/order_by_non_existing_column/sqlite/sqlc.yaml b/internal/endtoend/testdata/order_by_non_existing_column/sqlite/sqlc.yaml deleted file mode 100644 index c4b3831631..0000000000 --- a/internal/endtoend/testdata/order_by_non_existing_column/sqlite/sqlc.yaml +++ /dev/null @@ -1,7 +0,0 @@ -version: 1 -packages: - - path: "go" - name: "querytest" - engine: "postgresql" - schema: "query.sql" - queries: "query.sql" \ No newline at end of file diff --git a/internal/endtoend/testdata/order_by_non_existing_column/sqlite/stderr.txt b/internal/endtoend/testdata/order_by_non_existing_column/sqlite/stderr.txt deleted file mode 100644 index 166178156e..0000000000 --- a/internal/endtoend/testdata/order_by_non_existing_column/sqlite/stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -# package querytest -query.sql:7:1: column reference "adfadsf" not found: if you want to skip this validation, set 'strict_order_by' to false diff --git a/internal/endtoend/testdata/params_location/postgresql/pgx/v4/exec.json b/internal/endtoend/testdata/params_location/postgresql/pgx/v4/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/params_location/postgresql/pgx/v4/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/params_location/postgresql/pgx/v5/exec.json b/internal/endtoend/testdata/params_location/postgresql/pgx/v5/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/params_location/postgresql/pgx/v5/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/params_location/postgresql/stdlib/exec.json b/internal/endtoend/testdata/params_location/postgresql/stdlib/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/params_location/postgresql/stdlib/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/params_placeholder_in_left_expr/postgresql/exec.json b/internal/endtoend/testdata/params_placeholder_in_left_expr/postgresql/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/params_placeholder_in_left_expr/postgresql/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/pg_dump/exec.json b/internal/endtoend/testdata/pg_dump/exec.json new file mode 100644 index 0000000000..c16f123ce3 --- /dev/null +++ b/internal/endtoend/testdata/pg_dump/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} \ No newline at end of file diff --git a/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/exec.json b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/go/query.sql.go index d9146cf3d8..a156949e24 100644 --- a/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/go/query.sql.go +++ b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/go/query.sql.go @@ -8,12 +8,10 @@ package querytest import ( "context" "time" - - "github.com/jackc/pgtype" ) const generateSeries = `-- name: GenerateSeries :many -SELECT generate_series($1::timestamp, $2::timestamp) +SELECT generate_series($1::timestamp, $2::timestamp, '10 hours') ` type GenerateSeriesParams struct { @@ -21,15 +19,15 @@ type GenerateSeriesParams struct { Column2 time.Time `json:"column_2"` } -func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]pgtype.Numeric, error) { +func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]int64, error) { rows, err := q.db.Query(ctx, generateSeries, arg.Column1, arg.Column2) if err != nil { return nil, err } defer rows.Close() - var items []pgtype.Numeric + var items []int64 for rows.Next() { - var generate_series pgtype.Numeric + var generate_series int64 if err := rows.Scan(&generate_series); err != nil { return nil, err } diff --git a/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/query.sql index c00238feda..3d483e89ec 100644 --- a/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/query.sql +++ b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v4/query.sql @@ -1,2 +1,2 @@ -- name: GenerateSeries :many -SELECT generate_series($1::timestamp, $2::timestamp); +SELECT generate_series($1::timestamp, $2::timestamp, '10 hours'); diff --git a/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/exec.json b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/go/query.sql.go index de11bf7555..73d2f1855f 100644 --- a/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/go/query.sql.go @@ -12,7 +12,7 @@ import ( ) const generateSeries = `-- name: GenerateSeries :many -SELECT generate_series($1::timestamp, $2::timestamp) +SELECT generate_series($1::timestamp, $2::timestamp, '10 hours') ` type GenerateSeriesParams struct { @@ -20,15 +20,15 @@ type GenerateSeriesParams struct { Column2 pgtype.Timestamp `json:"column_2"` } -func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]pgtype.Numeric, error) { +func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]int64, error) { rows, err := q.db.Query(ctx, generateSeries, arg.Column1, arg.Column2) if err != nil { return nil, err } defer rows.Close() - var items []pgtype.Numeric + var items []int64 for rows.Next() { - var generate_series pgtype.Numeric + var generate_series int64 if err := rows.Scan(&generate_series); err != nil { return nil, err } diff --git a/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/query.sql index c00238feda..3d483e89ec 100644 --- a/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/query.sql +++ b/internal/endtoend/testdata/pg_generate_series/postgresql/pgx/v5/query.sql @@ -1,2 +1,2 @@ -- name: GenerateSeries :many -SELECT generate_series($1::timestamp, $2::timestamp); +SELECT generate_series($1::timestamp, $2::timestamp, '10 hours'); diff --git a/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/exec.json b/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/go/query.sql.go index 26487587ed..392a60099f 100644 --- a/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/go/query.sql.go @@ -11,7 +11,7 @@ import ( ) const generateSeries = `-- name: GenerateSeries :many -SELECT generate_series($1::timestamp, $2::timestamp) +SELECT generate_series($1::timestamp, $2::timestamp, '10 hours') ` type GenerateSeriesParams struct { @@ -19,15 +19,15 @@ type GenerateSeriesParams struct { Column2 time.Time `json:"column_2"` } -func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]string, error) { +func (q *Queries) GenerateSeries(ctx context.Context, arg GenerateSeriesParams) ([]int64, error) { rows, err := q.db.QueryContext(ctx, generateSeries, arg.Column1, arg.Column2) if err != nil { return nil, err } defer rows.Close() - var items []string + var items []int64 for rows.Next() { - var generate_series string + var generate_series int64 if err := rows.Scan(&generate_series); err != nil { return nil, err } diff --git a/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/query.sql b/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/query.sql index c00238feda..3d483e89ec 100644 --- a/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/query.sql +++ b/internal/endtoend/testdata/pg_generate_series/postgresql/stdlib/query.sql @@ -1,2 +1,2 @@ -- name: GenerateSeries :many -SELECT generate_series($1::timestamp, $2::timestamp); +SELECT generate_series($1::timestamp, $2::timestamp, '10 hours'); diff --git a/internal/endtoend/testdata/pointer_type_import/postgresql/pgx/v5/exec.json b/internal/endtoend/testdata/pointer_type_import/postgresql/pgx/v5/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/pointer_type_import/postgresql/pgx/v5/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/process_plugin_sqlc_gen_json/exec.json b/internal/endtoend/testdata/process_plugin_sqlc_gen_json/exec.json index 5be7ac8c74..2e996ca79d 100644 --- a/internal/endtoend/testdata/process_plugin_sqlc_gen_json/exec.json +++ b/internal/endtoend/testdata/process_plugin_sqlc_gen_json/exec.json @@ -1,3 +1,3 @@ { - "process": "sqlc-gen-json" + "contexts": ["base"] } diff --git a/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/query.sql b/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/query.sql index 7afab0139a..b96c66b9b3 100644 --- a/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/query.sql +++ b/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/query.sql @@ -1,5 +1,3 @@ -CREATE TABLE bar (id serial not null, name text not null, primary key (id)); - -- name: DeleteBarByID :execrows DELETE FROM bar WHERE id = $1; diff --git a/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/schema.sql b/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/schema.sql new file mode 100644 index 0000000000..fd3ca97902 --- /dev/null +++ b/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/schema.sql @@ -0,0 +1 @@ +CREATE TABLE bar (id serial not null, name text not null, primary key (id)); \ No newline at end of file diff --git a/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/sqlc.json b/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/sqlc.json index 3a7bd37085..d431feabb5 100644 --- a/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/sqlc.json +++ b/internal/endtoend/testdata/query_parameter_limit/-1/python_postgresql/sqlc.json @@ -11,7 +11,7 @@ ], "sql": [ { - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql", "engine": "postgresql", "codegen": [ diff --git a/internal/endtoend/testdata/relation_does_not_exist/postgresql/schema.sql b/internal/endtoend/testdata/relation_does_not_exist/postgresql/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/relation_does_not_exist/postgresql/sqlc.json b/internal/endtoend/testdata/relation_does_not_exist/postgresql/sqlc.json index ac7c2ed829..dbe55e66a6 100644 --- a/internal/endtoend/testdata/relation_does_not_exist/postgresql/sqlc.json +++ b/internal/endtoend/testdata/relation_does_not_exist/postgresql/sqlc.json @@ -4,7 +4,7 @@ { "path": "go", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr.txt b/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr.txt index 0d8930ee17..f5e231d552 100644 --- a/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr.txt +++ b/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr.txt @@ -3,3 +3,9 @@ query.sql:1:1: relation "nonexisting_relation" does not exist query.sql:5:1: relation "nonexisting_relation" does not exist query.sql:8:1: relation "nonexisting_relation" does not exist query.sql:11:1: relation "nonexisting_relation" does not exist +--- +# package querytest +query.sql:2:15: relation "nonexisting_relation" does not exist +query.sql:5:15: relation "nonexisting_relation" does not exist +query.sql:8:8: relation "nonexisting_relation" does not exist +query.sql:11:13: relation "nonexisting_relation" does not exist \ No newline at end of file diff --git a/internal/endtoend/testdata/select_limit/postgresql/pgx/v4/exec.json b/internal/endtoend/testdata/select_limit/postgresql/pgx/v4/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/select_limit/postgresql/pgx/v4/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/select_limit/postgresql/pgx/v5/exec.json b/internal/endtoend/testdata/select_limit/postgresql/pgx/v5/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/select_limit/postgresql/pgx/v5/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/select_limit/postgresql/stdlib/exec.json b/internal/endtoend/testdata/select_limit/postgresql/stdlib/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/select_limit/postgresql/stdlib/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/select_union/postgres/pgx/v4/exec.json b/internal/endtoend/testdata/select_union/postgres/pgx/v4/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/select_union/postgres/pgx/v4/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/select_union/postgres/pgx/v5/exec.json b/internal/endtoend/testdata/select_union/postgres/pgx/v5/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/select_union/postgres/pgx/v5/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/select_union/postgres/stdlib/exec.json b/internal/endtoend/testdata/select_union/postgres/stdlib/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/select_union/postgres/stdlib/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v4/go/query.sql.go index a904edc966..fa0c265bbd 100644 --- a/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v4/go/query.sql.go +++ b/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v4/go/query.sql.go @@ -54,7 +54,7 @@ func (q *Queries) GetUser(ctx context.Context, sub uuid.UUID) (uuid.UUID, error) const setDefaultName = `-- name: SetDefaultName :one UPDATE authors -SET name = "Default Name" +SET name = 'Default Name' WHERE id = $1 RETURNING id ` diff --git a/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v4/query.sql index 3e209ba5a4..ca3fc5c6a4 100644 --- a/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v4/query.sql +++ b/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v4/query.sql @@ -20,6 +20,6 @@ LIMIT 1; -- name: SetDefaultName :one UPDATE authors -SET name = "Default Name" +SET name = 'Default Name' WHERE id = $1 RETURNING id; diff --git a/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v5/go/query.sql.go index f00070c371..9e8923565e 100644 --- a/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v5/go/query.sql.go @@ -54,7 +54,7 @@ func (q *Queries) GetUser(ctx context.Context, sub pgtype.UUID) (pgtype.UUID, er const setDefaultName = `-- name: SetDefaultName :one UPDATE authors -SET name = "Default Name" +SET name = 'Default Name' WHERE id = $1 RETURNING id ` diff --git a/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v5/query.sql index 3e209ba5a4..ca3fc5c6a4 100644 --- a/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v5/query.sql +++ b/internal/endtoend/testdata/single_param_conflict/postgresql/pgx/v5/query.sql @@ -20,6 +20,6 @@ LIMIT 1; -- name: SetDefaultName :one UPDATE authors -SET name = "Default Name" +SET name = 'Default Name' WHERE id = $1 RETURNING id; diff --git a/internal/endtoend/testdata/single_param_conflict/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/single_param_conflict/postgresql/stdlib/go/query.sql.go index 1d992e3b85..be987b8417 100644 --- a/internal/endtoend/testdata/single_param_conflict/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/single_param_conflict/postgresql/stdlib/go/query.sql.go @@ -54,7 +54,7 @@ func (q *Queries) GetUser(ctx context.Context, sub uuid.UUID) (uuid.UUID, error) const setDefaultName = `-- name: SetDefaultName :one UPDATE authors -SET name = "Default Name" +SET name = 'Default Name' WHERE id = $1 RETURNING id ` diff --git a/internal/endtoend/testdata/single_param_conflict/postgresql/stdlib/query.sql b/internal/endtoend/testdata/single_param_conflict/postgresql/stdlib/query.sql index 3e209ba5a4..ca3fc5c6a4 100644 --- a/internal/endtoend/testdata/single_param_conflict/postgresql/stdlib/query.sql +++ b/internal/endtoend/testdata/single_param_conflict/postgresql/stdlib/query.sql @@ -20,6 +20,6 @@ LIMIT 1; -- name: SetDefaultName :one UPDATE authors -SET name = "Default Name" +SET name = 'Default Name' WHERE id = $1 RETURNING id; diff --git a/internal/endtoend/testdata/sqlc_arg_invalid/mysql/stderr.txt b/internal/endtoend/testdata/sqlc_arg_invalid/mysql/stderr.txt index 8009988505..be38c8b505 100644 --- a/internal/endtoend/testdata/sqlc_arg_invalid/mysql/stderr.txt +++ b/internal/endtoend/testdata/sqlc_arg_invalid/mysql/stderr.txt @@ -2,5 +2,5 @@ query.sql:7:1: function "sqlc.argh" does not exist query.sql:10:45: expected 1 parameter to sqlc.arg; got 2 query.sql:13:45: expected 1 parameter to sqlc.arg; got 0 -query.sql:16:54: Invalid argument to sqlc.arg() -query.sql:19:54: Invalid argument to sqlc.arg() +query.sql:16:45: expected parameter to sqlc.arg to be string or reference; got *ast.FuncCall +query.sql:19:45: expected parameter to sqlc.arg to be string or reference; got *ast.ParamRef diff --git a/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/query.sql b/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/query.sql index fe25398cce..397850187a 100644 --- a/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/query.sql +++ b/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/query.sql @@ -1,8 +1,3 @@ -CREATE TABLE users ( - id serial, - first_name text not null -); - -- name: WrongFunc :one select id, first_name from users where id = sqlc.argh(target_id); diff --git a/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/schema.sql b/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/schema.sql new file mode 100644 index 0000000000..0a380b5f9d --- /dev/null +++ b/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/schema.sql @@ -0,0 +1,4 @@ +CREATE TABLE users ( + id serial, + first_name text not null +); \ No newline at end of file diff --git a/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/sqlc.json b/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/sqlc.json index 696ed223db..f5a835c5a6 100644 --- a/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/sqlc.json +++ b/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/sqlc.json @@ -4,7 +4,7 @@ { "name": "querytest", "path": "go", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql", "engine": "postgresql" } diff --git a/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/stderr.txt b/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/stderr.txt index 8009988505..e988a53f2f 100644 --- a/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/stderr.txt +++ b/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/stderr.txt @@ -2,5 +2,12 @@ query.sql:7:1: function "sqlc.argh" does not exist query.sql:10:45: expected 1 parameter to sqlc.arg; got 2 query.sql:13:45: expected 1 parameter to sqlc.arg; got 0 -query.sql:16:54: Invalid argument to sqlc.arg() -query.sql:19:54: Invalid argument to sqlc.arg() +query.sql:16:45: expected parameter to sqlc.arg to be string or reference; got *ast.FuncCall +query.sql:19:45: expected parameter to sqlc.arg to be string or reference; got *ast.ParamRef +--- +# package querytest +query.sql:1:1: function "sqlc.argh" does not exist +query.sql:5:45: expected 1 parameter to sqlc.arg; got 2 +query.sql:8:45: expected 1 parameter to sqlc.arg; got 0 +query.sql:11:45: expected parameter to sqlc.arg to be string or reference; got *ast.FuncCall +query.sql:14:45: expected parameter to sqlc.arg to be string or reference; got *ast.ParamRef diff --git a/internal/endtoend/testdata/sqlc_arg_invalid/sqlite/stderr.txt b/internal/endtoend/testdata/sqlc_arg_invalid/sqlite/stderr.txt index 8009988505..be38c8b505 100644 --- a/internal/endtoend/testdata/sqlc_arg_invalid/sqlite/stderr.txt +++ b/internal/endtoend/testdata/sqlc_arg_invalid/sqlite/stderr.txt @@ -2,5 +2,5 @@ query.sql:7:1: function "sqlc.argh" does not exist query.sql:10:45: expected 1 parameter to sqlc.arg; got 2 query.sql:13:45: expected 1 parameter to sqlc.arg; got 0 -query.sql:16:54: Invalid argument to sqlc.arg() -query.sql:19:54: Invalid argument to sqlc.arg() +query.sql:16:45: expected parameter to sqlc.arg to be string or reference; got *ast.FuncCall +query.sql:19:45: expected parameter to sqlc.arg to be string or reference; got *ast.ParamRef diff --git a/internal/endtoend/testdata/strict_function_checks/postgresql/schema.sql b/internal/endtoend/testdata/strict_function_checks/postgresql/schema.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/endtoend/testdata/strict_function_checks/postgresql/sqlc.json b/internal/endtoend/testdata/strict_function_checks/postgresql/sqlc.json index 935bb9f278..6cb9103c1a 100644 --- a/internal/endtoend/testdata/strict_function_checks/postgresql/sqlc.json +++ b/internal/endtoend/testdata/strict_function_checks/postgresql/sqlc.json @@ -4,7 +4,7 @@ { "name": "querytest", "path": "go", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql", "engine": "postgresql", "strict_function_checks": true diff --git a/internal/endtoend/testdata/strict_function_checks/postgresql/stderr.txt b/internal/endtoend/testdata/strict_function_checks/postgresql/stderr.txt index a8972055f6..72392e1535 100644 --- a/internal/endtoend/testdata/strict_function_checks/postgresql/stderr.txt +++ b/internal/endtoend/testdata/strict_function_checks/postgresql/stderr.txt @@ -1,2 +1,5 @@ # package querytest query.sql:1:1: function "doesntexist" does not exist +--- +# package querytest +query.sql:2:8: function doesntexist() does not exist diff --git a/internal/endtoend/testdata/sum_type/issue.md b/internal/endtoend/testdata/sum_type/issue.md new file mode 100644 index 0000000000..b125c05134 --- /dev/null +++ b/internal/endtoend/testdata/sum_type/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1106 \ No newline at end of file diff --git a/internal/endtoend/testdata/sum_type/postgresql/pgx/exec.json b/internal/endtoend/testdata/sum_type/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/sum_type/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/sum_type/postgresql/pgx/go/db.go b/internal/endtoend/testdata/sum_type/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/sum_type/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/sum_type/postgresql/pgx/go/models.go b/internal/endtoend/testdata/sum_type/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..39fe1356af --- /dev/null +++ b/internal/endtoend/testdata/sum_type/postgresql/pgx/go/models.go @@ -0,0 +1,15 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type Order struct { + ID int64 + Quantity pgtype.Numeric + OrderCatalog pgtype.Int4 +} diff --git a/internal/endtoend/testdata/sum_type/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/sum_type/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..33f9e045aa --- /dev/null +++ b/internal/endtoend/testdata/sum_type/postgresql/pgx/go/query.sql.go @@ -0,0 +1,23 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const sumOrder = `-- name: SumOrder :one +SELECT SUM(quantity) FROM orders +` + +func (q *Queries) SumOrder(ctx context.Context) (pgtype.Numeric, error) { + row := q.db.QueryRow(ctx, sumOrder) + var sum pgtype.Numeric + err := row.Scan(&sum) + return sum, err +} diff --git a/internal/endtoend/testdata/sum_type/postgresql/pgx/query.sql b/internal/endtoend/testdata/sum_type/postgresql/pgx/query.sql new file mode 100644 index 0000000000..7effc6e765 --- /dev/null +++ b/internal/endtoend/testdata/sum_type/postgresql/pgx/query.sql @@ -0,0 +1,2 @@ +-- name: SumOrder :one +SELECT SUM(quantity) FROM orders; \ No newline at end of file diff --git a/internal/endtoend/testdata/sum_type/postgresql/pgx/schema.sql b/internal/endtoend/testdata/sum_type/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..85df079afe --- /dev/null +++ b/internal/endtoend/testdata/sum_type/postgresql/pgx/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE orders ( + id BIGSERIAL PRIMARY KEY, + quantity decimal NOT NULL, + order_catalog int +); \ No newline at end of file diff --git a/internal/endtoend/testdata/sum_type/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/sum_type/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/sum_type/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/table_function/postgresql/pgx/v4/go/models.go b/internal/endtoend/testdata/table_function/postgresql/pgx/v4/go/models.go index d0fd4d84a9..6f38d05c40 100644 --- a/internal/endtoend/testdata/table_function/postgresql/pgx/v4/go/models.go +++ b/internal/endtoend/testdata/table_function/postgresql/pgx/v4/go/models.go @@ -4,11 +4,13 @@ package querytest -import () +import ( + "github.com/jackc/pgtype" +) type Transaction struct { ID int64 Uri string ProgramID string - Data string + Data pgtype.JSONB } diff --git a/internal/endtoend/testdata/table_function/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/table_function/postgresql/pgx/v4/go/query.sql.go index c42aee02b5..783392c21b 100644 --- a/internal/endtoend/testdata/table_function/postgresql/pgx/v4/go/query.sql.go +++ b/internal/endtoend/testdata/table_function/postgresql/pgx/v4/go/query.sql.go @@ -7,36 +7,36 @@ package querytest import ( "context" + + "github.com/jackc/pgtype" ) const getTransaction = `-- name: GetTransaction :many SELECT - json_extract(transactions.data, '$.transaction.signatures[0]'), - json_group_array(instructions.value) + jsonb_extract_path(transactions.data, '$.transaction.signatures[0]'), + jsonb_agg(instructions.value) FROM transactions, - json_each(json_extract(transactions.data, '$.transaction.message.instructions')) AS instructions + jsonb_each(jsonb_extract_path(transactions.data, '$.transaction.message.instructions[0]')) AS instructions WHERE transactions.program_id = $1 - AND json_extract(transactions.data, '$.transaction.signatures[0]') > $2 - AND json_extract(json_extract(transactions.data, '$.transaction.message.accountKeys'), '$[' || json_extract(instructions.value, '$.programIdIndex') || ']') = transactions.program_id + AND jsonb_extract_path(transactions.data, '$.transaction.signatures[0]') @> to_jsonb($2::text) + AND jsonb_extract_path(jsonb_extract_path(transactions.data, '$.transaction.message.accountKeys'), 'key') = to_jsonb(transactions.program_id) GROUP BY transactions.id -LIMIT $3 ` type GetTransactionParams struct { ProgramID string Data string - Limit int32 } type GetTransactionRow struct { - JsonExtract interface{} - JsonGroupArray interface{} + JsonbExtractPath pgtype.JSONB + JsonbAgg pgtype.JSONB } func (q *Queries) GetTransaction(ctx context.Context, arg GetTransactionParams) ([]GetTransactionRow, error) { - rows, err := q.db.Query(ctx, getTransaction, arg.ProgramID, arg.Data, arg.Limit) + rows, err := q.db.Query(ctx, getTransaction, arg.ProgramID, arg.Data) if err != nil { return nil, err } @@ -44,7 +44,7 @@ func (q *Queries) GetTransaction(ctx context.Context, arg GetTransactionParams) var items []GetTransactionRow for rows.Next() { var i GetTransactionRow - if err := rows.Scan(&i.JsonExtract, &i.JsonGroupArray); err != nil { + if err := rows.Scan(&i.JsonbExtractPath, &i.JsonbAgg); err != nil { return nil, err } items = append(items, i) diff --git a/internal/endtoend/testdata/table_function/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/table_function/postgresql/pgx/v4/query.sql index cbf49a037b..99f02a70ef 100644 --- a/internal/endtoend/testdata/table_function/postgresql/pgx/v4/query.sql +++ b/internal/endtoend/testdata/table_function/postgresql/pgx/v4/query.sql @@ -1,13 +1,12 @@ /* name: GetTransaction :many */ SELECT - json_extract(transactions.data, '$.transaction.signatures[0]'), - json_group_array(instructions.value) + jsonb_extract_path(transactions.data, '$.transaction.signatures[0]'), + jsonb_agg(instructions.value) FROM transactions, - json_each(json_extract(transactions.data, '$.transaction.message.instructions')) AS instructions + jsonb_each(jsonb_extract_path(transactions.data, '$.transaction.message.instructions[0]')) AS instructions WHERE - transactions.program_id = $1 - AND json_extract(transactions.data, '$.transaction.signatures[0]') > $2 - AND json_extract(json_extract(transactions.data, '$.transaction.message.accountKeys'), '$[' || json_extract(instructions.value, '$.programIdIndex') || ']') = transactions.program_id -GROUP BY transactions.id -LIMIT $3; \ No newline at end of file + transactions.program_id = sqlc.arg('program_id') + AND jsonb_extract_path(transactions.data, '$.transaction.signatures[0]') @> to_jsonb(sqlc.arg('data')::text) + AND jsonb_extract_path(jsonb_extract_path(transactions.data, '$.transaction.message.accountKeys'), 'key') = to_jsonb(transactions.program_id) +GROUP BY transactions.id; \ No newline at end of file diff --git a/internal/endtoend/testdata/table_function/postgresql/pgx/v4/schema.sql b/internal/endtoend/testdata/table_function/postgresql/pgx/v4/schema.sql index 46b1f13951..455651b8ad 100644 --- a/internal/endtoend/testdata/table_function/postgresql/pgx/v4/schema.sql +++ b/internal/endtoend/testdata/table_function/postgresql/pgx/v4/schema.sql @@ -1,7 +1,7 @@ CREATE TABLE transactions ( - id BIGSERIAL PRIMARY KEY, - uri text NOT NULL, - program_id text NOT NULL, - data text NOT NULL + id BIGSERIAL PRIMARY KEY, + uri TEXT NOT NULL, + program_id TEXT NOT NULL, + data JSONB NOT NULL ); diff --git a/internal/endtoend/testdata/table_function/postgresql/pgx/v5/go/models.go b/internal/endtoend/testdata/table_function/postgresql/pgx/v5/go/models.go index d0fd4d84a9..b4ee022e62 100644 --- a/internal/endtoend/testdata/table_function/postgresql/pgx/v5/go/models.go +++ b/internal/endtoend/testdata/table_function/postgresql/pgx/v5/go/models.go @@ -10,5 +10,5 @@ type Transaction struct { ID int64 Uri string ProgramID string - Data string + Data []byte } diff --git a/internal/endtoend/testdata/table_function/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/table_function/postgresql/pgx/v5/go/query.sql.go index c42aee02b5..21e32608e7 100644 --- a/internal/endtoend/testdata/table_function/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/table_function/postgresql/pgx/v5/go/query.sql.go @@ -11,32 +11,30 @@ import ( const getTransaction = `-- name: GetTransaction :many SELECT - json_extract(transactions.data, '$.transaction.signatures[0]'), - json_group_array(instructions.value) + jsonb_extract_path(transactions.data, '$.transaction.signatures[0]'), + jsonb_agg(instructions.value) FROM transactions, - json_each(json_extract(transactions.data, '$.transaction.message.instructions')) AS instructions + jsonb_each(jsonb_extract_path(transactions.data, '$.transaction.message.instructions[0]')) AS instructions WHERE transactions.program_id = $1 - AND json_extract(transactions.data, '$.transaction.signatures[0]') > $2 - AND json_extract(json_extract(transactions.data, '$.transaction.message.accountKeys'), '$[' || json_extract(instructions.value, '$.programIdIndex') || ']') = transactions.program_id + AND jsonb_extract_path(transactions.data, '$.transaction.signatures[0]') @> to_jsonb($2::text) + AND jsonb_extract_path(jsonb_extract_path(transactions.data, '$.transaction.message.accountKeys'), 'key') = to_jsonb(transactions.program_id) GROUP BY transactions.id -LIMIT $3 ` type GetTransactionParams struct { ProgramID string Data string - Limit int32 } type GetTransactionRow struct { - JsonExtract interface{} - JsonGroupArray interface{} + JsonbExtractPath []byte + JsonbAgg []byte } func (q *Queries) GetTransaction(ctx context.Context, arg GetTransactionParams) ([]GetTransactionRow, error) { - rows, err := q.db.Query(ctx, getTransaction, arg.ProgramID, arg.Data, arg.Limit) + rows, err := q.db.Query(ctx, getTransaction, arg.ProgramID, arg.Data) if err != nil { return nil, err } @@ -44,7 +42,7 @@ func (q *Queries) GetTransaction(ctx context.Context, arg GetTransactionParams) var items []GetTransactionRow for rows.Next() { var i GetTransactionRow - if err := rows.Scan(&i.JsonExtract, &i.JsonGroupArray); err != nil { + if err := rows.Scan(&i.JsonbExtractPath, &i.JsonbAgg); err != nil { return nil, err } items = append(items, i) diff --git a/internal/endtoend/testdata/table_function/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/table_function/postgresql/pgx/v5/query.sql index cbf49a037b..99f02a70ef 100644 --- a/internal/endtoend/testdata/table_function/postgresql/pgx/v5/query.sql +++ b/internal/endtoend/testdata/table_function/postgresql/pgx/v5/query.sql @@ -1,13 +1,12 @@ /* name: GetTransaction :many */ SELECT - json_extract(transactions.data, '$.transaction.signatures[0]'), - json_group_array(instructions.value) + jsonb_extract_path(transactions.data, '$.transaction.signatures[0]'), + jsonb_agg(instructions.value) FROM transactions, - json_each(json_extract(transactions.data, '$.transaction.message.instructions')) AS instructions + jsonb_each(jsonb_extract_path(transactions.data, '$.transaction.message.instructions[0]')) AS instructions WHERE - transactions.program_id = $1 - AND json_extract(transactions.data, '$.transaction.signatures[0]') > $2 - AND json_extract(json_extract(transactions.data, '$.transaction.message.accountKeys'), '$[' || json_extract(instructions.value, '$.programIdIndex') || ']') = transactions.program_id -GROUP BY transactions.id -LIMIT $3; \ No newline at end of file + transactions.program_id = sqlc.arg('program_id') + AND jsonb_extract_path(transactions.data, '$.transaction.signatures[0]') @> to_jsonb(sqlc.arg('data')::text) + AND jsonb_extract_path(jsonb_extract_path(transactions.data, '$.transaction.message.accountKeys'), 'key') = to_jsonb(transactions.program_id) +GROUP BY transactions.id; \ No newline at end of file diff --git a/internal/endtoend/testdata/table_function/postgresql/pgx/v5/schema.sql b/internal/endtoend/testdata/table_function/postgresql/pgx/v5/schema.sql index 46b1f13951..455651b8ad 100644 --- a/internal/endtoend/testdata/table_function/postgresql/pgx/v5/schema.sql +++ b/internal/endtoend/testdata/table_function/postgresql/pgx/v5/schema.sql @@ -1,7 +1,7 @@ CREATE TABLE transactions ( - id BIGSERIAL PRIMARY KEY, - uri text NOT NULL, - program_id text NOT NULL, - data text NOT NULL + id BIGSERIAL PRIMARY KEY, + uri TEXT NOT NULL, + program_id TEXT NOT NULL, + data JSONB NOT NULL ); diff --git a/internal/endtoend/testdata/table_function/postgresql/stdlib/go/models.go b/internal/endtoend/testdata/table_function/postgresql/stdlib/go/models.go index d0fd4d84a9..62525257f0 100644 --- a/internal/endtoend/testdata/table_function/postgresql/stdlib/go/models.go +++ b/internal/endtoend/testdata/table_function/postgresql/stdlib/go/models.go @@ -4,11 +4,13 @@ package querytest -import () +import ( + "encoding/json" +) type Transaction struct { ID int64 Uri string ProgramID string - Data string + Data json.RawMessage } diff --git a/internal/endtoend/testdata/table_function/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/table_function/postgresql/stdlib/go/query.sql.go index f59f708b45..2b9fa93fe7 100644 --- a/internal/endtoend/testdata/table_function/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/table_function/postgresql/stdlib/go/query.sql.go @@ -7,36 +7,35 @@ package querytest import ( "context" + "encoding/json" ) const getTransaction = `-- name: GetTransaction :many SELECT - json_extract(transactions.data, '$.transaction.signatures[0]'), - json_group_array(instructions.value) + jsonb_extract_path(transactions.data, '$.transaction.signatures[0]'), + jsonb_agg(instructions.value) FROM transactions, - json_each(json_extract(transactions.data, '$.transaction.message.instructions')) AS instructions + jsonb_each(jsonb_extract_path(transactions.data, '$.transaction.message.instructions[0]')) AS instructions WHERE transactions.program_id = $1 - AND json_extract(transactions.data, '$.transaction.signatures[0]') > $2 - AND json_extract(json_extract(transactions.data, '$.transaction.message.accountKeys'), '$[' || json_extract(instructions.value, '$.programIdIndex') || ']') = transactions.program_id + AND jsonb_extract_path(transactions.data, '$.transaction.signatures[0]') @> to_jsonb($2::text) + AND jsonb_extract_path(jsonb_extract_path(transactions.data, '$.transaction.message.accountKeys'), 'key') = to_jsonb(transactions.program_id) GROUP BY transactions.id -LIMIT $3 ` type GetTransactionParams struct { ProgramID string Data string - Limit int32 } type GetTransactionRow struct { - JsonExtract interface{} - JsonGroupArray interface{} + JsonbExtractPath json.RawMessage + JsonbAgg json.RawMessage } func (q *Queries) GetTransaction(ctx context.Context, arg GetTransactionParams) ([]GetTransactionRow, error) { - rows, err := q.db.QueryContext(ctx, getTransaction, arg.ProgramID, arg.Data, arg.Limit) + rows, err := q.db.QueryContext(ctx, getTransaction, arg.ProgramID, arg.Data) if err != nil { return nil, err } @@ -44,7 +43,7 @@ func (q *Queries) GetTransaction(ctx context.Context, arg GetTransactionParams) var items []GetTransactionRow for rows.Next() { var i GetTransactionRow - if err := rows.Scan(&i.JsonExtract, &i.JsonGroupArray); err != nil { + if err := rows.Scan(&i.JsonbExtractPath, &i.JsonbAgg); err != nil { return nil, err } items = append(items, i) diff --git a/internal/endtoend/testdata/table_function/postgresql/stdlib/query.sql b/internal/endtoend/testdata/table_function/postgresql/stdlib/query.sql index 2ed11a193e..99f02a70ef 100644 --- a/internal/endtoend/testdata/table_function/postgresql/stdlib/query.sql +++ b/internal/endtoend/testdata/table_function/postgresql/stdlib/query.sql @@ -1,13 +1,12 @@ /* name: GetTransaction :many */ SELECT - json_extract(transactions.data, '$.transaction.signatures[0]'), - json_group_array(instructions.value) + jsonb_extract_path(transactions.data, '$.transaction.signatures[0]'), + jsonb_agg(instructions.value) FROM transactions, - json_each(json_extract(transactions.data, '$.transaction.message.instructions')) AS instructions + jsonb_each(jsonb_extract_path(transactions.data, '$.transaction.message.instructions[0]')) AS instructions WHERE - transactions.program_id = $1 - AND json_extract(transactions.data, '$.transaction.signatures[0]') > $2 - AND json_extract(json_extract(transactions.data, '$.transaction.message.accountKeys'), '$[' || json_extract(instructions.value, '$.programIdIndex') || ']') = transactions.program_id -GROUP BY transactions.id -LIMIT $3; + transactions.program_id = sqlc.arg('program_id') + AND jsonb_extract_path(transactions.data, '$.transaction.signatures[0]') @> to_jsonb(sqlc.arg('data')::text) + AND jsonb_extract_path(jsonb_extract_path(transactions.data, '$.transaction.message.accountKeys'), 'key') = to_jsonb(transactions.program_id) +GROUP BY transactions.id; \ No newline at end of file diff --git a/internal/endtoend/testdata/table_function/postgresql/stdlib/schema.sql b/internal/endtoend/testdata/table_function/postgresql/stdlib/schema.sql index 46b1f13951..455651b8ad 100644 --- a/internal/endtoend/testdata/table_function/postgresql/stdlib/schema.sql +++ b/internal/endtoend/testdata/table_function/postgresql/stdlib/schema.sql @@ -1,7 +1,7 @@ CREATE TABLE transactions ( - id BIGSERIAL PRIMARY KEY, - uri text NOT NULL, - program_id text NOT NULL, - data text NOT NULL + id BIGSERIAL PRIMARY KEY, + uri TEXT NOT NULL, + program_id TEXT NOT NULL, + data JSONB NOT NULL ); diff --git a/internal/endtoend/testdata/unknown_func/pganalyze/exec.json b/internal/endtoend/testdata/unknown_func/pganalyze/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/unknown_func/pganalyze/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/unknown_func/pganalyze/query.sql b/internal/endtoend/testdata/unknown_func/pganalyze/query.sql new file mode 100644 index 0000000000..36b697c8bb --- /dev/null +++ b/internal/endtoend/testdata/unknown_func/pganalyze/query.sql @@ -0,0 +1,2 @@ +-- name: ListFoos :one +SELECT id FROM foo WHERE id = frobnicate($1); diff --git a/internal/endtoend/testdata/unknown_func/pganalyze/schema.sql b/internal/endtoend/testdata/unknown_func/pganalyze/schema.sql new file mode 100644 index 0000000000..15fe2093e0 --- /dev/null +++ b/internal/endtoend/testdata/unknown_func/pganalyze/schema.sql @@ -0,0 +1 @@ +CREATE TABLE foo (id text not null); diff --git a/internal/endtoend/testdata/unknown_func/pganalyze/sqlc.json b/internal/endtoend/testdata/unknown_func/pganalyze/sqlc.json new file mode 100644 index 0000000000..32ede07158 --- /dev/null +++ b/internal/endtoend/testdata/unknown_func/pganalyze/sqlc.json @@ -0,0 +1,13 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "sql_package": "pgx/v5", + "name": "querytest", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/unknown_func/pganalyze/stderr.txt b/internal/endtoend/testdata/unknown_func/pganalyze/stderr.txt new file mode 100644 index 0000000000..8e63375c83 --- /dev/null +++ b/internal/endtoend/testdata/unknown_func/pganalyze/stderr.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:2:31: function frobnicate(unknown) does not exist \ No newline at end of file diff --git a/internal/endtoend/testdata/unknown_func/pgx/v4/exec.json b/internal/endtoend/testdata/unknown_func/pgx/v4/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/unknown_func/pgx/v4/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/unknown_func/pgx/v5/exec.json b/internal/endtoend/testdata/unknown_func/pgx/v5/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/unknown_func/pgx/v5/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/unknown_func/stdlib/exec.json b/internal/endtoend/testdata/unknown_func/stdlib/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/unknown_func/stdlib/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/unnest_star/issue.md b/internal/endtoend/testdata/unnest_star/issue.md new file mode 100644 index 0000000000..d0aede56b3 --- /dev/null +++ b/internal/endtoend/testdata/unnest_star/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1185 \ No newline at end of file diff --git a/internal/endtoend/testdata/unnest_star/postgresql/pgx/exec.json b/internal/endtoend/testdata/unnest_star/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/unnest_star/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/unnest_star/postgresql/pgx/go/db.go b/internal/endtoend/testdata/unnest_star/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/unnest_star/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/unnest_star/postgresql/pgx/go/models.go b/internal/endtoend/testdata/unnest_star/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..9f0b7ce585 --- /dev/null +++ b/internal/endtoend/testdata/unnest_star/postgresql/pgx/go/models.go @@ -0,0 +1,21 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () + +type Item struct { + ItemID int64 +} + +type Plan struct { + PlanID int64 +} + +type PlanItem struct { + PlanItemID int64 + PlanID int64 + ItemID int64 +} diff --git a/internal/endtoend/testdata/unnest_star/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/unnest_star/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..cf64948cd8 --- /dev/null +++ b/internal/endtoend/testdata/unnest_star/postgresql/pgx/go/query.sql.go @@ -0,0 +1,57 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const getPlanItems = `-- name: GetPlanItems :many +SELECT p.plan_id, p.item_id +FROM (SELECT unnest FROM unnest($1::bigint[])) AS i(req_item_id), +LATERAL ( + SELECT plan_id, item_id + FROM plan_items + WHERE + item_id = i.req_item_id AND + ($2 = 0 OR plan_id < $2) + ORDER BY plan_id DESC + LIMIT $3 +) p +` + +type GetPlanItemsParams struct { + Ids []int64 + After pgtype.Int4 + LimitCount int64 +} + +type GetPlanItemsRow struct { + PlanID int64 + ItemID int64 +} + +func (q *Queries) GetPlanItems(ctx context.Context, arg GetPlanItemsParams) ([]GetPlanItemsRow, error) { + rows, err := q.db.Query(ctx, getPlanItems, arg.Ids, arg.After, arg.LimitCount) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetPlanItemsRow + for rows.Next() { + var i GetPlanItemsRow + if err := rows.Scan(&i.PlanID, &i.ItemID); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/unnest_star/postgresql/pgx/query.sql b/internal/endtoend/testdata/unnest_star/postgresql/pgx/query.sql new file mode 100644 index 0000000000..01b5c77430 --- /dev/null +++ b/internal/endtoend/testdata/unnest_star/postgresql/pgx/query.sql @@ -0,0 +1,12 @@ +-- name: GetPlanItems :many +SELECT p.plan_id, p.item_id +FROM (SELECT * FROM unnest(@ids::bigint[])) AS i(req_item_id), +LATERAL ( + SELECT plan_id, item_id + FROM plan_items + WHERE + item_id = i.req_item_id AND + (@after = 0 OR plan_id < @after) + ORDER BY plan_id DESC + LIMIT @limit_count +) p; \ No newline at end of file diff --git a/internal/endtoend/testdata/unnest_star/postgresql/pgx/schema.sql b/internal/endtoend/testdata/unnest_star/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..787caf88c7 --- /dev/null +++ b/internal/endtoend/testdata/unnest_star/postgresql/pgx/schema.sql @@ -0,0 +1,13 @@ +create table plans ( + plan_id bigint generated by default as identity primary key +); + +create table items ( + item_id bigint generated by default as identity primary key +); + +create table plan_items ( + plan_item_id bigint generated by default as identity primary key, + plan_id bigint not null REFERENCES plans, + item_id bigint not null REFERENCES items +); \ No newline at end of file diff --git a/internal/endtoend/testdata/unnest_star/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/unnest_star/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/unnest_star/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/update_set_on_conflict/issue.md b/internal/endtoend/testdata/update_set_on_conflict/issue.md new file mode 100644 index 0000000000..27f06c09ab --- /dev/null +++ b/internal/endtoend/testdata/update_set_on_conflict/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1128 \ No newline at end of file diff --git a/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/exec.json b/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/query.sql b/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/query.sql new file mode 100644 index 0000000000..3f9e9d9b86 --- /dev/null +++ b/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/query.sql @@ -0,0 +1,4 @@ +-- name: UpsertServer :exec +INSERT INTO servers(code, name) VALUES ($1, $2) +ON CONFLICT (code) +DO UPDATE SET name_typo = 1111; \ No newline at end of file diff --git a/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/schema.sql b/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..3ff1ccd6b3 --- /dev/null +++ b/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/schema.sql @@ -0,0 +1,4 @@ +CREATE TABLE servers ( + code varchar PRIMARY KEY, + name text NOT NULL +); \ No newline at end of file diff --git a/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..01489e0ffc --- /dev/null +++ b/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" \ No newline at end of file diff --git a/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/stderr.txt b/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/stderr.txt new file mode 100644 index 0000000000..adbb13a418 --- /dev/null +++ b/internal/endtoend/testdata/update_set_on_conflict/postgresql/pgx/stderr.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:4:15: column "name_typo" of relation "servers" does not exist \ No newline at end of file diff --git a/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/exec.json b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/db.go b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/db.go new file mode 100644 index 0000000000..a457fb76b2 --- /dev/null +++ b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/models.go b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/models.go new file mode 100644 index 0000000000..ff5f263f68 --- /dev/null +++ b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/models.go @@ -0,0 +1,36 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import ( + "database/sql" + "time" +) + +type Author struct { + ID int64 + Name string + Bio sql.NullString +} + +type WeatherMetric struct { + Time time.Time + TimezoneShift sql.NullInt32 + CityName sql.NullString + TempC sql.NullFloat64 + FeelsLikeC sql.NullFloat64 + TempMinC sql.NullFloat64 + TempMaxC sql.NullFloat64 + PressureHpa sql.NullFloat64 + HumidityPercent sql.NullFloat64 + WindSpeedMs sql.NullFloat64 + WindDeg sql.NullInt32 + Rain1hMm sql.NullFloat64 + Rain3hMm sql.NullFloat64 + Snow1hMm sql.NullFloat64 + Snow3hMm sql.NullFloat64 + CloudsPercent sql.NullInt32 + WeatherTypeID sql.NullInt32 +} diff --git a/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/query.sql.go b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/query.sql.go new file mode 100644 index 0000000000..81a9cad7df --- /dev/null +++ b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/go/query.sql.go @@ -0,0 +1,105 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + "database/sql" + "time" +) + +const listAuthors = `-- name: ListAuthors :many +SELECT id, name as name, bio +FROM authors +` + +func (q *Queries) ListAuthors(ctx context.Context) ([]Author, error) { + rows, err := q.db.QueryContext(ctx, listAuthors) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Author + for rows.Next() { + var i Author + if err := rows.Scan(&i.ID, &i.Name, &i.Bio); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listAuthorsIdenticalAlias = `-- name: ListAuthorsIdenticalAlias :many +SELECT id, name as name, bio +FROM authors +` + +func (q *Queries) ListAuthorsIdenticalAlias(ctx context.Context) ([]Author, error) { + rows, err := q.db.QueryContext(ctx, listAuthorsIdenticalAlias) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Author + for rows.Next() { + var i Author + if err := rows.Scan(&i.ID, &i.Name, &i.Bio); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listMetrics = `-- name: ListMetrics :many +SELECT date_trunc('day', time) AS bucket, city_name, AVG(temp_c) +FROM weather_metrics +WHERE time > NOW() - (6 * INTERVAL '1 month') +GROUP BY bucket, city_name +ORDER BY bucket DESC +` + +type ListMetricsRow struct { + Bucket time.Time + CityName sql.NullString + Avg float64 +} + +func (q *Queries) ListMetrics(ctx context.Context) ([]ListMetricsRow, error) { + rows, err := q.db.QueryContext(ctx, listMetrics) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ListMetricsRow + for rows.Next() { + var i ListMetricsRow + if err := rows.Scan(&i.Bucket, &i.CityName, &i.Avg); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/query.sql b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/query.sql new file mode 100644 index 0000000000..839f5414c9 --- /dev/null +++ b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/query.sql @@ -0,0 +1,14 @@ +-- name: ListAuthors :many +SELECT id, name as name, bio +FROM authors; + +-- name: ListAuthorsIdenticalAlias :many +SELECT id, name as name, bio +FROM authors; + +-- name: ListMetrics :many +SELECT date_trunc('day', time) AS bucket, city_name, AVG(temp_c) +FROM weather_metrics +WHERE time > NOW() - (6 * INTERVAL '1 month') +GROUP BY bucket, city_name +ORDER BY bucket DESC; diff --git a/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/schema.sql b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/schema.sql new file mode 100644 index 0000000000..910e1da151 --- /dev/null +++ b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/schema.sql @@ -0,0 +1,26 @@ +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL, + bio text +); + +CREATE TABLE IF NOT EXISTS weather_metrics +( + time TIMESTAMP WITHOUT TIME ZONE NOT NULL, + timezone_shift INT NULL, + city_name TEXT NULL, + temp_c DOUBLE PRECISION NULL, + feels_like_c DOUBLE PRECISION NULL, + temp_min_c DOUBLE PRECISION NULL, + temp_max_c DOUBLE PRECISION NULL, + pressure_hpa DOUBLE PRECISION NULL, + humidity_percent DOUBLE PRECISION NULL, + wind_speed_ms DOUBLE PRECISION NULL, + wind_deg INT NULL, + rain_1h_mm DOUBLE PRECISION NULL, + rain_3h_mm DOUBLE PRECISION NULL, + snow_1h_mm DOUBLE PRECISION NULL, + snow_3h_mm DOUBLE PRECISION NULL, + clouds_percent INT NULL, + weather_type_id INT NULL +); diff --git a/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/sqlc.json b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/sqlc.json new file mode 100644 index 0000000000..a590361309 --- /dev/null +++ b/internal/endtoend/testdata/valid_group_by_reference/pganalyzer/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "name": "querytest", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/valid_group_by_reference/postgresql/exec.json b/internal/endtoend/testdata/valid_group_by_reference/postgresql/exec.json new file mode 100644 index 0000000000..2e996ca79d --- /dev/null +++ b/internal/endtoend/testdata/valid_group_by_reference/postgresql/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["base"] +} diff --git a/internal/endtoend/testdata/valid_group_by_reference/postgresql/go/query.sql.go b/internal/endtoend/testdata/valid_group_by_reference/postgresql/go/query.sql.go index e6af3b89fb..a32cf68206 100644 --- a/internal/endtoend/testdata/valid_group_by_reference/postgresql/go/query.sql.go +++ b/internal/endtoend/testdata/valid_group_by_reference/postgresql/go/query.sql.go @@ -13,7 +13,6 @@ import ( const listAuthors = `-- name: ListAuthors :many SELECT id, name as name, bio FROM authors -GROUP BY name ` func (q *Queries) ListAuthors(ctx context.Context) ([]Author, error) { @@ -42,7 +41,6 @@ func (q *Queries) ListAuthors(ctx context.Context) ([]Author, error) { const listAuthorsIdenticalAlias = `-- name: ListAuthorsIdenticalAlias :many SELECT id, name as name, bio FROM authors -GROUP BY name ` func (q *Queries) ListAuthorsIdenticalAlias(ctx context.Context) ([]Author, error) { @@ -69,7 +67,7 @@ func (q *Queries) ListAuthorsIdenticalAlias(ctx context.Context) ([]Author, erro } const listMetrics = `-- name: ListMetrics :many -SELECT time_bucket('15 days', time) AS bucket, city_name, AVG(temp_c) +SELECT date_trunc('day', time) AS bucket, city_name, AVG(temp_c) FROM weather_metrics WHERE time > NOW() - (6 * INTERVAL '1 month') GROUP BY bucket, city_name @@ -77,7 +75,7 @@ ORDER BY bucket DESC ` type ListMetricsRow struct { - Bucket interface{} + Bucket int64 CityName sql.NullString Avg float64 } diff --git a/internal/endtoend/testdata/valid_group_by_reference/postgresql/query.sql b/internal/endtoend/testdata/valid_group_by_reference/postgresql/query.sql index 0217b406a0..839f5414c9 100644 --- a/internal/endtoend/testdata/valid_group_by_reference/postgresql/query.sql +++ b/internal/endtoend/testdata/valid_group_by_reference/postgresql/query.sql @@ -1,15 +1,13 @@ -- name: ListAuthors :many SELECT id, name as name, bio -FROM authors -GROUP BY name; +FROM authors; -- name: ListAuthorsIdenticalAlias :many SELECT id, name as name, bio -FROM authors -GROUP BY name; +FROM authors; -- name: ListMetrics :many -SELECT time_bucket('15 days', time) AS bucket, city_name, AVG(temp_c) +SELECT date_trunc('day', time) AS bucket, city_name, AVG(temp_c) FROM weather_metrics WHERE time > NOW() - (6 * INTERVAL '1 month') GROUP BY bucket, city_name diff --git a/internal/endtoend/vet_test.go b/internal/endtoend/vet_test.go index f5fc47ac92..56b5837ed3 100644 --- a/internal/endtoend/vet_test.go +++ b/internal/endtoend/vet_test.go @@ -70,7 +70,11 @@ func TestExamplesVet(t *testing.T) { } var stderr bytes.Buffer - err := cmd.Vet(ctx, cmd.Env{}, path, "", &stderr) + opts := &cmd.Options{ + Stderr: &stderr, + Env: cmd.Env{}, + } + err := cmd.Vet(ctx, path, "", opts) if err != nil { t.Fatalf("sqlc vet failed: %s %s", err, stderr.String()) } From 884d3170acade2062a07da1504eb14fb104931d5 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 11 Oct 2023 18:29:22 -0700 Subject: [PATCH 3/9] back out change --- internal/engine/postgresql/pg_catalog.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/internal/engine/postgresql/pg_catalog.go b/internal/engine/postgresql/pg_catalog.go index 7020c0ff14..9000b592f4 100644 --- a/internal/engine/postgresql/pg_catalog.go +++ b/internal/engine/postgresql/pg_catalog.go @@ -29072,19 +29072,6 @@ var funcsgenPGCatalog = []*catalog.Function{ }, ReturnType: &ast.TypeName{Name: "anyelement"}, }, - { - Name: "unnest", - Args: []*catalog.Argument{ - { - Type: &ast.TypeName{Name: "anyarray"}, - }, - { - Type: &ast.TypeName{Name: "anyarray"}, - Mode: ast.FuncParamVariadic, - }, - }, - ReturnType: &ast.TypeName{Name: "anyelement"}, - }, { Name: "unnest", Args: []*catalog.Argument{ From 770837d0cf5c73c0ed8675f4b350f5c42001c99e Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 11 Oct 2023 18:49:04 -0700 Subject: [PATCH 4/9] Address comments --- examples/authors/sqlc.yaml | 3 +- examples/booktest/sqlc.json | 6 ++- examples/jets/sqlc.json | 4 +- examples/ondeck/sqlc.json | 8 +-- internal/compiler/engine.go | 2 +- internal/compiler/resolve.go | 2 +- internal/config/config.go | 10 ++-- internal/config/v_one.go | 1 + internal/config/v_one.json | 8 +++ internal/config/v_two.json | 8 +++ internal/endtoend/endtoend_test.go | 25 +++++---- .../endtoend/testdata/diff_output/stderr.txt | 54 ------------------- .../postgresql/pgx/v4/stderr.txt | 5 -- .../postgresql/pgx/v4/stderr/base.txt | 2 + .../postgresql/pgx/v4/stderr/managed-db.txt | 2 + internal/sql/validate/func_call.go | 1 - 16 files changed, 59 insertions(+), 82 deletions(-) delete mode 100644 internal/endtoend/testdata/diff_output/stderr.txt delete mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr.txt create mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr/base.txt create mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr/managed-db.txt diff --git a/examples/authors/sqlc.yaml b/examples/authors/sqlc.yaml index f3b5c6586c..9ba523c0d6 100644 --- a/examples/authors/sqlc.yaml +++ b/examples/authors/sqlc.yaml @@ -6,8 +6,9 @@ sql: queries: postgresql/query.sql engine: postgresql database: - analyzer: false managed: true + analyzer: + database: false rules: - sqlc/db-prepare - postgresql-query-too-costly diff --git a/examples/booktest/sqlc.json b/examples/booktest/sqlc.json index af2722bdd0..b1453a2e37 100644 --- a/examples/booktest/sqlc.json +++ b/examples/booktest/sqlc.json @@ -11,8 +11,10 @@ "queries": "postgresql/query.sql", "engine": "postgresql", "database": { - "managed": true, - "analyzer": false + "managed": true + }, + "analyzer": { + "database": false }, "rules": [ "sqlc/db-prepare" diff --git a/examples/jets/sqlc.json b/examples/jets/sqlc.json index 441ad0eb6c..14e80c4291 100644 --- a/examples/jets/sqlc.json +++ b/examples/jets/sqlc.json @@ -11,9 +11,11 @@ "queries": "postgresql/query-building.sql", "engine": "postgresql", "database": { - "analyzer": false, "managed": true }, + "analyzer": { + "database": false + }, "rules": [ "sqlc/db-prepare" ] diff --git a/examples/ondeck/sqlc.json b/examples/ondeck/sqlc.json index 9fceb5e3ad..0eed50f9d7 100644 --- a/examples/ondeck/sqlc.json +++ b/examples/ondeck/sqlc.json @@ -11,8 +11,10 @@ "queries": "postgresql/query", "engine": "postgresql", "database": { - "managed": true, - "analyzer": false + "managed": true + }, + "analyzer": { + "database": false }, "rules": [ "sqlc/db-prepare" @@ -22,7 +24,7 @@ "emit_interface": true }, { - "path": "mysql", + "path": "mysql", "name": "ondeck", "schema": "mysql/schema", "queries": "mysql/query", diff --git a/internal/compiler/engine.go b/internal/compiler/engine.go index 1287ef3e43..bbef2f00d5 100644 --- a/internal/compiler/engine.go +++ b/internal/compiler/engine.go @@ -50,7 +50,7 @@ func NewCompiler(conf config.SQL, combo config.CombinedSettings) (*Compiler, err c.parser = postgresql.NewParser() c.catalog = postgresql.NewCatalog() if conf.Database != nil { - if conf.Database.Analyzer == nil || *conf.Database.Analyzer { + if conf.Analyzer.Database == nil || *conf.Analyzer.Database { c.analyzer = pganalyze.New(c.client, *conf.Database) } } diff --git a/internal/compiler/resolve.go b/internal/compiler/resolve.go index 3b80a7d118..2cb93fabc3 100644 --- a/internal/compiler/resolve.go +++ b/internal/compiler/resolve.go @@ -2,6 +2,7 @@ package compiler import ( "fmt" + "log/slog" "strconv" "github.com/sqlc-dev/sqlc/internal/sql/ast" @@ -10,7 +11,6 @@ import ( "github.com/sqlc-dev/sqlc/internal/sql/named" "github.com/sqlc-dev/sqlc/internal/sql/rewrite" "github.com/sqlc-dev/sqlc/internal/sql/sqlerr" - "golang.org/x/exp/slog" ) func dataType(n *ast.TypeName) string { diff --git a/internal/config/config.go b/internal/config/config.go index a33dd51490..96e5e3bfc0 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -64,9 +64,8 @@ type Config struct { } type Database struct { - URI string `json:"uri" yaml:"uri"` - Managed bool `json:"managed" yaml:"managed"` - Analyzer *bool `json:"analyzer" yaml:"analyzer"` + URI string `json:"uri" yaml:"uri"` + Managed bool `json:"managed" yaml:"managed"` } type Cloud struct { @@ -112,6 +111,11 @@ type SQL struct { Gen SQLGen `json:"gen" yaml:"gen"` Codegen []Codegen `json:"codegen" yaml:"codegen"` Rules []string `json:"rules" yaml:"rules"` + Analyzer Analyzer `json:"analyzer" yaml:"analyzer"` +} + +type Analyzer struct { + Database *bool `json:"database" yaml:"database"` } // TODO: Figure out a better name for this diff --git a/internal/config/v_one.go b/internal/config/v_one.go index 3d2a53f13a..c6dd19be20 100644 --- a/internal/config/v_one.go +++ b/internal/config/v_one.go @@ -53,6 +53,7 @@ type v1PackageSettings struct { QueryParameterLimit *int32 `json:"query_parameter_limit,omitempty" yaml:"query_parameter_limit"` OmitUnusedStructs bool `json:"omit_unused_structs,omitempty" yaml:"omit_unused_structs"` Rules []string `json:"rules" yaml:"rules"` + Analyzer Analyzer `json:"analyzer" yaml:"analyzer"` } func v1ParseConfig(rd io.Reader) (Config, error) { diff --git a/internal/config/v_one.json b/internal/config/v_one.json index e2e8fb03cc..087a7b7495 100644 --- a/internal/config/v_one.json +++ b/internal/config/v_one.json @@ -75,6 +75,14 @@ } } }, + "analyzer": { + "type": "object", + "properties": { + "database": { + "type": "boolean" + } + } + }, "strict_function_checks": { "type": "boolean" }, diff --git a/internal/config/v_two.json b/internal/config/v_two.json index a77f2616df..7b1b69ad13 100644 --- a/internal/config/v_two.json +++ b/internal/config/v_two.json @@ -75,6 +75,14 @@ } } }, + "analyzer": { + "type": "object", + "properties": { + "database": { + "type": "boolean" + } + } + }, "strict_function_checks": { "type": "boolean" }, diff --git a/internal/endtoend/endtoend_test.go b/internal/endtoend/endtoend_test.go index 3e4c7cbc1f..b4d79a6eb1 100644 --- a/internal/endtoend/endtoend_test.go +++ b/internal/endtoend/endtoend_test.go @@ -4,15 +4,16 @@ import ( "bytes" "context" "encoding/json" + "fmt" "os" osexec "os/exec" "path/filepath" + "slices" "strings" "testing" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "golang.org/x/exp/slices" "github.com/sqlc-dev/sqlc/internal/cmd" "github.com/sqlc-dev/sqlc/internal/config" @@ -166,7 +167,7 @@ func TestReplay(t *testing.T) { } } - expected := expectedStderr(t, path) + expected := expectedStderr(t, path, name) opts := cmd.Options{ Env: cmd.Env{ Debug: opts.DebugFromString(args.Env["SQLCDEBUG"]), @@ -202,7 +203,6 @@ func TestReplay(t *testing.T) { } } if diff != "" { - t.Log(stderr.String()) // TODO: Remove t.Fatalf("stderr differed (-want +got):\n%s", diff) } }) @@ -269,15 +269,20 @@ func cmpDirectory(t *testing.T, dir string, actual map[string]string) { } } -func expectedStderr(t *testing.T, dir string) string { +func expectedStderr(t *testing.T, dir, testctx string) string { t.Helper() - path := filepath.Join(dir, "stderr.txt") - if _, err := os.Stat(path); !os.IsNotExist(err) { - blob, err := os.ReadFile(path) - if err != nil { - t.Fatal(err) + paths := []string{ + filepath.Join(dir, "stderr", fmt.Sprintf("%s.txt", testctx)), + filepath.Join(dir, "stderr.txt"), + } + for _, path := range paths { + if _, err := os.Stat(path); !os.IsNotExist(err) { + blob, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + return string(blob) } - return string(blob) } return "" } diff --git a/internal/endtoend/testdata/diff_output/stderr.txt b/internal/endtoend/testdata/diff_output/stderr.txt deleted file mode 100644 index 4db48d8d44..0000000000 --- a/internal/endtoend/testdata/diff_output/stderr.txt +++ /dev/null @@ -1,54 +0,0 @@ ---- a/go/models.go -+++ b/go/models.go -@@ -13,3 +13,8 @@ - Name string - Bio sql.NullString - } -+ -+type Book struct { -+ ID int64 -+ Title string -+} ---- a/go/query.sql.go -+++ b/go/query.sql.go -@@ -31,16 +31,6 @@ - return i, err - } - --const deleteAuthor = `-- name: DeleteAuthor :exec --DELETE FROM authors --WHERE id = $1 --` -- --func (q *Queries) DeleteAuthor(ctx context.Context, id int64) error { -- _, err := q.db.ExecContext(ctx, deleteAuthor, id) -- return err --} -- - const getAuthor = `-- name: GetAuthor :one - SELECT id, name, bio FROM authors - WHERE id = $1 LIMIT 1 -@@ -55,7 +45,7 @@ - - const listAuthors = `-- name: ListAuthors :many - SELECT id, name, bio FROM authors -+ORDER BY bio --ORDER BY name - ` - - func (q *Queries) ListAuthors(ctx context.Context) ([]Author, error) { -@@ -80,3 +70,14 @@ - } - return items, nil - } -+ -+const selectOne = `-- name: SelectOne :one -+SELECT 1 -+` -+ -+func (q *Queries) SelectOne(ctx context.Context) (int32, error) { -+ row := q.db.QueryRowContext(ctx, selectOne) -+ var column_1 int32 -+ err := row.Scan(&column_1) -+ return column_1, err -+} diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr.txt deleted file mode 100644 index 8463ed03b8..0000000000 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -# package querytest -query.sql:1:1: INSERT has more expressions than target columns ---- -# package querytest -query.sql:3:11: INSERT has more expressions than target columns \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr/base.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr/base.txt new file mode 100644 index 0000000000..77fedb8c3a --- /dev/null +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr/base.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:1:1: INSERT has more expressions than target columns \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr/managed-db.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr/managed-db.txt new file mode 100644 index 0000000000..7448a74a95 --- /dev/null +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v4/stderr/managed-db.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:3:11: INSERT has more expressions than target columns \ No newline at end of file diff --git a/internal/sql/validate/func_call.go b/internal/sql/validate/func_call.go index 75a2cd5d37..dad621eb12 100644 --- a/internal/sql/validate/func_call.go +++ b/internal/sql/validate/func_call.go @@ -30,7 +30,6 @@ func (v *funcCallVisitor) Visit(node ast.Node) astutils.Visitor { return v } - // Maybe not necessary now? if fn.Schema == "sqlc" { return nil } From 854758fa8032cdd196cceaeb8b690424733de565 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 11 Oct 2023 18:51:43 -0700 Subject: [PATCH 5/9] No more splitting --- internal/endtoend/endtoend_test.go | 8 +------- .../insert_select_invalid/postgresql/pgx/v5/stderr.txt | 5 ----- .../postgresql/pgx/v5/stderr/base.txt | 2 ++ .../postgresql/pgx/v5/stderr/managed-db.txt | 2 ++ .../insert_select_invalid/postgresql/stdlib/stderr.txt | 5 ----- .../postgresql/stdlib/stderr/base.txt | 2 ++ .../postgresql/stdlib/stderr/managed-db.txt | 2 ++ 7 files changed, 9 insertions(+), 17 deletions(-) delete mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr.txt create mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr/base.txt create mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr/managed-db.txt delete mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr.txt create mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr/base.txt create mode 100644 internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr/managed-db.txt diff --git a/internal/endtoend/endtoend_test.go b/internal/endtoend/endtoend_test.go index b4d79a6eb1..a2b29fa118 100644 --- a/internal/endtoend/endtoend_test.go +++ b/internal/endtoend/endtoend_test.go @@ -195,13 +195,7 @@ func TestReplay(t *testing.T) { t.Fatalf("sqlc %s failed: %s", args.Command, stderr.String()) } - var diff string - for _, expectedErr := range strings.Split(expected, "---\n") { - diff = cmp.Diff(strings.TrimSpace(expectedErr), strings.TrimSpace(stderr.String())) - if diff == "" { - break - } - } + diff := cmp.Diff(strings.TrimSpace(expected), strings.TrimSpace(stderr.String())) if diff != "" { t.Fatalf("stderr differed (-want +got):\n%s", diff) } diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr.txt deleted file mode 100644 index 8463ed03b8..0000000000 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -# package querytest -query.sql:1:1: INSERT has more expressions than target columns ---- -# package querytest -query.sql:3:11: INSERT has more expressions than target columns \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr/base.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr/base.txt new file mode 100644 index 0000000000..77fedb8c3a --- /dev/null +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr/base.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:1:1: INSERT has more expressions than target columns \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr/managed-db.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr/managed-db.txt new file mode 100644 index 0000000000..7448a74a95 --- /dev/null +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/pgx/v5/stderr/managed-db.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:3:11: INSERT has more expressions than target columns \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr.txt deleted file mode 100644 index 3f3bfe37f5..0000000000 --- a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -# package querytest -query.sql:1:1: INSERT has more expressions than target columns ---- -# package querytest -query.sql:3:11: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr/base.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr/base.txt new file mode 100644 index 0000000000..77fedb8c3a --- /dev/null +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr/base.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:1:1: INSERT has more expressions than target columns \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr/managed-db.txt b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr/managed-db.txt new file mode 100644 index 0000000000..95a26a4d4f --- /dev/null +++ b/internal/endtoend/testdata/insert_select_invalid/postgresql/stdlib/stderr/managed-db.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:3:11: INSERT has more expressions than target columns From 7e73bc38888de06f838a0d4b490d31fdd86a43b7 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 11 Oct 2023 18:54:34 -0700 Subject: [PATCH 6/9] fix invalid_func_args --- .../endtoend/testdata/invalid_func_args/pgx/v4/stderr.txt | 5 ----- .../testdata/invalid_func_args/pgx/v4/stderr/base.txt | 2 ++ .../testdata/invalid_func_args/pgx/v4/stderr/managed-db.txt | 2 ++ .../endtoend/testdata/invalid_func_args/pgx/v5/stderr.txt | 5 ----- .../testdata/invalid_func_args/pgx/v5/stderr/base.txt | 2 ++ .../testdata/invalid_func_args/pgx/v5/stderr/managed-db.txt | 2 ++ .../endtoend/testdata/invalid_func_args/stdlib/stderr.txt | 5 ----- .../testdata/invalid_func_args/stdlib/stderr/base.txt | 2 ++ .../testdata/invalid_func_args/stdlib/stderr/managed-db.txt | 2 ++ 9 files changed, 12 insertions(+), 15 deletions(-) delete mode 100644 internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr.txt create mode 100644 internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr/base.txt create mode 100644 internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr/managed-db.txt delete mode 100644 internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr.txt create mode 100644 internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr/base.txt create mode 100644 internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr/managed-db.txt delete mode 100644 internal/endtoend/testdata/invalid_func_args/stdlib/stderr.txt create mode 100644 internal/endtoend/testdata/invalid_func_args/stdlib/stderr/base.txt create mode 100644 internal/endtoend/testdata/invalid_func_args/stdlib/stderr/managed-db.txt diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr.txt b/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr.txt deleted file mode 100644 index a243664087..0000000000 --- a/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -# package querytest -query.sql:1:8: function random(unknown) does not exist ---- -# package querytest -query.sql:1:8: function random(integer) does not exist \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr/base.txt b/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr/base.txt new file mode 100644 index 0000000000..09d46d1f95 --- /dev/null +++ b/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr/base.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:1:8: function random(unknown) does not exist diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr/managed-db.txt b/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr/managed-db.txt new file mode 100644 index 0000000000..34430f733e --- /dev/null +++ b/internal/endtoend/testdata/invalid_func_args/pgx/v4/stderr/managed-db.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:1:8: function random(integer) does not exist diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr.txt b/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr.txt deleted file mode 100644 index eb2957c1b9..0000000000 --- a/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -# package querytest -query.sql:1:8: function random(unknown) does not exist ---- -# package querytest -query.sql:1:8: function random(integer) does not exist diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr/base.txt b/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr/base.txt new file mode 100644 index 0000000000..09d46d1f95 --- /dev/null +++ b/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr/base.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:1:8: function random(unknown) does not exist diff --git a/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr/managed-db.txt b/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr/managed-db.txt new file mode 100644 index 0000000000..34430f733e --- /dev/null +++ b/internal/endtoend/testdata/invalid_func_args/pgx/v5/stderr/managed-db.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:1:8: function random(integer) does not exist diff --git a/internal/endtoend/testdata/invalid_func_args/stdlib/stderr.txt b/internal/endtoend/testdata/invalid_func_args/stdlib/stderr.txt deleted file mode 100644 index eb2957c1b9..0000000000 --- a/internal/endtoend/testdata/invalid_func_args/stdlib/stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -# package querytest -query.sql:1:8: function random(unknown) does not exist ---- -# package querytest -query.sql:1:8: function random(integer) does not exist diff --git a/internal/endtoend/testdata/invalid_func_args/stdlib/stderr/base.txt b/internal/endtoend/testdata/invalid_func_args/stdlib/stderr/base.txt new file mode 100644 index 0000000000..09d46d1f95 --- /dev/null +++ b/internal/endtoend/testdata/invalid_func_args/stdlib/stderr/base.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:1:8: function random(unknown) does not exist diff --git a/internal/endtoend/testdata/invalid_func_args/stdlib/stderr/managed-db.txt b/internal/endtoend/testdata/invalid_func_args/stdlib/stderr/managed-db.txt new file mode 100644 index 0000000000..34430f733e --- /dev/null +++ b/internal/endtoend/testdata/invalid_func_args/stdlib/stderr/managed-db.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:1:8: function random(integer) does not exist From 65ffec2e7753d2872ff5c5edb0a96d18b4626e9e Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 11 Oct 2023 18:57:47 -0700 Subject: [PATCH 7/9] invalid_params --- .../postgresql/{stderr.txt => stderr/base.txt} | 3 --- .../postgresql/stderr/managed-db.txt | 2 ++ .../invalid_params/pgx/v4/{stderr.txt => stderr/base.txt} | 6 ------ .../testdata/invalid_params/pgx/v4/stderr/managed-db.txt | 5 +++++ .../invalid_params/pgx/v5/{stderr.txt => stderr/base.txt} | 6 ------ .../testdata/invalid_params/pgx/v5/stderr/managed-db.txt | 5 +++++ .../invalid_params/stdlib/{stderr.txt => stderr/base.txt} | 6 ------ .../testdata/invalid_params/stdlib/stderr/managed-db.txt | 5 +++++ 8 files changed, 17 insertions(+), 21 deletions(-) rename internal/endtoend/testdata/invalid_group_by_reference/postgresql/{stderr.txt => stderr/base.txt} (50%) create mode 100644 internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr/managed-db.txt rename internal/endtoend/testdata/invalid_params/pgx/v4/{stderr.txt => stderr/base.txt} (53%) create mode 100644 internal/endtoend/testdata/invalid_params/pgx/v4/stderr/managed-db.txt rename internal/endtoend/testdata/invalid_params/pgx/v5/{stderr.txt => stderr/base.txt} (53%) create mode 100644 internal/endtoend/testdata/invalid_params/pgx/v5/stderr/managed-db.txt rename internal/endtoend/testdata/invalid_params/stdlib/{stderr.txt => stderr/base.txt} (53%) create mode 100644 internal/endtoend/testdata/invalid_params/stdlib/stderr/managed-db.txt diff --git a/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr.txt b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr/base.txt similarity index 50% rename from internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr.txt rename to internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr/base.txt index 3981cb4a1e..d686d4f4d8 100644 --- a/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr.txt +++ b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr/base.txt @@ -1,5 +1,2 @@ # package querytest query.sql:4:10: column reference "invalid_reference" not found ---- -# package querytest -query.sql:4:22: column "invalid_reference" does not exist diff --git a/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr/managed-db.txt b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr/managed-db.txt new file mode 100644 index 0000000000..d13cdbaf62 --- /dev/null +++ b/internal/endtoend/testdata/invalid_group_by_reference/postgresql/stderr/managed-db.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:4:22: column "invalid_reference" does not exist diff --git a/internal/endtoend/testdata/invalid_params/pgx/v4/stderr.txt b/internal/endtoend/testdata/invalid_params/pgx/v4/stderr/base.txt similarity index 53% rename from internal/endtoend/testdata/invalid_params/pgx/v4/stderr.txt rename to internal/endtoend/testdata/invalid_params/pgx/v4/stderr/base.txt index 89d645ff49..c74f98d2c2 100644 --- a/internal/endtoend/testdata/invalid_params/pgx/v4/stderr.txt +++ b/internal/endtoend/testdata/invalid_params/pgx/v4/stderr/base.txt @@ -3,9 +3,3 @@ query.sql:1:1: could not determine data type of parameter $1 query.sql:5:1: could not determine data type of parameter $2 query.sql:8:8: column "foo" does not exist query.sql:11:1: could not determine data type of parameter $2 ---- -# package querytest -query.sql:2:8: column "foo" does not exist -query.sql:5:8: column "foo" does not exist -query.sql:8:8: column "foo" does not exist -query.sql:8:20: could not determine data type of parameter $3 \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_params/pgx/v4/stderr/managed-db.txt b/internal/endtoend/testdata/invalid_params/pgx/v4/stderr/managed-db.txt new file mode 100644 index 0000000000..a7eff89c6a --- /dev/null +++ b/internal/endtoend/testdata/invalid_params/pgx/v4/stderr/managed-db.txt @@ -0,0 +1,5 @@ +# package querytest +query.sql:2:8: column "foo" does not exist +query.sql:5:8: column "foo" does not exist +query.sql:8:8: column "foo" does not exist +query.sql:8:20: could not determine data type of parameter $3 diff --git a/internal/endtoend/testdata/invalid_params/pgx/v5/stderr.txt b/internal/endtoend/testdata/invalid_params/pgx/v5/stderr/base.txt similarity index 53% rename from internal/endtoend/testdata/invalid_params/pgx/v5/stderr.txt rename to internal/endtoend/testdata/invalid_params/pgx/v5/stderr/base.txt index 89d645ff49..c74f98d2c2 100644 --- a/internal/endtoend/testdata/invalid_params/pgx/v5/stderr.txt +++ b/internal/endtoend/testdata/invalid_params/pgx/v5/stderr/base.txt @@ -3,9 +3,3 @@ query.sql:1:1: could not determine data type of parameter $1 query.sql:5:1: could not determine data type of parameter $2 query.sql:8:8: column "foo" does not exist query.sql:11:1: could not determine data type of parameter $2 ---- -# package querytest -query.sql:2:8: column "foo" does not exist -query.sql:5:8: column "foo" does not exist -query.sql:8:8: column "foo" does not exist -query.sql:8:20: could not determine data type of parameter $3 \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_params/pgx/v5/stderr/managed-db.txt b/internal/endtoend/testdata/invalid_params/pgx/v5/stderr/managed-db.txt new file mode 100644 index 0000000000..a7eff89c6a --- /dev/null +++ b/internal/endtoend/testdata/invalid_params/pgx/v5/stderr/managed-db.txt @@ -0,0 +1,5 @@ +# package querytest +query.sql:2:8: column "foo" does not exist +query.sql:5:8: column "foo" does not exist +query.sql:8:8: column "foo" does not exist +query.sql:8:20: could not determine data type of parameter $3 diff --git a/internal/endtoend/testdata/invalid_params/stdlib/stderr.txt b/internal/endtoend/testdata/invalid_params/stdlib/stderr/base.txt similarity index 53% rename from internal/endtoend/testdata/invalid_params/stdlib/stderr.txt rename to internal/endtoend/testdata/invalid_params/stdlib/stderr/base.txt index 89d645ff49..c74f98d2c2 100644 --- a/internal/endtoend/testdata/invalid_params/stdlib/stderr.txt +++ b/internal/endtoend/testdata/invalid_params/stdlib/stderr/base.txt @@ -3,9 +3,3 @@ query.sql:1:1: could not determine data type of parameter $1 query.sql:5:1: could not determine data type of parameter $2 query.sql:8:8: column "foo" does not exist query.sql:11:1: could not determine data type of parameter $2 ---- -# package querytest -query.sql:2:8: column "foo" does not exist -query.sql:5:8: column "foo" does not exist -query.sql:8:8: column "foo" does not exist -query.sql:8:20: could not determine data type of parameter $3 \ No newline at end of file diff --git a/internal/endtoend/testdata/invalid_params/stdlib/stderr/managed-db.txt b/internal/endtoend/testdata/invalid_params/stdlib/stderr/managed-db.txt new file mode 100644 index 0000000000..a7eff89c6a --- /dev/null +++ b/internal/endtoend/testdata/invalid_params/stdlib/stderr/managed-db.txt @@ -0,0 +1,5 @@ +# package querytest +query.sql:2:8: column "foo" does not exist +query.sql:5:8: column "foo" does not exist +query.sql:8:8: column "foo" does not exist +query.sql:8:20: could not determine data type of parameter $3 From ea912022e2bf2e2eaa9269d96170408f909108a7 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 11 Oct 2023 19:07:43 -0700 Subject: [PATCH 8/9] Fix last tests --- .../testdata/invalid_queries_bar/pgx/v4/stderr.txt | 7 ------- .../invalid_queries_bar/pgx/v4/stderr/base.txt | 3 +++ .../invalid_queries_bar/pgx/v4/stderr/managed-db.txt | 3 +++ .../testdata/invalid_queries_bar/pgx/v5/stderr.txt | 7 ------- .../invalid_queries_bar/pgx/v5/stderr/base.txt | 3 +++ .../invalid_queries_bar/pgx/v5/stderr/managed-db.txt | 3 +++ .../testdata/invalid_queries_bar/stdlib/stderr.txt | 7 ------- .../invalid_queries_bar/stdlib/stderr/base.txt | 3 +++ .../invalid_queries_bar/stdlib/stderr/managed-db.txt | 3 +++ .../invalid_table_alias/postgresql/stderr/base.txt | 2 ++ .../postgresql/{stderr.txt => stderr/managed-db.txt} | 3 --- .../postgresql/{stderr.txt => stderr/base.txt} | 3 --- .../postgresql/stderr/managed-db.txt | 2 ++ .../relation_does_not_exist/postgresql/stderr.txt | 11 ----------- .../postgresql/stderr/base.txt | 5 +++++ .../postgresql/stderr/managed-db.txt | 5 +++++ .../testdata/sqlc_arg_invalid/postgresql/stderr.txt | 8 +------- .../strict_function_checks/postgresql/stderr.txt | 5 ----- .../strict_function_checks/postgresql/stderr/base.txt | 2 ++ .../postgresql/stderr/managed-db.txt | 2 ++ 20 files changed, 37 insertions(+), 50 deletions(-) delete mode 100644 internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr.txt create mode 100644 internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr/base.txt create mode 100644 internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr/managed-db.txt delete mode 100644 internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr.txt create mode 100644 internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr/base.txt create mode 100644 internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr/managed-db.txt delete mode 100644 internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr.txt create mode 100644 internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr/base.txt create mode 100644 internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr/managed-db.txt create mode 100644 internal/endtoend/testdata/invalid_table_alias/postgresql/stderr/base.txt rename internal/endtoend/testdata/invalid_table_alias/postgresql/{stderr.txt => stderr/managed-db.txt} (51%) rename internal/endtoend/testdata/order_by_non_existing_column/postgresql/{stderr.txt => stderr/base.txt} (66%) create mode 100644 internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr/managed-db.txt delete mode 100644 internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr.txt create mode 100644 internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr/base.txt create mode 100644 internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr/managed-db.txt delete mode 100644 internal/endtoend/testdata/strict_function_checks/postgresql/stderr.txt create mode 100644 internal/endtoend/testdata/strict_function_checks/postgresql/stderr/base.txt create mode 100644 internal/endtoend/testdata/strict_function_checks/postgresql/stderr/managed-db.txt diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr.txt b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr.txt deleted file mode 100644 index fe8035b775..0000000000 --- a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr.txt +++ /dev/null @@ -1,7 +0,0 @@ -# package querytest -query.sql:1:1: INSERT has more target columns than expressions -query.sql:5:1: INSERT has more expressions than target columns ---- -# package querytest -query.sql:2:23: INSERT has more target columns than expressions -query.sql:5:35: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr/base.txt b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr/base.txt new file mode 100644 index 0000000000..1e06800df3 --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr/base.txt @@ -0,0 +1,3 @@ +# package querytest +query.sql:1:1: INSERT has more target columns than expressions +query.sql:5:1: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr/managed-db.txt b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr/managed-db.txt new file mode 100644 index 0000000000..143dcf6c0d --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v4/stderr/managed-db.txt @@ -0,0 +1,3 @@ +# package querytest +query.sql:2:23: INSERT has more target columns than expressions +query.sql:5:35: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr.txt b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr.txt deleted file mode 100644 index fe8035b775..0000000000 --- a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr.txt +++ /dev/null @@ -1,7 +0,0 @@ -# package querytest -query.sql:1:1: INSERT has more target columns than expressions -query.sql:5:1: INSERT has more expressions than target columns ---- -# package querytest -query.sql:2:23: INSERT has more target columns than expressions -query.sql:5:35: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr/base.txt b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr/base.txt new file mode 100644 index 0000000000..1e06800df3 --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr/base.txt @@ -0,0 +1,3 @@ +# package querytest +query.sql:1:1: INSERT has more target columns than expressions +query.sql:5:1: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr/managed-db.txt b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr/managed-db.txt new file mode 100644 index 0000000000..143dcf6c0d --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_bar/pgx/v5/stderr/managed-db.txt @@ -0,0 +1,3 @@ +# package querytest +query.sql:2:23: INSERT has more target columns than expressions +query.sql:5:35: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr.txt b/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr.txt deleted file mode 100644 index fe8035b775..0000000000 --- a/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr.txt +++ /dev/null @@ -1,7 +0,0 @@ -# package querytest -query.sql:1:1: INSERT has more target columns than expressions -query.sql:5:1: INSERT has more expressions than target columns ---- -# package querytest -query.sql:2:23: INSERT has more target columns than expressions -query.sql:5:35: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr/base.txt b/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr/base.txt new file mode 100644 index 0000000000..1e06800df3 --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr/base.txt @@ -0,0 +1,3 @@ +# package querytest +query.sql:1:1: INSERT has more target columns than expressions +query.sql:5:1: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr/managed-db.txt b/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr/managed-db.txt new file mode 100644 index 0000000000..143dcf6c0d --- /dev/null +++ b/internal/endtoend/testdata/invalid_queries_bar/stdlib/stderr/managed-db.txt @@ -0,0 +1,3 @@ +# package querytest +query.sql:2:23: INSERT has more target columns than expressions +query.sql:5:35: INSERT has more expressions than target columns diff --git a/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr/base.txt b/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr/base.txt new file mode 100644 index 0000000000..1eddeaac99 --- /dev/null +++ b/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr/base.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:4:9: table alias "p" does not exist diff --git a/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr.txt b/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr/managed-db.txt similarity index 51% rename from internal/endtoend/testdata/invalid_table_alias/postgresql/stderr.txt rename to internal/endtoend/testdata/invalid_table_alias/postgresql/stderr/managed-db.txt index 896058296f..2de34ae434 100644 --- a/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr.txt +++ b/internal/endtoend/testdata/invalid_table_alias/postgresql/stderr/managed-db.txt @@ -1,5 +1,2 @@ # package querytest -query.sql:4:9: table alias "p" does not exist ---- -# package querytest query.sql:5:3: missing FROM-clause entry for table "p" diff --git a/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr.txt b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr/base.txt similarity index 66% rename from internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr.txt rename to internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr/base.txt index cfdfa539cc..5d9a674dc6 100644 --- a/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr.txt +++ b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr/base.txt @@ -1,5 +1,2 @@ # package querytest query.sql:1:1: column reference "adfadsf" not found: if you want to skip this validation, set 'strict_order_by' to false ---- -# package querytest -query.sql:3:10: column "adfadsf" does not exist \ No newline at end of file diff --git a/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr/managed-db.txt b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr/managed-db.txt new file mode 100644 index 0000000000..55cbb71463 --- /dev/null +++ b/internal/endtoend/testdata/order_by_non_existing_column/postgresql/stderr/managed-db.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:3:10: column "adfadsf" does not exist diff --git a/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr.txt b/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr.txt deleted file mode 100644 index f5e231d552..0000000000 --- a/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr.txt +++ /dev/null @@ -1,11 +0,0 @@ -# package querytest -query.sql:1:1: relation "nonexisting_relation" does not exist -query.sql:5:1: relation "nonexisting_relation" does not exist -query.sql:8:1: relation "nonexisting_relation" does not exist -query.sql:11:1: relation "nonexisting_relation" does not exist ---- -# package querytest -query.sql:2:15: relation "nonexisting_relation" does not exist -query.sql:5:15: relation "nonexisting_relation" does not exist -query.sql:8:8: relation "nonexisting_relation" does not exist -query.sql:11:13: relation "nonexisting_relation" does not exist \ No newline at end of file diff --git a/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr/base.txt b/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr/base.txt new file mode 100644 index 0000000000..0d8930ee17 --- /dev/null +++ b/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr/base.txt @@ -0,0 +1,5 @@ +# package querytest +query.sql:1:1: relation "nonexisting_relation" does not exist +query.sql:5:1: relation "nonexisting_relation" does not exist +query.sql:8:1: relation "nonexisting_relation" does not exist +query.sql:11:1: relation "nonexisting_relation" does not exist diff --git a/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr/managed-db.txt b/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr/managed-db.txt new file mode 100644 index 0000000000..5621f9739e --- /dev/null +++ b/internal/endtoend/testdata/relation_does_not_exist/postgresql/stderr/managed-db.txt @@ -0,0 +1,5 @@ +# package querytest +query.sql:2:15: relation "nonexisting_relation" does not exist +query.sql:5:15: relation "nonexisting_relation" does not exist +query.sql:8:8: relation "nonexisting_relation" does not exist +query.sql:11:13: relation "nonexisting_relation" does not exist diff --git a/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/stderr.txt b/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/stderr.txt index e988a53f2f..8dbea1f949 100644 --- a/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/stderr.txt +++ b/internal/endtoend/testdata/sqlc_arg_invalid/postgresql/stderr.txt @@ -1,13 +1,7 @@ # package querytest -query.sql:7:1: function "sqlc.argh" does not exist -query.sql:10:45: expected 1 parameter to sqlc.arg; got 2 -query.sql:13:45: expected 1 parameter to sqlc.arg; got 0 -query.sql:16:45: expected parameter to sqlc.arg to be string or reference; got *ast.FuncCall -query.sql:19:45: expected parameter to sqlc.arg to be string or reference; got *ast.ParamRef ---- -# package querytest query.sql:1:1: function "sqlc.argh" does not exist query.sql:5:45: expected 1 parameter to sqlc.arg; got 2 query.sql:8:45: expected 1 parameter to sqlc.arg; got 0 query.sql:11:45: expected parameter to sqlc.arg to be string or reference; got *ast.FuncCall query.sql:14:45: expected parameter to sqlc.arg to be string or reference; got *ast.ParamRef + diff --git a/internal/endtoend/testdata/strict_function_checks/postgresql/stderr.txt b/internal/endtoend/testdata/strict_function_checks/postgresql/stderr.txt deleted file mode 100644 index 72392e1535..0000000000 --- a/internal/endtoend/testdata/strict_function_checks/postgresql/stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -# package querytest -query.sql:1:1: function "doesntexist" does not exist ---- -# package querytest -query.sql:2:8: function doesntexist() does not exist diff --git a/internal/endtoend/testdata/strict_function_checks/postgresql/stderr/base.txt b/internal/endtoend/testdata/strict_function_checks/postgresql/stderr/base.txt new file mode 100644 index 0000000000..a8972055f6 --- /dev/null +++ b/internal/endtoend/testdata/strict_function_checks/postgresql/stderr/base.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:1:1: function "doesntexist" does not exist diff --git a/internal/endtoend/testdata/strict_function_checks/postgresql/stderr/managed-db.txt b/internal/endtoend/testdata/strict_function_checks/postgresql/stderr/managed-db.txt new file mode 100644 index 0000000000..16996b66fd --- /dev/null +++ b/internal/endtoend/testdata/strict_function_checks/postgresql/stderr/managed-db.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:2:8: function doesntexist() does not exist From e955bb581603cc1d06634061e28f28cf44b6f052 Mon Sep 17 00:00:00 2001 From: Kyle Conroy Date: Wed, 11 Oct 2023 19:22:17 -0700 Subject: [PATCH 9/9] Fix diff_output test --- .../endtoend/testdata/diff_output/stderr.txt | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 internal/endtoend/testdata/diff_output/stderr.txt diff --git a/internal/endtoend/testdata/diff_output/stderr.txt b/internal/endtoend/testdata/diff_output/stderr.txt new file mode 100644 index 0000000000..e7e455436e --- /dev/null +++ b/internal/endtoend/testdata/diff_output/stderr.txt @@ -0,0 +1,55 @@ +--- a/go/models.go ++++ b/go/models.go +@@ -13,3 +13,8 @@ + Name string + Bio sql.NullString + } ++ ++type Book struct { ++ ID int64 ++ Title string ++} +--- a/go/query.sql.go ++++ b/go/query.sql.go +@@ -31,16 +31,6 @@ + return i, err + } + +-const deleteAuthor = `-- name: DeleteAuthor :exec +-DELETE FROM authors +-WHERE id = $1 +-` +- +-func (q *Queries) DeleteAuthor(ctx context.Context, id int64) error { +- _, err := q.db.ExecContext(ctx, deleteAuthor, id) +- return err +-} +- + const getAuthor = `-- name: GetAuthor :one + SELECT id, name, bio FROM authors + WHERE id = $1 LIMIT 1 +@@ -55,7 +45,7 @@ + + const listAuthors = `-- name: ListAuthors :many + SELECT id, name, bio FROM authors ++ORDER BY bio +-ORDER BY name + ` + + func (q *Queries) ListAuthors(ctx context.Context) ([]Author, error) { +@@ -80,3 +70,14 @@ + } + return items, nil + } ++ ++const selectOne = `-- name: SelectOne :one ++SELECT 1 ++` ++ ++func (q *Queries) SelectOne(ctx context.Context) (int32, error) { ++ row := q.db.QueryRowContext(ctx, selectOne) ++ var column_1 int32 ++ err := row.Scan(&column_1) ++ return column_1, err ++} +