From 9ab0cebe4581005d5de74b1d7743c36313c10339 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 22:22:25 +0000 Subject: [PATCH 1/5] build: upgrade to Go 1.26.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Go version across the project: - go.mod: 1.24.7 → 1.26.0 - CI workflows (ci.yml, build.yml): 1.25.0 → 1.26.0 - CI plugin workflows (ci-python, ci-kotlin, ci-typescript): 1.24.1 → 1.26.0 - Dockerfile: 1.25.5 → 1.26.0 - CLAUDE.md: update prerequisite version https://claude.ai/code/session_01WLKDmB7kemgPsjsj9KFEXa --- .github/workflows/build.yml | 2 +- .github/workflows/ci-kotlin.yml | 2 +- .github/workflows/ci-python.yml | 2 +- .github/workflows/ci-typescript.yml | 2 +- .github/workflows/ci.yml | 4 ++-- CLAUDE.md | 2 +- Dockerfile | 2 +- go.mod | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7595757ddd..b15a5ea75b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: - go-version: '1.25.0' + go-version: '1.26.0' - name: install ./... run: go build ./... env: diff --git a/.github/workflows/ci-kotlin.yml b/.github/workflows/ci-kotlin.yml index b011cb997f..a324917ed7 100644 --- a/.github/workflows/ci-kotlin.yml +++ b/.github/workflows/ci-kotlin.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: - go-version: '1.24.1' + go-version: '1.26.0' - name: install ./... run: go install ./... - uses: actions/checkout@v6 diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 940a5008b0..a59bd402c3 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: - go-version: '1.24.1' + go-version: '1.26.0' - name: install ./... run: go install ./... - uses: actions/checkout@v6 diff --git a/.github/workflows/ci-typescript.yml b/.github/workflows/ci-typescript.yml index d08c7ba8f0..7ec747a91f 100644 --- a/.github/workflows/ci-typescript.yml +++ b/.github/workflows/ci-typescript.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: - go-version: '1.24.1' + go-version: '1.26.0' - name: install ./... run: go install ./... - uses: actions/checkout@v6 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5959992750..e2324c05f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: - go-version: '1.25.0' + go-version: '1.26.0' - run: go build ./... env: CGO_ENABLED: "0" @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: - go-version: '1.25.0' + go-version: '1.26.0' - name: install gotestsum run: go install gotest.tools/gotestsum@latest diff --git a/CLAUDE.md b/CLAUDE.md index 43abb0d491..b8337d5426 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,7 +6,7 @@ This document provides essential information for working with the sqlc codebase, ### Prerequisites -- **Go 1.25.0+** - Required for building and testing +- **Go 1.26.0+** - Required for building and testing - **Docker & Docker Compose** - Required for integration tests with databases (local development) - **Git** - For version control diff --git a/Dockerfile b/Dockerfile index 05a93abf7e..1c78fb107e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # STEP 1: Build sqlc -FROM golang:1.25.5 AS builder +FROM golang:1.26.0 AS builder COPY . /workspace WORKDIR /workspace diff --git a/go.mod b/go.mod index f3c92bfd78..f27750e6fb 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/sqlc-dev/sqlc -go 1.24.7 +go 1.26.0 require ( github.com/antlr4-go/antlr/v4 v4.13.1 From be1b0398edceea54f0b1f3452f4312d1909478b3 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 22:23:45 +0000 Subject: [PATCH 2/5] chore: add sqlc binary to .gitignore Prevent accidentally committing the compiled sqlc binary. https://claude.ai/code/session_01WLKDmB7kemgPsjsj9KFEXa --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 39961ebb02..c030d23e2a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/sqlc /.idea/ __pycache__ .DS_Store From 885349da3d844fee7c8b3c0e77107fb9f20481a8 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 18 Feb 2026 05:49:26 +0000 Subject: [PATCH 3/5] docs: document Go module proxy setup in remote environment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HTTP_PROXY/HTTPS_PROXY env vars are pre-configured in the Claude Code remote environment and Go's toolchain respects them automatically. Document this so future sessions don't waste time debugging module fetching. Also improve the troubleshooting section with actionable steps. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude https://claude.ai/code/session_01WLKDmB7kemgPsjsj9KFEXa --- CLAUDE.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index b8337d5426..e9d0da109f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,9 +14,13 @@ This document provides essential information for working with the sqlc codebase, When running in the Claude Code remote environment (or any environment without Docker), you can install PostgreSQL and MySQL natively. The test framework automatically detects and uses native database installations. +### Network Proxy (Pre-configured) + +The Claude Code remote environment routes outbound traffic through an HTTP proxy via the `HTTP_PROXY` and `HTTPS_PROXY` environment variables. **Go module operations (`go mod tidy`, `go mod download`, `go get`, etc.) work automatically** because Go's toolchain respects these variables. No extra configuration is needed for the Go module proxy (`proxy.golang.org`) or checksum database (`sum.golang.org`). + ### Step 1: Configure apt Proxy (Required in Remote Environment) -The Claude Code remote environment requires an HTTP proxy for apt. Configure it: +The apt package manager needs its own proxy configuration since it does not read `HTTP_PROXY`: ```bash bash -c 'echo "Acquire::http::Proxy \"$http_proxy\";"' | sudo tee /etc/apt/apt.conf.d/99proxy @@ -306,9 +310,13 @@ POSTGRESQL_SERVER_URI="postgres://postgres:mysecretpassword@localhost:5432/postg ## Common Issues & Solutions -### Network Connectivity Issues +### Network Connectivity / Go Module Proxy Issues + +In the Claude Code remote environment, Go module fetching works automatically via the `HTTP_PROXY`/`HTTPS_PROXY` environment variables. If you see errors about `storage.googleapis.com` or `proxy.golang.org`: -If you see errors about `storage.googleapis.com`, the Go proxy may be unreachable. Tests may still pass for packages that don't require network dependencies. +1. **Verify proxy vars are set:** `echo $HTTP_PROXY` (should be non-empty in the remote environment) +2. **Test connectivity:** `go mod download 2>&1 | head` to check for errors +3. **If proxy is not set** (e.g., local development without Docker), Go will try to reach `proxy.golang.org` directly, which requires internet access ### Test Timeouts From 03369a7dfe766e7d4fee9fa440629cb3949978f3 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 18 Feb 2026 06:11:30 +0000 Subject: [PATCH 4/5] fix: handle stopped Docker containers in test setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The docker test helpers checked if a container existed via `docker container inspect`, but this returns true for stopped/exited containers too. When a container existed but wasn't running, the code skipped creation and went straight to pinging — which timed out after 10s. Extract an ensureContainer helper that: 1. Inspects the container state (not just existence) 2. Runs `docker start` if the container exists but is stopped 3. Creates via `docker run` if the container doesn't exist 4. Handles the race where a parallel test process creates the container between our inspect and run calls 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude https://claude.ai/code/session_01WLKDmB7kemgPsjsj9KFEXa --- internal/sqltest/docker/enabled.go | 42 +++++++++++++++++++++++++++++ internal/sqltest/docker/mysql.go | 33 ++++++----------------- internal/sqltest/docker/postgres.go | 35 +++++++----------------- 3 files changed, 59 insertions(+), 51 deletions(-) diff --git a/internal/sqltest/docker/enabled.go b/internal/sqltest/docker/enabled.go index e17c0201b2..3196d0ea97 100644 --- a/internal/sqltest/docker/enabled.go +++ b/internal/sqltest/docker/enabled.go @@ -3,6 +3,7 @@ package docker import ( "fmt" "os/exec" + "strings" "golang.org/x/sync/singleflight" ) @@ -15,3 +16,44 @@ func Installed() error { } return nil } + +// ensureContainer makes sure a Docker container with the given name is running. +// It handles three cases: +// 1. Container doesn't exist: create it with docker run +// 2. Container exists but stopped: start it with docker start +// 3. Container exists and running: do nothing +// +// It also handles the race condition where a parallel test process creates the +// container between our inspect and run calls. +func ensureContainer(name string, runArgs ...string) error { + // Check if container exists and whether it's running + output, err := exec.Command("docker", "container", "inspect", + "-f", "{{.State.Running}}", name).CombinedOutput() + + if err == nil { + // Container exists — check if it's running + if strings.TrimSpace(string(output)) != "true" { + // Container exists but is stopped, start it + if startOut, startErr := exec.Command("docker", "start", name).CombinedOutput(); startErr != nil { + return fmt.Errorf("docker start %s: %s: %w", name, string(startOut), startErr) + } + } + return nil + } + + // Container doesn't exist, create it + args := append([]string{"run", "--name", name}, runArgs...) + createOut, createErr := exec.Command("docker", args...).CombinedOutput() + + if createErr != nil { + // Handle race: another process may have created the container between + // our inspect and run calls + conflictMsg := fmt.Sprintf(`Conflict. The container name "/%s" is already in use`, name) + if strings.Contains(string(createOut), conflictMsg) { + return nil + } + return fmt.Errorf("docker run %s: %s: %w", name, string(createOut), createErr) + } + + return nil +} diff --git a/internal/sqltest/docker/mysql.go b/internal/sqltest/docker/mysql.go index 39a1af6160..c9706a9f59 100644 --- a/internal/sqltest/docker/mysql.go +++ b/internal/sqltest/docker/mysql.go @@ -5,7 +5,6 @@ import ( "database/sql" "fmt" "os/exec" - "strings" "time" _ "github.com/go-sql-driver/mysql" @@ -46,30 +45,14 @@ func startMySQLServer(c context.Context) (string, error) { } } - var exists bool - { - cmd := exec.Command("docker", "container", "inspect", "sqlc_sqltest_docker_mysql") - // This means we've already started the container - exists = cmd.Run() == nil - } - - if !exists { - cmd := exec.Command("docker", "run", - "--name", "sqlc_sqltest_docker_mysql", - "-e", "MYSQL_ROOT_PASSWORD=mysecretpassword", - "-e", "MYSQL_DATABASE=dinotest", - "-p", "3306:3306", - "-d", - "mysql:9", - ) - - output, err := cmd.CombinedOutput() - fmt.Println(string(output)) - - msg := `Conflict. The container name "/sqlc_sqltest_docker_mysql" is already in use by container` - if !strings.Contains(string(output), msg) && err != nil { - return "", err - } + if err := ensureContainer("sqlc_sqltest_docker_mysql", + "-e", "MYSQL_ROOT_PASSWORD=mysecretpassword", + "-e", "MYSQL_DATABASE=dinotest", + "-p", "3306:3306", + "-d", + "mysql:9", + ); err != nil { + return "", err } ctx, cancel := context.WithTimeout(c, 10*time.Second) diff --git a/internal/sqltest/docker/postgres.go b/internal/sqltest/docker/postgres.go index 1b2d842c70..d17fdac68c 100644 --- a/internal/sqltest/docker/postgres.go +++ b/internal/sqltest/docker/postgres.go @@ -5,7 +5,6 @@ import ( "fmt" "log/slog" "os/exec" - "strings" "time" "github.com/jackc/pgx/v5" @@ -48,31 +47,15 @@ func startPostgreSQLServer(c context.Context) (string, error) { uri := "postgres://postgres:mysecretpassword@localhost:5432/postgres?sslmode=disable" - var exists bool - { - cmd := exec.Command("docker", "container", "inspect", "sqlc_sqltest_docker_postgres") - // This means we've already started the container - exists = cmd.Run() == nil - } - - if !exists { - cmd := exec.Command("docker", "run", - "--name", "sqlc_sqltest_docker_postgres", - "-e", "POSTGRES_PASSWORD=mysecretpassword", - "-e", "POSTGRES_USER=postgres", - "-p", "5432:5432", - "-d", - "postgres:16", - "-c", "max_connections=200", - ) - - output, err := cmd.CombinedOutput() - fmt.Println(string(output)) - - msg := `Conflict. The container name "/sqlc_sqltest_docker_postgres" is already in use by container` - if !strings.Contains(string(output), msg) && err != nil { - return "", err - } + if err := ensureContainer("sqlc_sqltest_docker_postgres", + "-e", "POSTGRES_PASSWORD=mysecretpassword", + "-e", "POSTGRES_USER=postgres", + "-p", "5432:5432", + "-d", + "postgres:16", + "-c", "max_connections=200", + ); err != nil { + return "", err } ctx, cancel := context.WithTimeout(c, 5*time.Second) From efb3fdc588ee5fd677b7d1aea22a97c072cbe8be Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 18 Feb 2026 06:25:41 +0000 Subject: [PATCH 5/5] refactor: apply go fix modernizations for Go 1.26 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run `go fix ./...` to apply automated code modernizations: - interface{} → any - Remove unnecessary loop variable copies (Go 1.22+ semantics) - String concatenation → strings.Builder - Manual loops → slices.Contains, maps.Copy - strings.Split → strings.SplitSeq where applicable - Remove redundant struct tags 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude https://claude.ai/code/session_01WLKDmB7kemgPsjsj9KFEXa --- internal/cmd/cmd.go | 2 +- internal/cmd/createdb.go | 1 - internal/codegen/golang/field.go | 20 ++++++++++---------- internal/codegen/golang/gen.go | 7 +++---- internal/codegen/golang/go_type.go | 9 +++------ internal/codegen/golang/opts/go_type.go | 2 +- internal/codegen/golang/result.go | 10 +++++----- internal/codegen/golang/struct.go | 2 +- internal/compiler/output_columns.go | 1 - internal/config/config.go | 10 +++++----- internal/config/convert/convert.go | 6 +++--- internal/dbmanager/client.go | 2 +- internal/debug/dump.go | 2 +- internal/endtoend/ddl_test.go | 2 -- internal/endtoend/endtoend_test.go | 3 --- internal/endtoend/fmt_test.go | 2 -- internal/engine/postgresql/catalog.go | 4 +++- internal/engine/sqlite/analyzer/analyze.go | 4 ++-- internal/engine/sqlite/parse.go | 2 +- internal/ext/wasm/wasm.go | 2 +- internal/metadata/meta.go | 2 +- internal/opts/debug.go | 2 +- internal/opts/experiment.go | 2 +- internal/pattern/match.go | 17 +++++++++-------- internal/rpc/interceptor.go | 2 +- internal/source/code.go | 8 ++++---- internal/sql/ast/param_exec_data.go | 2 +- internal/sql/ast/param_list_info_data.go | 4 ++-- internal/sql/astutils/rewrite.go | 2 +- internal/sqltest/docker/mysql.go | 2 +- internal/sqltest/docker/postgres.go | 2 +- internal/sqltest/local/postgres.go | 2 +- internal/sqltest/native/mysql.go | 2 +- internal/sqltest/native/postgres.go | 2 +- internal/tools/sqlc-pg-gen/main.go | 2 +- internal/x/expander/expander_test.go | 2 +- scripts/test-json-process-plugin/main.go | 6 +++--- 37 files changed, 72 insertions(+), 82 deletions(-) diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index 80a167353e..b7c82f58da 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -100,7 +100,7 @@ var initCmd = &cobra.Command{ if err != nil { return err } - var yamlConfig interface{} + var yamlConfig any if useV1 { yamlConfig = config.V1GenerateSettings{Version: "1"} } else { diff --git a/internal/cmd/createdb.go b/internal/cmd/createdb.go index 02b3031352..09536816d3 100644 --- a/internal/cmd/createdb.go +++ b/internal/cmd/createdb.go @@ -47,7 +47,6 @@ func CreateDB(ctx context.Context, dir, filename, querySetName string, o *Option var queryset *config.SQL var count int for _, sql := range conf.SQL { - sql := sql if querySetName != "" && sql.Name != querySetName { continue } diff --git a/internal/codegen/golang/field.go b/internal/codegen/golang/field.go index 2a63b6d342..90ea1a7529 100644 --- a/internal/codegen/golang/field.go +++ b/internal/codegen/golang/field.go @@ -97,23 +97,23 @@ func toPascalCase(s string) string { } func toCamelInitCase(name string, initUpper bool) string { - out := "" + var out strings.Builder for i, p := range strings.Split(name, "_") { if !initUpper && i == 0 { - out += p + out.WriteString(p) continue } if p == "id" { - out += "ID" + out.WriteString("ID") } else { - out += strings.Title(p) + out.WriteString(strings.Title(p)) } } - return out + return out.String() } func toJsonCamelCase(name string, idUppercase bool) string { - out := "" + var out strings.Builder idStr := "Id" if idUppercase { @@ -122,16 +122,16 @@ func toJsonCamelCase(name string, idUppercase bool) string { for i, p := range strings.Split(name, "_") { if i == 0 { - out += p + out.WriteString(p) continue } if p == "id" { - out += idStr + out.WriteString(idStr) } else { - out += strings.Title(p) + out.WriteString(strings.Title(p)) } } - return out + return out.String() } func toLowerCase(str string) string { diff --git a/internal/codegen/golang/gen.go b/internal/codegen/golang/gen.go index 7df56a0a41..9c29b9da9e 100644 --- a/internal/codegen/golang/gen.go +++ b/internal/codegen/golang/gen.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "go/format" + "slices" "strings" "text/template" @@ -344,10 +345,8 @@ func usesCopyFrom(queries []Query) bool { func usesBatch(queries []Query) bool { for _, q := range queries { - for _, cmd := range []string{metadata.CmdBatchExec, metadata.CmdBatchMany, metadata.CmdBatchOne} { - if q.Cmd == cmd { - return true - } + if slices.Contains([]string{metadata.CmdBatchExec, metadata.CmdBatchMany, metadata.CmdBatchOne}, q.Cmd) { + return true } } return false diff --git a/internal/codegen/golang/go_type.go b/internal/codegen/golang/go_type.go index c4aac84dd6..21914736d0 100644 --- a/internal/codegen/golang/go_type.go +++ b/internal/codegen/golang/go_type.go @@ -1,6 +1,7 @@ package golang import ( + "maps" "strings" "github.com/sqlc-dev/sqlc/internal/codegen/golang/opts" @@ -15,9 +16,7 @@ func addExtraGoStructTags(tags map[string]string, req *plugin.GenerateRequest, o continue } if override.MatchesColumn(col) { - for k, v := range oride.GoType.StructTags { - tags[k] = v - } + maps.Copy(tags, oride.GoType.StructTags) continue } if !override.Matches(col.Table, req.Catalog.DefaultSchema) { @@ -33,9 +32,7 @@ func addExtraGoStructTags(tags map[string]string, req *plugin.GenerateRequest, o continue } // Add the extra tags. - for k, v := range oride.GoType.StructTags { - tags[k] = v - } + maps.Copy(tags, oride.GoType.StructTags) } } diff --git a/internal/codegen/golang/opts/go_type.go b/internal/codegen/golang/opts/go_type.go index 5dcb3e8af0..723594cffb 100644 --- a/internal/codegen/golang/opts/go_type.go +++ b/internal/codegen/golang/opts/go_type.go @@ -51,7 +51,7 @@ func (o *GoType) UnmarshalJSON(data []byte) error { return nil } -func (o *GoType) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (o *GoType) UnmarshalYAML(unmarshal func(any) error) error { var spec string if err := unmarshal(&spec); err == nil { *o = GoType{Spec: spec} diff --git a/internal/codegen/golang/result.go b/internal/codegen/golang/result.go index 0820488f9d..fa48e27e93 100644 --- a/internal/codegen/golang/result.go +++ b/internal/codegen/golang/result.go @@ -168,17 +168,17 @@ func paramName(p *plugin.Parameter) string { } func argName(name string) string { - out := "" + var out strings.Builder for i, p := range strings.Split(name, "_") { if i == 0 { - out += strings.ToLower(p) + out.WriteString(strings.ToLower(p)) } else if p == "id" { - out += "ID" + out.WriteString("ID") } else { - out += strings.Title(p) + out.WriteString(strings.Title(p)) } } - return out + return out.String() } func buildQueries(req *plugin.GenerateRequest, options *opts.Options, structs []Struct) ([]Query, error) { diff --git a/internal/codegen/golang/struct.go b/internal/codegen/golang/struct.go index ed9311800e..f52eb4947d 100644 --- a/internal/codegen/golang/struct.go +++ b/internal/codegen/golang/struct.go @@ -31,7 +31,7 @@ func StructName(name string, options *opts.Options) string { return rune('_') }, name) - for _, p := range strings.Split(name, "_") { + for p := range strings.SplitSeq(name, "_") { if _, found := options.InitialismsMap[p]; found { out += strings.ToUpper(p) } else { diff --git a/internal/compiler/output_columns.go b/internal/compiler/output_columns.go index dbd486359a..6cc2567ebe 100644 --- a/internal/compiler/output_columns.go +++ b/internal/compiler/output_columns.go @@ -517,7 +517,6 @@ 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: diff --git a/internal/config/config.go b/internal/config/config.go index d3e610ef05..ff7faedcaa 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -36,7 +36,7 @@ func (p *Paths) UnmarshalJSON(data []byte) error { return nil } -func (p *Paths) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (p *Paths) UnmarshalYAML(unmarshal func(any) error) error { out := []string{} if sliceErr := unmarshal(&out); sliceErr != nil { var ele string @@ -61,7 +61,7 @@ type Config struct { Cloud Cloud `json:"cloud" yaml:"cloud"` Servers []Server `json:"servers" yaml:"servers"` SQL []SQL `json:"sql" yaml:"sql"` - Overrides Overrides `json:"overrides,omitempty" yaml:"overrides"` + Overrides Overrides `json:"overrides" yaml:"overrides"` Plugins []Plugin `json:"plugins" yaml:"plugins"` Rules []Rule `json:"rules" yaml:"rules"` Options map[string]yaml.Node `json:"options" yaml:"options"` @@ -125,8 +125,8 @@ type SQL struct { // AnalyzerDatabase represents the database analyzer setting. // It can be a boolean (true/false) or the string "only" for database-only mode. type AnalyzerDatabase struct { - value *bool // nil means not set, true/false for boolean values - isOnly bool // true when set to "only" + value *bool // nil means not set, true/false for boolean values + isOnly bool // true when set to "only" } // IsEnabled returns true if the database analyzer should be used. @@ -166,7 +166,7 @@ func (a *AnalyzerDatabase) UnmarshalJSON(data []byte) error { return errors.New("analyzer.database must be true, false, or \"only\"") } -func (a *AnalyzerDatabase) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (a *AnalyzerDatabase) UnmarshalYAML(unmarshal func(any) error) error { // Try to unmarshal as boolean first var b bool if err := unmarshal(&b); err == nil { diff --git a/internal/config/convert/convert.go b/internal/config/convert/convert.go index 2bd0550886..a1fd2881ce 100644 --- a/internal/config/convert/convert.go +++ b/internal/config/convert/convert.go @@ -8,11 +8,11 @@ import ( "gopkg.in/yaml.v3" ) -func gen(n *yaml.Node) (interface{}, error) { +func gen(n *yaml.Node) (any, error) { switch n.Kind { case yaml.MappingNode: - nn := map[string]interface{}{} + nn := map[string]any{} for i, _ := range n.Content { if i%2 == 0 { k := n.Content[i] @@ -26,7 +26,7 @@ func gen(n *yaml.Node) (interface{}, error) { return nn, nil case yaml.SequenceNode: - nn := []interface{}{} + nn := []any{} for i, _ := range n.Content { v, err := gen(n.Content[i]) if err != nil { diff --git a/internal/dbmanager/client.go b/internal/dbmanager/client.go index 18aec947cb..2c49433aef 100644 --- a/internal/dbmanager/client.go +++ b/internal/dbmanager/client.go @@ -90,7 +90,7 @@ func (m *ManagedClient) CreateDatabase(ctx context.Context, req *CreateDatabaseR uri.Path = "/" + name key := uri.String() - _, err, _ = flight.Do(key, func() (interface{}, error) { + _, err, _ = flight.Do(key, func() (any, error) { // TODO: Use a parameterized query row := pool.QueryRow(ctx, fmt.Sprintf(`SELECT datname FROM pg_database WHERE datname = '%s'`, name)) diff --git a/internal/debug/dump.go b/internal/debug/dump.go index 6921ecb67f..9756328556 100644 --- a/internal/debug/dump.go +++ b/internal/debug/dump.go @@ -20,7 +20,7 @@ func init() { } } -func Dump(n ...interface{}) { +func Dump(n ...any) { if Active { spew.Dump(n) } diff --git a/internal/endtoend/ddl_test.go b/internal/endtoend/ddl_test.go index bed9333743..36b0aaa131 100644 --- a/internal/endtoend/ddl_test.go +++ b/internal/endtoend/ddl_test.go @@ -12,7 +12,6 @@ import ( func TestValidSchema(t *testing.T) { for _, replay := range FindTests(t, "testdata", "base") { - replay := replay // https://golang.org/doc/faq#closures_and_goroutines if replay.Exec != nil { if replay.Exec.Meta.InvalidSchema { @@ -32,7 +31,6 @@ func TestValidSchema(t *testing.T) { } for j, pkg := range conf.SQL { - j, pkg := j, pkg switch pkg.Engine { case config.EnginePostgreSQL: // pass diff --git a/internal/endtoend/endtoend_test.go b/internal/endtoend/endtoend_test.go index 7634918446..648bb03255 100644 --- a/internal/endtoend/endtoend_test.go +++ b/internal/endtoend/endtoend_test.go @@ -221,8 +221,6 @@ func TestReplay(t *testing.T) { } for name, testctx := range contexts { - name := name - testctx := testctx if !testctx.Enabled() { continue @@ -354,7 +352,6 @@ func cmpDirectory(t *testing.T, dir string, actual map[string]string) { if !cmp.Equal(expected, actual, opts...) { t.Errorf("%s contents differ", dir) for name, contents := range expected { - name := name if actual[name] == "" { t.Errorf("%s is empty", name) return diff --git a/internal/endtoend/fmt_test.go b/internal/endtoend/fmt_test.go index eac3fa0390..886ab419e8 100644 --- a/internal/endtoend/fmt_test.go +++ b/internal/endtoend/fmt_test.go @@ -31,7 +31,6 @@ type sqlFormatter interface { func TestFormat(t *testing.T) { t.Parallel() for _, tc := range FindTests(t, "testdata", "base") { - tc := tc t.Run(tc.Name, func(t *testing.T) { // Parse the config file to determine the engine configPath := filepath.Join(tc.Path, tc.ConfigName) @@ -145,7 +144,6 @@ func TestFormat(t *testing.T) { } for i, stmt := range stmts { - stmt := stmt t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { // Extract the original query text using statement location and length start := stmt.Raw.StmtLocation diff --git a/internal/engine/postgresql/catalog.go b/internal/engine/postgresql/catalog.go index 3c262122a2..e11fe21222 100644 --- a/internal/engine/postgresql/catalog.go +++ b/internal/engine/postgresql/catalog.go @@ -4,8 +4,10 @@ import "github.com/sqlc-dev/sqlc/internal/sql/catalog" // toPointer converts an int to a pointer without a temporary // variable at the call-site, and is used by the generated schemas +// +//go:fix inline func toPointer(x int) *int { - return &x + return new(x) } func NewCatalog() *catalog.Catalog { diff --git a/internal/engine/sqlite/analyzer/analyze.go b/internal/engine/sqlite/analyzer/analyze.go index 3af9f99a30..c9e6a167be 100644 --- a/internal/engine/sqlite/analyzer/analyze.go +++ b/internal/engine/sqlite/analyzer/analyze.go @@ -87,7 +87,7 @@ func (a *Analyzer) Analyze(ctx context.Context, n ast.Node, query string, migrat // Get column information colCount := stmt.ColumnCount() - for i := 0; i < colCount; i++ { + for i := range colCount { name := stmt.ColumnName(i) declType := stmt.ColumnDeclType(i) tableName := stmt.ColumnTableName(i) @@ -249,7 +249,7 @@ func (a *Analyzer) GetColumnNames(ctx context.Context, query string) ([]string, colCount := stmt.ColumnCount() columns := make([]string, colCount) - for i := 0; i < colCount; i++ { + for i := range colCount { columns[i] = stmt.ColumnName(i) } diff --git a/internal/engine/sqlite/parse.go b/internal/engine/sqlite/parse.go index 13425b156e..5de4c3a69e 100644 --- a/internal/engine/sqlite/parse.go +++ b/internal/engine/sqlite/parse.go @@ -17,7 +17,7 @@ type errorListener struct { err string } -func (el *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) { +func (el *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol any, line, column int, msg string, e antlr.RecognitionException) { el.err = msg } diff --git a/internal/ext/wasm/wasm.go b/internal/ext/wasm/wasm.go index 58384a9c95..7653676493 100644 --- a/internal/ext/wasm/wasm.go +++ b/internal/ext/wasm/wasm.go @@ -59,7 +59,7 @@ func (r *Runner) loadAndCompile(ctx context.Context) (*runtimeAndCode, error) { if err != nil { return nil, err } - value, err, _ := flight.Do(expected, func() (interface{}, error) { + value, err, _ := flight.Do(expected, func() (any, error) { return r.loadAndCompileWASM(ctx, cacheDir, expected) }) if err != nil { diff --git a/internal/metadata/meta.go b/internal/metadata/meta.go index 8f63624d2c..76ee992a7a 100644 --- a/internal/metadata/meta.go +++ b/internal/metadata/meta.go @@ -59,7 +59,7 @@ func validateQueryName(name string) error { } func ParseQueryNameAndType(t string, commentStyle CommentSyntax) (string, string, error) { - for _, line := range strings.Split(t, "\n") { + for line := range strings.SplitSeq(t, "\n") { var prefix string if strings.HasPrefix(line, "--") { if !commentStyle.Dash { diff --git a/internal/opts/debug.go b/internal/opts/debug.go index b92cbd4ae8..96f2fb06a7 100644 --- a/internal/opts/debug.go +++ b/internal/opts/debug.go @@ -39,7 +39,7 @@ func DebugFromString(val string) Debug { if val == "" { return d } - for _, pair := range strings.Split(val, ",") { + for pair := range strings.SplitSeq(val, ",") { pair = strings.TrimSpace(pair) switch { case pair == "dumpast=1": diff --git a/internal/opts/experiment.go b/internal/opts/experiment.go index 45a1c11e05..e37c35db60 100644 --- a/internal/opts/experiment.go +++ b/internal/opts/experiment.go @@ -47,7 +47,7 @@ func ExperimentFromString(val string) Experiment { return e } - for _, name := range strings.Split(val, ",") { + for name := range strings.SplitSeq(val, ",") { name = strings.TrimSpace(name) if name == "" { continue diff --git a/internal/pattern/match.go b/internal/pattern/match.go index 1cf8afb1e4..c72663d463 100644 --- a/internal/pattern/match.go +++ b/internal/pattern/match.go @@ -3,6 +3,7 @@ package pattern import ( "fmt" "regexp" + "strings" "sync" ) @@ -42,16 +43,16 @@ func MatchCompile(pattern string) (*Match, error) { } func matchCompile(pattern string) (match *Match, err error) { - regex := "" + var regex strings.Builder escaped := false arr := []byte(pattern) - for i := 0; i < len(arr); i++ { + for i := range arr { if escaped { escaped = false switch arr[i] { case '*', '?', '\\': - regex += "\\" + string(arr[i]) + regex.WriteString("\\" + string(arr[i])) default: return nil, fmt.Errorf("Invalid escaped character '%c'", arr[i]) } @@ -60,13 +61,13 @@ func matchCompile(pattern string) (match *Match, err error) { case '\\': escaped = true case '*': - regex += ".*" + regex.WriteString(".*") case '?': - regex += "." + regex.WriteString(".") case '.', '(', ')', '+', '|', '^', '$', '[', ']', '{', '}': - regex += "\\" + string(arr[i]) + regex.WriteString("\\" + string(arr[i])) default: - regex += string(arr[i]) + regex.WriteString(string(arr[i])) } } } @@ -77,7 +78,7 @@ func matchCompile(pattern string) (match *Match, err error) { var r *regexp.Regexp - if r, err = regexp.Compile("^" + regex + "$"); err != nil { + if r, err = regexp.Compile("^" + regex.String() + "$"); err != nil { return nil, err } diff --git a/internal/rpc/interceptor.go b/internal/rpc/interceptor.go index ac0490bd1a..6d8dc798b1 100644 --- a/internal/rpc/interceptor.go +++ b/internal/rpc/interceptor.go @@ -8,7 +8,7 @@ import ( "google.golang.org/grpc/status" ) -func UnaryInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { +func UnaryInterceptor(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { err := invoker(ctx, method, req, reply, cc, opts...) switch status.Convert(err).Code() { diff --git a/internal/source/code.go b/internal/source/code.go index 8b88a24136..e7ef0f5880 100644 --- a/internal/source/code.go +++ b/internal/source/code.go @@ -110,8 +110,8 @@ func StripComments(sql string) (string, []string, error) { if strings.HasPrefix(t, "# name:") { continue } - if strings.HasPrefix(t, "--") { - comments = append(comments, strings.TrimPrefix(t, "--")) + if after, ok := strings.CutPrefix(t, "--"); ok { + comments = append(comments, after) continue } if strings.HasPrefix(t, "/*") && strings.HasSuffix(t, "*/") { @@ -120,8 +120,8 @@ func StripComments(sql string) (string, []string, error) { comments = append(comments, t) continue } - if strings.HasPrefix(t, "#") { - comments = append(comments, strings.TrimPrefix(t, "#")) + if after, ok := strings.CutPrefix(t, "#"); ok { + comments = append(comments, after) continue } lines = append(lines, t) diff --git a/internal/sql/ast/param_exec_data.go b/internal/sql/ast/param_exec_data.go index 83e9b04f9a..0d8c3db9bf 100644 --- a/internal/sql/ast/param_exec_data.go +++ b/internal/sql/ast/param_exec_data.go @@ -1,7 +1,7 @@ package ast type ParamExecData struct { - ExecPlan interface{} + ExecPlan any Value Datum Isnull bool } diff --git a/internal/sql/ast/param_list_info_data.go b/internal/sql/ast/param_list_info_data.go index 1275124244..a3fa0796e2 100644 --- a/internal/sql/ast/param_list_info_data.go +++ b/internal/sql/ast/param_list_info_data.go @@ -1,8 +1,8 @@ package ast type ParamListInfoData struct { - ParamFetchArg interface{} - ParserSetupArg interface{} + ParamFetchArg any + ParserSetupArg any NumParams int ParamMask []uint32 } diff --git a/internal/sql/astutils/rewrite.go b/internal/sql/astutils/rewrite.go index fc7996b5f5..25b274a16c 100644 --- a/internal/sql/astutils/rewrite.go +++ b/internal/sql/astutils/rewrite.go @@ -120,7 +120,7 @@ type application struct { func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.Node) { // convert typed nil into untyped nil - if v := reflect.ValueOf(n); v.Kind() == reflect.Ptr && v.IsNil() { + if v := reflect.ValueOf(n); v.Kind() == reflect.Pointer && v.IsNil() { n = nil } diff --git a/internal/sqltest/docker/mysql.go b/internal/sqltest/docker/mysql.go index c9706a9f59..fecef886e9 100644 --- a/internal/sqltest/docker/mysql.go +++ b/internal/sqltest/docker/mysql.go @@ -19,7 +19,7 @@ func StartMySQLServer(c context.Context) (string, error) { if mysqlHost != "" { return mysqlHost, nil } - value, err, _ := flight.Do("mysql", func() (interface{}, error) { + value, err, _ := flight.Do("mysql", func() (any, error) { host, err := startMySQLServer(c) if err != nil { return "", err diff --git a/internal/sqltest/docker/postgres.go b/internal/sqltest/docker/postgres.go index d17fdac68c..15ec860871 100644 --- a/internal/sqltest/docker/postgres.go +++ b/internal/sqltest/docker/postgres.go @@ -19,7 +19,7 @@ func StartPostgreSQLServer(c context.Context) (string, error) { if postgresHost != "" { return postgresHost, nil } - value, err, _ := flight.Do("postgresql", func() (interface{}, error) { + value, err, _ := flight.Do("postgresql", func() (any, error) { host, err := startPostgreSQLServer(c) if err != nil { return "", err diff --git a/internal/sqltest/local/postgres.go b/internal/sqltest/local/postgres.go index 243a7133ab..7b5a848dc7 100644 --- a/internal/sqltest/local/postgres.go +++ b/internal/sqltest/local/postgres.go @@ -91,7 +91,7 @@ func postgreSQL(t *testing.T, migrations []string, rw bool) string { key := uri.String() - _, err, _ = flight.Do(key, func() (interface{}, error) { + _, err, _ = flight.Do(key, func() (any, error) { row := postgresPool.QueryRow(ctx, fmt.Sprintf(`SELECT datname FROM pg_database WHERE datname = '%s'`, name)) diff --git a/internal/sqltest/native/mysql.go b/internal/sqltest/native/mysql.go index 69482bace6..924e23b13b 100644 --- a/internal/sqltest/native/mysql.go +++ b/internal/sqltest/native/mysql.go @@ -23,7 +23,7 @@ func StartMySQLServer(ctx context.Context) (string, error) { if mysqlURI != "" { return mysqlURI, nil } - value, err, _ := mysqlFlight.Do("mysql", func() (interface{}, error) { + value, err, _ := mysqlFlight.Do("mysql", func() (any, error) { uri, err := startMySQLServer(ctx) if err != nil { return "", err diff --git a/internal/sqltest/native/postgres.go b/internal/sqltest/native/postgres.go index f805a40a1c..91b7f56afe 100644 --- a/internal/sqltest/native/postgres.go +++ b/internal/sqltest/native/postgres.go @@ -23,7 +23,7 @@ func StartPostgreSQLServer(ctx context.Context) (string, error) { if postgresURI != "" { return postgresURI, nil } - value, err, _ := postgresFlight.Do("postgresql", func() (interface{}, error) { + value, err, _ := postgresFlight.Do("postgresql", func() (any, error) { uri, err := startPostgreSQLServer(ctx) if err != nil { return "", err diff --git a/internal/tools/sqlc-pg-gen/main.go b/internal/tools/sqlc-pg-gen/main.go index d70dcb9595..0b1a99d309 100644 --- a/internal/tools/sqlc-pg-gen/main.go +++ b/internal/tools/sqlc-pg-gen/main.go @@ -304,7 +304,7 @@ func run(ctx context.Context) error { name := strings.Replace(extension, "-", "_", -1) var funcName string - for _, part := range strings.Split(name, "_") { + for part := range strings.SplitSeq(name, "_") { funcName += strings.Title(part) } diff --git a/internal/x/expander/expander_test.go b/internal/x/expander/expander_test.go index 84de74cdf3..195eeb9ea8 100644 --- a/internal/x/expander/expander_test.go +++ b/internal/x/expander/expander_test.go @@ -101,7 +101,7 @@ func (g *SQLiteColumnGetter) GetColumnNames(ctx context.Context, query string) ( // Get column names from the prepared statement count := stmt.ColumnCount() columns := make([]string, count) - for i := 0; i < count; i++ { + for i := range count { columns[i] = stmt.ColumnName(i) } diff --git a/scripts/test-json-process-plugin/main.go b/scripts/test-json-process-plugin/main.go index 6bcc7a25d0..471e0206ef 100644 --- a/scripts/test-json-process-plugin/main.go +++ b/scripts/test-json-process-plugin/main.go @@ -17,7 +17,7 @@ type File struct { } func main() { - in := make(map[string]interface{}) + in := make(map[string]any) decoder := json.NewDecoder(os.Stdin) err := decoder.Decode(&in) if err != nil { @@ -26,9 +26,9 @@ func main() { } buf := bytes.NewBuffer(nil) - queries := in["queries"].([]interface{}) + queries := in["queries"].([]any) for _, q := range queries { - text := q.(map[string]interface{})["text"].(string) + text := q.(map[string]any)["text"].(string) buf.WriteString(text) buf.WriteString("\n") }