Skip to content

[SavedObjects] use ComposerQuery for esql pipeline option#270628

Open
rudolf wants to merge 3 commits into
elastic:mainfrom
rudolf:so/esql-composer-query
Open

[SavedObjects] use ComposerQuery for esql pipeline option#270628
rudolf wants to merge 3 commits into
elastic:mainfrom
rudolf:so/esql-composer-query

Conversation

@rudolf
Copy link
Copy Markdown
Contributor

@rudolf rudolf commented May 22, 2026

Summary

Replaces the raw pipeline: string option on SavedObjectsEsqlOptions with pipeline: ComposerQuery from @elastic/esql.

Developers now use the esql tagged template to build pipelines:

import { esql } from '@elastic/esql';

const result = await savedObjectsClient.esql({
  type: 'dashboard',
  namespaces: ['default'],
  pipeline: esql`WHERE dashboard.title LIKE ${{ title: searchTerm }} | LIMIT 100`,
});

Template holes (${{ name: value }}) are promoted to ES|QL named parameters — values are forwarded to Elasticsearch at the protocol level and never appear in the query string, eliminating the injection risk of string interpolation.

Changes

@kbn/core-saved-objects-api-server

  • SavedObjectsEsqlOptions.pipeline changed from string to ComposerQuery
  • Removed the @elastic/esql import in the params example (params are now extracted automatically from the template)

@kbn/core-saved-objects-api-server-internal

  • Removed SOURCE_COMMAND_PATTERN guard (the type system now prevents raw strings; the esql tag's parser handles source-command detection)
  • performEsql calls .toRequest() unconditionally to extract the pipeline string and named params
  • ComposerQuery params are merged with any explicitly provided params before the request

@kbn/eslint-plugin-esql

  • no_invalid_esql_template rule gains a pipelinePropertyNames option (default: ['pipeline'])
  • When an esql template is used as the value of a pipeline: property, the missing-FROM warning is suppressed — the FROM clause is supplied by the callee

Consumers updated

  • examples/saved_objects/server/esql_example_routes.ts
  • src/core/server/integration_tests/saved_objects/service/lib/esql.test.ts
  • dev_docs/tutorials/saved_objects_esql.mdx

Test plan

  • Unit tests: node scripts/jest src/core/packages/saved-objects/api-server-internal/src/lib/apis/esql.test.ts (24 tests)
  • ESLint rule tests: node scripts/jest packages/kbn-eslint-plugin-esql (36 tests)
  • Type check: node scripts/type_check --project src/core/packages/saved-objects/api-server-internal/tsconfig.json
  • Integration tests: node scripts/jest_integration src/core/server/integration_tests/saved_objects/service/lib/esql.test.ts

Made with Cursor

Replace the raw `pipeline: string` API on `SavedObjectsEsqlOptions` with
`pipeline: ComposerQuery` from `@elastic/esql`. Template holes (`${{ name: value }}`)
are promoted to ES|QL named parameters forwarded at the protocol level, eliminating
the injection risk of string interpolation.

- Remove `SOURCE_COMMAND_PATTERN` guard (type system enforces it now)
- Call `.toRequest()` to extract the pipeline string and params
- Merge ComposerQuery params with any explicitly provided `params`
- Update example routes and integration tests to use the `esql` tag

Co-authored-by: Cursor <cursoragent@cursor.com>
@rudolf rudolf force-pushed the so/esql-composer-query branch 8 times, most recently from 6f2330f to 6edf70b Compare May 22, 2026 19:26
@rudolf rudolf marked this pull request as ready for review May 26, 2026 12:11
@rudolf rudolf requested a review from a team as a code owner May 26, 2026 12:11
@rudolf rudolf changed the title feat(saved-objects): use ComposerQuery for esql pipeline option [SavedObjects] use ComposerQuery for esql pipeline option May 26, 2026
@rudolf rudolf added release_note:skip Skip the PR/issue when compiling release notes backport:prev-minor labels May 26, 2026
@achyutjhunjhunwala
Copy link
Copy Markdown
Contributor

@rudolf I believe the changes to the ES Lint were not pushed ?

…peline

Restores the runtime check that rejects pipelines starting with FROM, ROW,
SHOW, METRICS, or TS. The check now runs against toRequest().query rather
than the raw string, since pipeline is now always a ComposerQuery.

Without this a developer writing esql`FROM .kibana | LIMIT 10` would get
an opaque ES|QL syntax error from Elasticsearch instead of a clear message.

Co-authored-by: Cursor <cursoragent@cursor.com>
@rudolf rudolf force-pushed the so/esql-composer-query branch from d5bd87a to 7cbeab1 Compare May 26, 2026 21:02
@rudolf rudolf requested review from a team as code owners May 26, 2026 21:02
@kibanamachine
Copy link
Copy Markdown
Contributor

kibanamachine commented May 26, 2026

💔 Build Failed

Failed CI Steps

Metrics [docs]

✅ unchanged

History

Copy link
Copy Markdown
Contributor

@stratoula stratoula left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not do the change in the esql pipeline, is there a reason you did that?

steps:
- command: .buildkite/scripts/steps/esql_generate_function_metadata.sh
label: Generate Function Metadata
- command: .buildkite/scripts/steps/esql_grammar_sync.sh
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change this? esql_grammar_sync.sh doesnt exist at the repo anymore, it is at the esql-js one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:prev-minor release_note:skip Skip the PR/issue when compiling release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants