Files
Felipe Martin 2b3fb21fe3 Add KVListWithOptions for server-side prefix filtering in plugin KV store (#35441)
* Add KVListWithOptions to push prefix filtering into SQL

Add server-side prefix filtering for plugin KV store key listing via
KVListWithOptions across the full stack: store interface, SQL
implementation, platform service, app layer, plugin API, pluginapi
helper, and memory store.

Previously, WithPrefix in pluginapi.ListKeys performed client-side
filtering after fetching all keys. This pushes the LIKE filter into
the SQL query for efficiency, using sanitizeSearchTerm to escape
SQL wildcards.

* Add KVListWithOptions backward-compat fallback for old servers

Manually implement the KVListWithOptions RPC glue instead of generating
it so the client can detect "rpc: can't find method" errors from
pre-11.5 servers and return a proper AppError with StatusNotImplemented.
The generated version silently returns (nil, nil) on RPC errors, which
is indistinguishable from an empty result due to encoding/gob conflating
nil and empty slices. The pluginapi helper already checks for
StatusNotImplemented and falls back to KVList with client-side prefix
filtering.

* Address review findings on KVListWithOptions

- Escape backslashes in the SQL prefix instead of stripping them.
- Return an AppError for every RPC failure in the KVListWithOptions client.
- AND multiple WithPrefix options again; extra prefixes become checkers.
- Make the old-server fallback page over prefix-filtered keys and trigger
  only on StatusNotImplemented.
- Set the minimum server version to 12.2 and fix the WithChecker doc.
- Remove the unused PlatformService.KVListWithOptions.
- Route List and ListPluginKeys through their WithOptions variants.

* Tighten KV list tests from CodeRabbit nitpicks

- Assert exact keys per page in the prefix pagination store test.
- Drop unused pgHost/pgPort lookups in the KV integration test.
- Include compiler output in the plugin build failure message.

* Use snake_case mlog field key in ListPluginKeysWithOptions

* Move KVListWithOptions integration tests into regular test suites

- Cover the plugin-to-SQL path with a test_kv_list_with_options plugin run by TestBasicAPIPlugins.
- Cover the old-server RPC error mapping with a unit test against an RPC server that lacks the method.
- Remove server/integration/pluginapi and the testcontainers dependency it pulled into server/go.mod.

* Combine WithPrefix prefixes so all prefix filtering stays server-side

A second prefix ran as a checker after page and count were applied, so
pages came back short. Nested prefixes now collapse to the longest one,
and prefixes that cannot both match return no keys.

* Use a fixed batch size for the ListKeys prefix fallback scan

The scan read the caller's count keys per KVList call, so a small count
made many RPCs. It now reads 1000 keys per call, independent of count.

* Use an explicit ESCAPE '*' for the plugin KV prefix LIKE

Matches the other LIKE queries in the store and does not depend on the
default backslash escape of Postgres.

* Rename the KVListWithOptions RPC error ids to plugin.api.kv_list_with_options.*

Matches the naming of the other plugin API error ids.

* Add a benchmark for listing plugin keys with a prefix

Compares paging through KVList and filtering in Go with KVListWithOptions,
for 10k, 100k and 1M keys.

* Document KVListWithOptions and prefix listing for plugins

Expands the doc comments that generate the server plugin reference, and
adds a best-practices section on listing KV store keys with a prefix.
2026-11-01 09:37:48 +01:00
..
…
…
…
…
…