feat(tool/looker): add create_merge_query tool - #3758
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request introduces a new tool, create_merge_query (type looker-create-merge-query), to the Looker integration. This tool enables merging query results from multiple explores, mimicking a SQL left outer join. The changes include the Go implementation of the tool, comprehensive unit and integration tests, updates to prebuilt configurations, and extensive documentation. No review comments were provided, so I have no feedback to offer on the review itself.
Adds `looker-create-merge-query`, exposing Looker's Merged Results through the API (`POST /merge_queries`). This lets an agent combine fields from two or more explores — even across different databases — in a single result, which a plain `query` call cannot do since it targets one explore. The tool takes a `source_queries` array (one entry per explore) whose order is significant: the first entry is the primary query and the results of every later entry are joined onto it via that entry's `merge_fields`, matching Looker's left-outer-join semantics. Each source query is created with `sdk.CreateQuery` (idempotent, so identical queries are reused) and the resulting ids are passed to `sdk.CreateMergeQuery`. Looker has no API endpoint that runs a merge query, so the tool returns the merge query id, its result_maker_id, the created source queries and a URL that opens the merged results in the Looker UI, rather than rows. This is stated in the tool description and docs so the planner does not expect data back. Notable details: - Unknown keys inside a source query are rejected rather than silently dropped, so a typo like `explores` surfaces as an error instead of a query missing a filter. - Reuses `lookercommon.EscapeUnquotedParameterFilters` per source query, so `type: unquoted` parameter filters behave as they do in `looker-query`. - Adds a note to the prebuilt `query` tool description pointing at this tool, so the planner can discover it. The shared parameter descriptions in `lookercommon` are deliberately untouched to avoid churn in the integration-test expectations.
a99c6c5 to
17737fa
Compare
|
Hi @drstrangelooker, this contributor is adding a new Looker tool. Could you take a look and see if this is what you want? Thank you! |
Description
Adds a new Looker tool,
looker-create-merge-query(registered ascreate_merge_query), exposing Looker'sMerged Results through the
API (
POST /merge_queries).Impact: a
querycall can only target one explore, so today an agent thatneeds fields from two explores has to run both queries and stitch the rows
together itself — losing Looker's join semantics and burning extra tool calls.
This tool performs the merge server-side, including across explores backed by
different databases.
Solution: the tool takes a
source_queriesarray, one entry per explore.Order is significant — the first entry is the primary query, and the results of
every later entry are joined onto it using that entry's
merge_fields, matchingLooker's left-outer-join semantics. Each source query is created with
sdk.CreateQuery(idempotent, so an identical query is reused rather thanduplicated) and the resulting query ids are handed to
sdk.CreateMergeQuery.Merge-level
pivots,sorts,limit,column_limit,total,dynamic_fieldsandvis_configare supported.Important API limitation
Looker has no endpoint that runs a merge query — only create and get. So the
tool returns the merge query
id, itsresult_maker_id, the created sourcequeries (
name,model,explore,query_id,slug) and aurlthat opensthe merged results in the Looker UI, rather than rows of data. This is stated
explicitly in the tool description and the docs page so the planner does not
expect data back and instead falls back to
queryper explore when it needs therows in-conversation.
Notable details
rejected rather than silently dropped, so a typo like
exploressurfaces as anerror instead of a query quietly missing a filter.
lookercommon.EscapeUnquotedParameterFiltersper source query, so LookMLtype: unquotedparameters behave exactly as they do inlooker-query.querytool descriptionpointing at
create_merge_query. The shared parameter descriptions inlookercommonare deliberately left untouched — changing them forces editsacross five separate integration-test expectation blocks.
NewWriteAnnotations(non-destructive write), since thecall does create objects in Looker but nothing user-visible or destructive.
Testing
processSourceQuery(happypath, every optional key, 10 error cases),
processSourceQueries(arity guard),asRowLimitandmergeURL.go test -race ./cmd/... ./internal/...passes.go vetandgofmtclean, includingtests/looker..ci/lint-docs-tool-page.shpasses (320 pages).RunToolGetTestByNamemanifestassertion (verified byte-for-byte against the generated manifest) and a
RunToolInvokeParametersTestinvoke case.Reviewer notes
merges two
system__activitylookqueries joined onlook.idand assumeslook.id/look.titleexist there. I had no Looker instance available, sothis is the most likely thing to need adjusting.
golangci-lintis not installed in my environment and was not run; CI will bethe first real check.
.ci/lint-docs-sample-filters.shfails locally, but it reports every filter inevery untouched file as invalid — a pre-existing local tooling problem, not
something this branch causes.
PR Checklist
CONTRIBUTING.md
bug/issue
before writing your code! That way we can discuss the change, evaluate
designs, and agree on the general idea
!if this involve a breaking change (not a breaking change)🛠️ Fixes #3756 🦕
🤖 Generated with Claude Code