Repository: sqlc-dev/sqlc
Pull request #3313 (2024-04-04 01:52:05)

deps: Bump golang.org/x/net to v0.23.0


Patch:
diff --git a/go.mod b/go.mod
index 7ae554b5c..e7eaea69d 100644
--- a/go.mod
+++ b/go.mod
@@ -58,10 +58,10 @@ require (
 	go.uber.org/atomic v1.11.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	go.uber.org/zap v1.26.0 // indirect
-	golang.org/x/crypto v0.20.0 // indirect
+	golang.org/x/crypto v0.21.0 // indirect
 	golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect
-	golang.org/x/net v0.21.0 // indirect
-	golang.org/x/sys v0.17.0 // indirect
+	golang.org/x/net v0.23.0 // indirect
+	golang.org/x/sys v0.18.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
diff --git a/go.sum b/go.sum
index 3adb56ab0..c05feef80 100644
--- a/go.sum
+++ b/go.sum
@@ -223,8 +223,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
-golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
+golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
+golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
 golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w=
 golang.org/x/exp v0.0.0-20231108232855-2478ac86f678/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -237,8 +237,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
-golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
+golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
 golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
@@ -255,8 +255,8 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
-golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
+golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/internal/compiler/query_catalog.go b/internal/compiler/query_catalog.go
index 96b42be7f..80b59d876 100644
--- a/internal/compiler/query_catalog.go
+++ b/internal/compiler/query_catalog.go
@@ -9,15 +9,13 @@ import (
 )
 
 type QueryCatalog struct {
-	catalog     *catalog.Catalog
-	ctes        map[string]*Table
-	fromClauses map[string]*Table
-	embeds      rewrite.EmbedSet
+	catalog *catalog.Catalog
+	ctes    map[string]*Table
+	embeds  rewrite.EmbedSet
 }
 
 func (comp *Compiler) buildQueryCatalog(c *catalog.Catalog, node ast.Node, embeds rewrite.EmbedSet) (*QueryCatalog, error) {
 	var with *ast.WithClause
-	var from *ast.List
 	switch n := node.(type) {
 	case *ast.DeleteStmt:
 		with = n.WithClause
@@ -25,20 +23,12 @@ func (comp *Compiler) buildQueryCatalog(c *catalog.Catalog, node ast.Node, embed
 		with = n.WithClause
 	case *ast.UpdateStmt:
 		with = n.WithClause
-		from = n.FromClause
 	case *ast.SelectStmt:
 		with = n.WithClause
-		from = n.FromClause
 	default:
 		with = nil
-		from = nil
-	}
-	qc := &QueryCatalog{
-		catalog:     c,
-		ctes:        map[string]*Table{},
-		fromClauses: map[string]*Table{},
-		embeds:      embeds,
 	}
+	qc := &QueryCatalog{catalog: c, ctes: map[string]*Table{}, embeds: embeds}
 	if with != nil {
 		for _, item := range with.Ctes.Items {
 			if cte, ok := item.(*ast.CommonTableExpr); ok {
@@ -70,37 +60,6 @@ func (comp *Compiler) buildQueryCatalog(c *catalog.Catalog, node ast.Node, embed
 			}
 		}
 	}
-	if from != nil {
-		for _, item := range from.Items {
-			if rs, ok := item.(*ast.RangeSubselect); ok {
-				cols, err := comp.outputColumns(qc, rs.Subquery)
-				if err != nil {
-					return nil, err
-				}
-				var names []string
-				if rs.Alias.Colnames != nil {
-					for _, item := range rs.Alias.Colnames.Items {
-						if val, ok := item.(*ast.String); ok {
-							names = append(names, val.Str)
-						} else {
-							names = append(names, "")
-						}
-					}
-				}
-				rel := &ast.TableName{Name: *rs.Alias.Aliasname}
-				for i := range cols {
-					cols[i].Table = rel
-					if len(names) > i {
-						cols[i].Name = names[i]
-					}
-				}
-				qc.fromClauses[*rs.Alias.Aliasname] = &Table{
-					Rel:     rel,
-					Columns: cols,
-				}
-			}
-		}
-	}
 	return qc, nil
 }
 
diff --git a/internal/compiler/resolve.go b/internal/compiler/resolve.go
index a001a9ace..b1fbb1990 100644
--- a/internal/compiler/resolve.go
+++ b/internal/compiler/resolve.go
@@ -67,38 +67,7 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
 				continue
 			}
 			// If the table name doesn't exist, first check if it's a CTE
-			catTable, qcerr := qc.GetTable(fqn)
-			if qcerr != nil {
-				return nil, err
-			}
-
-			// If it's a CTE, add it to the alias map and add its columns to
-			// the type map. This is to allow us to resolve references to the
-			// CTE's columns in a query.
-			aliasMap[fqn.Name] = fqn
-			if rv.Alias != nil {
-				aliasMap[*rv.Alias.Aliasname] = fqn
-			}
-
-			catCols := make([]*catalog.Column, 0, len(catTable.Columns))
-			for _, col := range catTable.Columns {
-				catCols = append(catCols, &catalog.Column{
-					Name:       col.Name,
-					Type:       ast.TypeName{Name: col.DataType},
-					IsNotNull:  col.NotNull,
-					IsUnsigned: col.Unsigned,
-					IsArray:    col.IsArray,
-					ArrayDims:  col.ArrayDims,
-					Comment:    col.Comment,
-					Length:     col.Length,
-				})
-			}
-
-			err = indexTable(catalog.Table{
-				Rel:     catTable.Rel,
-				Columns: catCols,
-			})
-			if err != nil {
+			if _, qcerr := qc.GetTable(fqn); qcerr != nil {
 				return nil, err
 			}
 			continue
@@ -111,28 +80,6 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar,
 			aliasMap[*rv.Alias.Aliasname] = fqn
 		}
 	}
-	for _, f := range qc.fromClauses {
-		catCols := make([]*catalog.Column, 0, len(f.Columns))
-		for _, col := range f.Columns {
-			catCols = append(catCols, &catalog.Column{
-				Name:       col.Name,
-				Type:       ast.TypeName{Name: col.DataType},
-				IsNotNull:  col.NotNull,
-				IsUnsigned: col.Unsigned,
-				IsArray:    col.IsArray,
-				ArrayDims:  col.ArrayDims,
-				Comment:    col.Comment,
-				Length:     col.Length,
-			})
-		}
-
-		if err := indexTable(catalog.Table{
-			Rel:     f.Rel,
-			Columns: catCols,
-		}); err != nil {
-			return nil, err
-		}
-	}
 
 	// resolve a table for an embed
 	for _, embed := range embeds {
diff --git a/internal/pgx/poolcache/poolcache.go b/internal/pgx/poolcache/poolcache.go
new file mode 100644
index 000000000..93401ec93
--- /dev/null
+++ b/internal/pgx/poolcache/poolcache.go
@@ -0,0 +1,32 @@
+package poolcache
+
+import (
+	"context"
+	"sync"
+
+	"github.com/jackc/pgx/v5/pgxpool"
+)
+
+var lock sync.RWMutex
+var pools = map[string]*pgxpool.Pool{}
+
+func New(ctx context.Context, uri string) (*pgxpool.Pool, error) {
+	lock.RLock()
+	existing, found := pools[uri]
+	lock.RUnlock()
+
+	if found {
+		return existing, nil
+	}
+
+	pool, err := pgxpool.New(ctx, uri)
+	if err != nil {
+		return nil, err
+	}
+
+	lock.Lock()
+	pools[uri] = pool
+	lock.Unlock()
+
+	return pool, nil
+}


Test patch:
diff --git a/internal/endtoend/endtoend_test.go b/internal/endtoend/endtoend_test.go
index 8420340d8..c2792ee1d 100644
--- a/internal/endtoend/endtoend_test.go
+++ b/internal/endtoend/endtoend_test.go
@@ -120,7 +120,6 @@ func TestReplay(t *testing.T) {
 		"managed-db": {
 			Mutate: func(t *testing.T, path string) func(*config.Config) {
 				return func(c *config.Config) {
-					c.Cloud.Project = "01HAQMMECEYQYKFJN8MP16QC41" // TODO: Read from environment
 					for i := range c.SQL {
 						files := []string{}
 						for _, s := range c.SQL[i].Schema {
@@ -128,7 +127,7 @@ func TestReplay(t *testing.T) {
 						}
 						switch c.SQL[i].Engine {
 						case config.EnginePostgreSQL:
-							uri := local.PostgreSQL(t, files)
+							uri := local.ReadOnlyPostgreSQL(t, files)
 							c.SQL[i].Database = &config.Database{
 								URI: uri,
 							}
@@ -138,18 +137,12 @@ func TestReplay(t *testing.T) {
 						// 		URI: uri,
 						// 	}
 						default:
-							c.SQL[i].Database = &config.Database{
-								Managed: true,
-							}
+							// pass
 						}
 					}
 				}
 			},
 			Enabled: func() bool {
-				// Return false if no auth token exists
-				if len(os.Getenv("SQLC_AUTH_TOKEN")) == 0 {
-					return false
-				}
 				if len(os.Getenv("POSTGRESQL_SERVER_URI")) == 0 {
 					return false
 				}
diff --git a/internal/endtoend/testdata/cte_resolve_ref/issue.md b/internal/endtoend/testdata/cte_resolve_ref/issue.md
deleted file mode 100644
index 9268a7d1f..000000000
--- a/internal/endtoend/testdata/cte_resolve_ref/issue.md
+++ /dev/null
@@ -1,2 +0,0 @@
-https://github.com/sqlc-dev/sqlc/issues/3219
-
diff --git a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/go/db.go b/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/go/db.go
deleted file mode 100644
index 7c111fd4e..000000000
--- a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/go/db.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Code generated by sqlc. DO NOT EDIT.
-// versions:
-//   sqlc v1.26.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_resolve_ref/postgresql/pgx/go/models.go b/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/go/models.go
deleted file mode 100644
index 9099b926b..000000000
--- a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/go/models.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Code generated by sqlc. DO NOT EDIT.
-// versions:
-//   sqlc v1.26.0
-
-package querytest
-
-type T1 struct {
-	ID int32
-}
-
-type T2 struct {
-	ID int32
-}
diff --git a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/go/query.sql.go
deleted file mode 100644
index d4fb8b9c5..000000000
--- a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/go/query.sql.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Code generated by sqlc. DO NOT EDIT.
-// versions:
-//   sqlc v1.26.0
-// source: query.sql
-
-package querytest
-
-import (
-	"context"
-)
-
-const cTEMultipleRefs = `-- name: CTEMultipleRefs :one
-WITH t1_ids AS (
-    SELECT id FROM t1 WHERE t1.id = $1
-),
-t2_ids AS (
-    SELECT id FROM t2 WHERE t2.id = $1
-),
-all_ids AS (
-    SELECT id FROM t1_ids
-    UNION
-    SELECT id FROM t2_ids
-)
-SELECT id FROM all_ids AS ids WHERE ids.id = $1
-`
-
-func (q *Queries) CTEMultipleRefs(ctx context.Context, id int32) (int32, error) {
-	row := q.db.QueryRow(ctx, cTEMultipleRefs, id)
-	err := row.Scan(&id)
-	return id, err
-}
-
-const cTERef = `-- name: CTERef :one
-WITH t1_ids AS (
-    SELECT id FROM t1
-)
-SELECT id FROM t1_ids WHERE t1_ids.id = $1
-`
-
-func (q *Queries) CTERef(ctx context.Context, id int32) (int32, error) {
-	row := q.db.QueryRow(ctx, cTERef, id)
-	err := row.Scan(&id)
-	return id, err
-}
diff --git a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/query.sql b/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/query.sql
deleted file mode 100644
index 39c87dfc3..000000000
--- a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/query.sql
+++ /dev/null
@@ -1,21 +0,0 @@
--- name: CTERef :one
-WITH t1_ids AS (
-    SELECT id FROM t1
-)
-SELECT * FROM t1_ids WHERE t1_ids.id = sqlc.arg('id');
-
--- name: CTEMultipleRefs :one
-WITH t1_ids AS (
-    SELECT id FROM t1 WHERE t1.id = sqlc.arg('id')
-),
-t2_ids AS (
-    SELECT id FROM t2 WHERE t2.id = sqlc.arg('id')
-),
-all_ids AS (
-    SELECT * FROM t1_ids
-    UNION
-    SELECT * FROM t2_ids
-)
-SELECT * FROM all_ids AS ids WHERE ids.id = sqlc.arg('id');
-
-
diff --git a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/schema.sql b/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/schema.sql
deleted file mode 100644
index 3029ac89b..000000000
--- a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/schema.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-CREATE TABLE t1
-(
-    id SERIAL NOT NULL PRIMARY KEY
-);
-
-CREATE TABLE t2
-(
-    id SERIAL NOT NULL PRIMARY KEY
-);
diff --git a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/sqlc.yaml
deleted file mode 100644
index 01489e0ff..000000000
--- a/internal/endtoend/testdata/cte_resolve_ref/postgresql/pgx/sqlc.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-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/golang_initialisms_url/schema.sql b/internal/endtoend/testdata/golang_initialisms_url/schema.sql
index 83ab16012..d0b250690 100644
--- a/internal/endtoend/testdata/golang_initialisms_url/schema.sql
+++ b/internal/endtoend/testdata/golang_initialisms_url/schema.sql
@@ -1,4 +1,4 @@
-CREATE TABLE foo(
+CREATE TABLE foo (
         bar_id text,
         site_url text
 );
diff --git a/internal/endtoend/testdata/golang_invalid_sql_package/schema.sql b/internal/endtoend/testdata/golang_invalid_sql_package/schema.sql
index 1bd72529f..e29621be5 100644
--- a/internal/endtoend/testdata/golang_invalid_sql_package/schema.sql
+++ b/internal/endtoend/testdata/golang_invalid_sql_package/schema.sql
@@ -1,3 +1,3 @@
-CREATE TABLE foo(
+CREATE TABLE foo (
         bar text
 );
diff --git a/internal/endtoend/testdata/join_alias/mysql/go/query.sql.go b/internal/endtoend/testdata/join_alias/mysql/go/query.sql.go
index e6d565560..836f62c6d 100644
--- a/internal/endtoend/testdata/join_alias/mysql/go/query.sql.go
+++ b/internal/endtoend/testdata/join_alias/mysql/go/query.sql.go
@@ -80,57 +80,3 @@ func (q *Queries) AliasJoin(ctx context.Context, id uint64) ([]AliasJoinRow, err
 	}
 	return items, nil
 }
-
-const columnAlias = `-- name: ColumnAlias :many
-SELECT n FROM (SELECT 1 AS n) AS x WHERE n <= ?
-`
-
-func (q *Queries) ColumnAlias(ctx context.Context, n int32) ([]int32, error) {
-	rows, err := q.db.QueryContext(ctx, columnAlias, n)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-	var items []int32
-	for rows.Next() {
-		var n int32
-		if err := rows.Scan(&n); err != nil {
-			return nil, err
-		}
-		items = append(items, n)
-	}
-	if err := rows.Close(); err != nil {
-		return nil, err
-	}
-	if err := rows.Err(); err != nil {
-		return nil, err
-	}
-	return items, nil
-}
-
-const subqueryAlias = `-- name: SubqueryAlias :many
-SELECT n FROM (SELECT 1 AS n) AS x WHERE x.n <= ?
-`
-
-func (q *Queries) SubqueryAlias(ctx context.Context, n int32) ([]int32, error) {
-	rows, err := q.db.QueryContext(ctx, subqueryAlias, n)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-	var items []int32
-	for rows.Next() {
-		var n int32
-		if err := rows.Scan(&n); err != nil {
-			return nil, err
-		}
-		items = append(items, n)
-	}
-	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/join_alias/mysql/query.sql b/internal/endtoend/testdata/join_alias/mysql/query.sql
index 82bb2e5cd..9b087bcae 100644
--- a/internal/endtoend/testdata/join_alias/mysql/query.sql
+++ b/internal/endtoend/testdata/join_alias/mysql/query.sql
@@ -9,9 +9,3 @@ SELECT *
 FROM foo f
 JOIN bar b ON b.id = f.id
 WHERE f.id = ?;
-
--- name: SubqueryAlias :many
-SELECT * FROM (SELECT 1 AS n) AS x WHERE x.n <= ?;
-
--- name: ColumnAlias :many
-SELECT * FROM (SELECT 1 AS n) AS x WHERE n <= ?;
diff --git a/internal/endtoend/testdata/schema_scoped_filter/mysql/schema.sql b/internal/endtoend/testdata/schema_scoped_filter/mysql/schema.sql
index a22ab0907..e5cb43f4b 100644
--- a/internal/endtoend/testdata/schema_scoped_filter/mysql/schema.sql
+++ b/internal/endtoend/testdata/schema_scoped_filter/mysql/schema.sql
@@ -1,3 +1,2 @@
 CREATE SCHEMA foo;
 CREATE TABLE foo.bar (id serial not null);
-
diff --git a/internal/sqltest/local/postgres.go b/internal/sqltest/local/postgres.go
index a283273ac..3520d42b8 100644
--- a/internal/sqltest/local/postgres.go
+++ b/internal/sqltest/local/postgres.go
@@ -3,23 +3,31 @@ package local
 import (
 	"context"
 	"fmt"
+	"hash/fnv"
 	"net/url"
 	"os"
 	"strings"
-	"sync"
 	"testing"
 
 	"github.com/jackc/pgx/v5"
-	"github.com/jackc/pgx/v5/pgxpool"
+	"golang.org/x/sync/singleflight"
 
 	migrate "github.com/sqlc-dev/sqlc/internal/migrations"
+	"github.com/sqlc-dev/sqlc/internal/pgx/poolcache"
 	"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
 )
 
-var postgresPool *pgxpool.Pool
-var postgresSync sync.Once
+var flight singleflight.Group
 
 func PostgreSQL(t *testing.T, migrations []string) string {
+	return postgreSQL(t, migrations, true)
+}
+
+func ReadOnlyPostgreSQL(t *testing.T, migrations []string) string {
+	return postgreSQL(t, migrations, false)
+}
+
+func postgreSQL(t *testing.T, migrations []string, rw bool) string {
 	ctx := context.Background()
 	t.Helper()
 
@@ -28,16 +36,9 @@ func PostgreSQL(t *testing.T, migrations []string) string {
 		t.Skip("POSTGRESQL_SERVER_URI is empty")
 	}
 
-	postgresSync.Do(func() {
-		pool, err := pgxpool.New(ctx, dburi)
-		if err != nil {
-			t.Fatal(err)
-		}
-		postgresPool = pool
-	})
-
-	if postgresPool == nil {
-		t.Fatalf("PostgreSQL pool creation failed")
+	postgresPool, err := poolcache.New(ctx, dburi)
+	if err != nil {
+		t.Fatalf("PostgreSQL pool creation failed: %s", err)
 	}
 
 	var seed []string
@@ -45,48 +46,73 @@ func PostgreSQL(t *testing.T, migrations []string) string {
 	if err != nil {
 		t.Fatal(err)
 	}
+
+	h := fnv.New64()
 	for _, f := range files {
 		blob, err := os.ReadFile(f)
 		if err != nil {
 			t.Fatal(err)
 		}
+		h.Write(blob)
 		seed = append(seed, migrate.RemoveRollbackStatements(string(blob)))
 	}
 
-	uri, err := url.Parse(dburi)
-	if err != nil {
-		t.Fatal(err)
+	var name string
+	if rw {
+		name = fmt.Sprintf("sqlc_test_%s", id())
+	} else {
+		name = fmt.Sprintf("sqlc_test_%x", h.Sum(nil))
 	}
 
-	name := fmt.Sprintf("sqlc_test_%s", id())
-
-	if _, err := postgresPool.Exec(ctx, fmt.Sprintf(`CREATE DATABASE "%s"`, name)); err != nil {
+	uri, err := url.Parse(dburi)
+	if err != nil {
 		t.Fatal(err)
 	}
-
 	uri.Path = name
 	dropQuery := fmt.Sprintf(`DROP DATABASE IF EXISTS "%s" WITH (FORCE)`, name)
 
-	t.Cleanup(func() {
-		if _, err := postgresPool.Exec(ctx, dropQuery); err != nil {
-			t.Fatal(err)
+	key := uri.String()
+
+	_, err, _ = flight.Do(key, func() (interface{}, error) {
+		row := postgresPool.QueryRow(ctx,
+			fmt.Sprintf(`SELECT datname FROM pg_database WHERE datname = '%s'`, name))
+
+		var datname string
+		if err := row.Scan(&datname); err == nil {
+			t.Logf("database exists: %s", name)
+			return nil, nil
 		}
-	})
 
-	conn, err := pgx.Connect(ctx, uri.String())
-	if err != nil {
-		t.Fatalf("connect %s: %s", name, err)
-	}
-	defer conn.Close(ctx)
+		t.Logf("creating database: %s", name)
+		if _, err := postgresPool.Exec(ctx, fmt.Sprintf(`CREATE DATABASE "%s"`, name)); err != nil {
+			return nil, err
+		}
 
-	for _, q := range seed {
-		if len(strings.TrimSpace(q)) == 0 {
-			continue
+		conn, err := pgx.Connect(ctx, uri.String())
+		if err != nil {
+			return nil, fmt.Errorf("connect %s: %s", name, err)
 		}
-		if _, err := conn.Exec(ctx, q); err != nil {
-			t.Fatalf("%s: %s", q, err)
+		defer conn.Close(ctx)
+
+		for _, q := range seed {
+			if len(strings.TrimSpace(q)) == 0 {
+				continue
+			}
+			if _, err := conn.Exec(ctx, q); err != nil {
+				return nil, fmt.Errorf("%s: %s", q, err)
+			}
 		}
+		return nil, nil
+	})
+	if rw || err != nil {
+		t.Cleanup(func() {
+			if _, err := postgresPool.Exec(ctx, dropQuery); err != nil {
+				t.Fatalf("failed cleaning up: %s", err)
+			}
+		})
 	}
-
-	return uri.String()
+	if err != nil {
+		t.Fatalf("create db: %s", err)
+	}
+	return key
 }
diff --git a/scripts/cleanup-test-dbs/main.go b/scripts/cleanup-test-dbs/main.go
new file mode 100644
index 000000000..51093db30
--- /dev/null
+++ b/scripts/cleanup-test-dbs/main.go
@@ -0,0 +1,55 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"log"
+	"os"
+
+	"github.com/jackc/pgx/v5"
+	"github.com/jackc/pgx/v5/pgxpool"
+)
+
+func main() {
+	if err := run(); err != nil {
+		log.Fatal(err)
+	}
+}
+
+const query = `
+SELECT datname
+FROM pg_database
+WHERE datname LIKE 'sqlc_test_%'
+`
+
+func run() error {
+	ctx := context.Background()
+	dburi := os.Getenv("POSTGRESQL_SERVER_URI")
+	if dburi == "" {
+		return fmt.Errorf("POSTGRESQL_SERVER_URI is empty")
+	}
+	pool, err := pgxpool.New(ctx, dburi)
+	if err != nil {
+		return err
+	}
+
+	rows, err := pool.Query(ctx, query)
+	if err != nil {
+		return err
+	}
+
+	names, err := pgx.CollectRows(rows, pgx.RowTo[string])
+	if err != nil {
+		return err
+	}
+
+	for _, name := range names {
+		drop := fmt.Sprintf(`DROP DATABASE IF EXISTS "%s" WITH (FORCE)`, name)
+		if _, err := pool.Exec(ctx, drop); err != nil {
+			return err
+		}
+		log.Println("dropping database", name)
+	}
+
+	return nil
+}