From 1ef8aa48c2e7ede4d61158075fb81800bfe218f6 Mon Sep 17 00:00:00 2001 From: Edward Xu Date: Fri, 3 Jul 2026 02:57:30 +0000 Subject: [PATCH] Fix autocomplete for custom schemas Autocomplete queries did not pass the River client's configured schema. With a non-default schema, job kind and queue name suggestions could query the wrong tables. Pass the configured schema to both driver queries so autocomplete reads from the same schema as the River client. --- CHANGELOG.md | 1 + handler_api_endpoint.go | 2 ++ handler_api_endpoint_test.go | 39 ++++++++++++++++++++++++++++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0618d8e2..3af357e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Global live update pause: disable automatic query refreshes on browser focus and reconnect, preventing paused workflow detail pages from re-fetching wait data outside the configured refresh interval. [PR #584](https://github.com/riverqueue/riverui/pull/584). - Job detail: preserve line breaks in attempt logs while keeping structured JSON viewer content outside preformatted code markup. [PR #592](https://github.com/riverqueue/riverui/pull/592). +- Autocomplete: correctly use the River client's configured schema when querying job kinds and queue names. ## [v0.16.0] - 2026-05-19 diff --git a/handler_api_endpoint.go b/handler_api_endpoint.go index 22cd326f..e8536d2c 100644 --- a/handler_api_endpoint.go +++ b/handler_api_endpoint.go @@ -114,6 +114,7 @@ func (a *autocompleteListEndpoint[TTx]) Execute(ctx context.Context, req *autoco Exclude: req.Exclude, Match: match, Max: 100, + Schema: a.Client.Schema(), }) if err != nil { return nil, fmt.Errorf("error listing job kinds: %w", err) @@ -133,6 +134,7 @@ func (a *autocompleteListEndpoint[TTx]) Execute(ctx context.Context, req *autoco Exclude: req.Exclude, Match: match, Max: 100, + Schema: a.Client.Schema(), }) if err != nil { return nil, fmt.Errorf("error listing queue names: %w", err) diff --git a/handler_api_endpoint_test.go b/handler_api_endpoint_test.go index b555f54d..47d70bf8 100644 --- a/handler_api_endpoint_test.go +++ b/handler_api_endpoint_test.go @@ -31,6 +31,7 @@ type setupEndpointTestBundle struct { client *river.Client[pgx.Tx] exec riverdriver.ExecutorTx logger *slog.Logger + schema string tx pgx.Tx } @@ -43,10 +44,10 @@ func setupEndpointWithOpts[TEndpoint any](ctx context.Context, t *testing.T, ini t.Helper() var ( - logger = riversharedtest.Logger(t) - driver = riverpgxv5.New(riversharedtest.DBPool(ctx, t)) - tx, _ = riverdbtest.TestTxPgxDriver(ctx, t, driver, opts) - exec = driver.UnwrapExecutor(tx) + logger = riversharedtest.Logger(t) + driver = riverpgxv5.New(riversharedtest.DBPool(ctx, t)) + tx, schema = riverdbtest.TestTxPgxDriver(ctx, t, driver, opts) + exec = driver.UnwrapExecutor(tx) ) client, err := river.NewClient(driver, &river.Config{ @@ -72,6 +73,7 @@ func setupEndpointWithOpts[TEndpoint any](ctx context.Context, t *testing.T, ini client: client, exec: exec, logger: logger, + schema: schema, tx: tx, } } @@ -174,6 +176,35 @@ func runAutocompleteTests(t *testing.T, facet autocompleteFacet, setupFunc func( require.Len(t, resp.Data, 1) require.Equal(t, "alpha_task", *resp.Data[0]) }) + + t.Run("WithCustomSchema", func(t *testing.T) { + t.Parallel() + + endpoint, bundle := setupEndpoint(ctx, t, newAutocompleteListEndpoint) + client, err := river.NewClient(endpoint.Driver, &river.Config{ + Logger: bundle.logger, + Schema: bundle.schema, + }) + require.NoError(t, err) + endpoint.Client = client + + setupFunc(t, bundle) + + // Ensure autocomplete uses the client's configured schema instead of the + // transaction's search path. + _, err = bundle.tx.Exec(ctx, "SET LOCAL search_path TO public") + require.NoError(t, err) + + resp, err := apitest.InvokeHandler(ctx, endpoint.Execute, testMountOpts(t), &autocompleteListRequest{ + Facet: facet, + }) + require.NoError(t, err) + require.Len(t, resp.Data, 4) + require.Equal(t, "alpha_"+facet.baseString(), *resp.Data[0]) + require.Equal(t, "alpha_task", *resp.Data[1]) + require.Equal(t, "beta_"+facet.baseString(), *resp.Data[2]) + require.Equal(t, "gamma_"+facet.baseString(), *resp.Data[3]) + }) } func (f autocompleteFacet) baseString() string {