From 96d17d80fa2c95798efb8529f349044f08fa5384 Mon Sep 17 00:00:00 2001 From: Chris Hundt Date: Thu, 16 Apr 2026 15:03:22 -0400 Subject: [PATCH 1/2] Support search_path in postgres+rds-iam scheme Also, use "config" param when adding a search path to a regular postgres DSN because that is supported by both psql and the Go pq library, whereas search_path is only supported by the latter. --- pgutils/connector.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/pgutils/connector.go b/pgutils/connector.go index f859c0b..6868c4e 100644 --- a/pgutils/connector.go +++ b/pgutils/connector.go @@ -143,7 +143,10 @@ func addSearchPathToURL(rawURL string, searchPath string) (string, error) { if v := q.Get("search_path"); v != "" { return "", fmt.Errorf("search_path already set to %q", v) } - q.Set("search_path", searchPath) + if v := q.Get("options"); v != "" { + return "", fmt.Errorf("options already set to %q", v) + } + q.Set("options", fmt.Sprintf("-csearch_path=%s", searchPath)) u.RawQuery = q.Encode() return u.String(), nil } @@ -247,6 +250,7 @@ func newIAMConnectionStringProviderFromURL(ctx context.Context, u *url.URL, onTo supportedParams := map[string]struct{}{ "assume_role_arn": {}, "assume_role_session_name": {}, + "search_path": {}, } for k := range q { if _, ok := supportedParams[k]; !ok { @@ -278,7 +282,7 @@ func newIAMConnectionStringProviderFromURL(ctx context.Context, u *url.URL, onTo creds = aws.NewCredentialsCache(assumeProvider) } - return &rdsIAMConnectionStringProvider{ + var p ConnectionStringProvider = &rdsIAMConnectionStringProvider{ Region: awsCfg.Region, RDSEndpoint: net.JoinHostPort(host, port), User: user, @@ -287,5 +291,11 @@ func newIAMConnectionStringProviderFromURL(ctx context.Context, u *url.URL, onTo AssumeRoleARN: assumeRoleARN, AssumeRoleSessionName: sessionName, OnTokenSign: onTokenSign, - }, nil + } + + if searchPath := q.Get("search_path"); searchPath != "" { + p = WithSchemaSearchPath(p, searchPath) + } + + return p, nil } From d4a1462fc2b0351f8b0ab7674b5100487a8bc82d Mon Sep 17 00:00:00 2001 From: Chris Hundt Date: Mon, 20 Apr 2026 13:48:49 -0400 Subject: [PATCH 2/2] Address review comments --- pgutils/connector.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pgutils/connector.go b/pgutils/connector.go index 6868c4e..0fa35a5 100644 --- a/pgutils/connector.go +++ b/pgutils/connector.go @@ -127,23 +127,20 @@ func MustConnectDB(conn driver.Connector) *sqlx.DB { return db } -// addSearchPathToURL returns a copy of u with search_path set in the query string. -// It returns an error if search_path is already present. +// addSearchPathToURL returns a copy of u with search_path set in the options parameter +// of the query string. It returns an error if the search_path or options parameter is +// already present. func addSearchPathToURL(rawURL string, searchPath string) (string, error) { u, err := url.Parse(rawURL) if err != nil { return "", fmt.Errorf("url string failed to parse while adding search path: %w", err) } - if searchPath == "" { - return u.String(), nil - } - q := u.Query() - if v := q.Get("search_path"); v != "" { + if v, ok := q["search_path"]; ok { return "", fmt.Errorf("search_path already set to %q", v) } - if v := q.Get("options"); v != "" { + if v, ok := q["options"]; ok { return "", fmt.Errorf("options already set to %q", v) } q.Set("options", fmt.Sprintf("-csearch_path=%s", searchPath)) @@ -293,8 +290,11 @@ func newIAMConnectionStringProviderFromURL(ctx context.Context, u *url.URL, onTo OnTokenSign: onTokenSign, } - if searchPath := q.Get("search_path"); searchPath != "" { - p = WithSchemaSearchPath(p, searchPath) + if searchPath, ok := q["search_path"]; ok { + if len(searchPath) > 1 { + return nil, fmt.Errorf("Multiple search_path values specified") + } + p = WithSchemaSearchPath(p, searchPath[0]) } return p, nil