Add search support to GLQL

GLQL (GitLab Query Language) is compiled by a Rust crate in gitlab-org/glql and shipped into gitlab-org/gitlab as the gitlab_query_language Ruby gem and the @gitlab/query-language-rust npm package. Today it supports sources like work items, merge requests, projects, jobs, code suggestions, and contributions, but none of them accept a free-text search term, and there is no source for code search. Prototype work for both exists on two shared demo branches (glql!441 (closed) and !246669 (closed)), which mix unrelated work from multiple authors. This issue tracks extracting and productionising the search-related parts of those branches.

Proposal

Part 1: free-text search filter on existing sources

  • Add a Search field to GLQL, usable as a filter on work items, merge requests, and projects.
  • Example: type = Issue AND search = "memory leak".
  • In gitlab-org/gitlab, ee/lib/ee/search/advanced_finders/work_items_finder.rb currently hardcodes the Elasticsearch query string to '*' (match-all). Update it to pass through a caller-supplied search term, falling back to '*' when none is given.

Part 2: new Code source backed by blobSearch

  • Add a Code source to GLQL that compiles to the blobSearch GraphQL query.
  • Example: type = Code AND search = "def initialize".
  • Supported filters: search, regex, includeArchived, excludeForks, language.
  • Display fields: path, projectPath, matchCount, language.
  • blobSearch does not support sorting.
  • blobSearch is a root-level GraphQL field. Every other GLQL source is nested under a project, group, or namespace scope, so the transformer needs to handle a response with no scope wrapper.
  • blobSearch returns a files array and page numbers, but GLQL's presentation layer expects a nodes array and cursor-based pageInfo. A response transform is needed to bridge the two shapes.
  • Scoping uses projectId/groupId GraphQL arguments built from the page context, not the path-based scope wrappers other sources use.
  • In gitlab-org/gitlab, the GLQL presenter registry needs presenters for the new CodeSearchResult type and its fields.

Open questions

  • Pagination. blobSearch pages by page number, not cursor. The prototype emits a placeholder pageInfo that always reports no further pages. Real pagination needs a decision on how to map page numbers onto GLQL's cursor-based pagination contract.
  • Global (unscoped) code search. Whether to allow a Code query with no project or group scope, and if so, what the authorization story is.

Delivery

  • Two merge requests: one in gitlab-org/glql for the Rust changes, one in gitlab-org/gitlab for the Rails finder change and the frontend presenters.
  • The gitlab-org/gitlab MR depends on a gitlab_query_language gem release containing the glql changes, so it can't merge until that release ships.

Related to gitlab-org/gitlab#605539