Repository navigation
fix(semantic-layer): derive dataset fqn from the table's Storage location (#761) - #762
Conversation
…tion (#761) `semantic-layer add dataset` and `build` wrote every dataset fqn as "KEBOOLA"."<bucket-id>"."<table>". No project has a KEBOOLA database, so every consumer pasting the fqn into SQL failed. The INFORMATION_SCHEMA type lookup behind `build --types-workspace` queried the same nonexistent database. The location now comes from the owning bucket's Storage backendPath, exposed on `storage table-detail` as `backend_path` and `sql_path`. Swapping only the database would not be enough: a linked bucket's backendPath names the SOURCE project's database and schema, and only that path resolves (live-verified). - `add dataset` reads the fqn from table detail, so the table must exist; `--fqn` (CLI and REST body) stores a value verbatim instead. - A table whose location Storage does not report fails with VALIDATION_ERROR instead of getting a fabricated fqn. - `validate --deep` warns FQN_MISMATCH for stored fqns that differ, which flags models built before this fix.
keboola-pr-reviewer-bot
left a comment
There was a problem hiding this comment.
Verdict: auto_approve (risk 2/5) · profile keboola-mcp-server
Well-tested, well-documented bug fix deriving semantic-layer dataset fqn from real Storage location instead of a nonexistent "KEBOOLA" database.
- `build` no longer tells users to pass `--fqn`, a flag it does not have: the unresolvable-location error now points at `semantic-layer add dataset --fqn`. - Drop the second quote check in derive_dataset_fqn; `table_sql_path` already refuses identifiers it cannot quote, and the test now drives that path. - Document `backend_path` / `sql_path` on the table-detail entries of AGENT_CONTEXT and CLAUDE.md, and add the fqn gotcha to keboola-expert.md. - Trim docstrings and test comments that argued for the change.
Dismissing prior approval — a new commit was pushed and this review was for an earlier SHA. Run @keboola-pr-reviewer-bot review to get a fresh verdict.
|
New commit on |
|
@keboola-pr-reviewer-bot review |
keboola-pr-reviewer-bot
left a comment
There was a problem hiding this comment.
Verdict: needs_human (risk 4/5) · profile keboola-mcp-server
Head commit has failing checks (copilot-pull-request-reviewer); no required-check rules discovered on the base branch, falling back to block-on-any-failure.
soustruh
left a comment
There was a problem hiding this comment.
Approved. Root-cause fix: the dataset fqn is derived from the table's real Storage backendPath instead of a hardcoded KEBOOLA database. The change is additive and backward-compatible, and CI is green.
Closes #761.
Release Notes
semantic-layer add datasetandsemantic-layer buildnow read the datasetfqnfrom the table's real warehouse location in Storage. Before, they wrote a hardcoded"KEBOOLA"database that exists in no project, so any consumer pasting the fqn into SQL failed (Kai, data apps, AI SQL generation).--fqn FQNonsemantic-layer add dataset(andfqnin the REST body) stores a value verbatim.storage table-detailreturns two new keys:backend_pathandsql_path.semantic-layer validate --deepwarnsFQN_MISMATCHon datasets whose stored fqn differs from the table's location. Models built before this fix are flagged this way.Plans for customer communication
None.
Impact analysis
Root cause.
_derive_fqnreturned"KEBOOLA"."<bucket-id>"."<table>". The SnowflakeINFORMATION_SCHEMAquery behindbuild --types-workspacealso targeted"KEBOOLA".Why not just swap the database name. I checked this in a read-only workspace on a GCP us-east4 project:
"KEBOOLA"."out.c-azure-costs-copy"."2025-reservations-final"Database 'KEBOOLA' does not exist"KBC_USE4_5024"."out.c-azure-costs-copy"."2025-reservations-final""KBC_USE4_5024"."in.c-aws-costs-raw"."reports"(linked bucket, own database)Schema ... does not exist"KBC_USE4_337"."in.c-keboola-ex-aws-s3-…"."reports"(linked bucket, source database and schema)A linked bucket's tables live in the source project's database and schema. The Storage API returns exactly that in
bucket.backendPath, so the fix uses it verbatim and never rebuilds the path from the tableId.Changes
services/_table_detail.py:table_sql_path()quotes the location per backend. Snowflake gives"db"."schema"."table". BigQuery gives`dataset`.`table`, with the project prepended whendatabaseNameis set; this matchesbucket-detail. It returnsNonefor an unsupported backend, a missingbackendPath, or a quote character inside an identifier.services/_semantic_layer_fqn.py(new):derive_dataset_fqnraisesVALIDATION_ERRORwhen there is no usable location, pointing atsemantic-layer add dataset --fqn(the same message servesbuild, which has no--fqn).append_fqn_mismatch_warningspowers the newvalidate --deepwarning.add_datasetfetches table detail once, which also serves--deep-fields. With--fqnalone it makes no Storage call.build_information_schema_sqltakesbackend_path. The Snowflake query uses its database and schema. The BigQuery query usesbackendPath[0]instead of rebuilding the dataset name from the bucket id.Behavior changes
add datasetwithout--fqnnow fails when the table does not exist, or when Storage reports no location for it. It used to store a broken fqn silently. The E2E tests that use synthetic tableIds now pass--fqn.buildaborts before any write when a table's location cannot be derived.gotchas.mddocuments the repair path: export, fix the fqn and metric sql, thenimport --overwrite.Live verification (kbagent from this branch)
build --dry-run --types-workspaceon a normal table and a linked alias table: both fqns match the working paths above.type_resolution_errors: [], and the linked table got its types from"KBC_USE4_337".INFORMATION_SCHEMA.validate --deepon the two europe-west3 models from the issue: 41FQN_MISMATCHwarnings on each. The other 6 of the 47 datasets hit the existingDEEP_FETCH_FAILED.Not covered. BigQuery was not verified live; no BigQuery project was available. A plain alias table in the project's own (non-linked) bucket was not verified live either: none of the available projects had one. It takes its own bucket's
backendPath, the same as a regular table.buildstill emits Snowflakesql_dialectand column quoting on BigQuery, and its BigQueryINFORMATION_SCHEMAlookup omits the GCP project (unchanged from before). Both are tracked as a separate follow-up.Reviews on this PR
table-detailkeys inAGENT_CONTEXT,CLAUDE.mdandkeboola-expert.md; removed a duplicate quote check; trimmed comments that argued for the change.builderror advised--fqn, whichbuilddoes not have. Fixed. A liveSELECT 1 FROM <fqn>check invalidate --deepwas only suggested in the issue; this PR compares against the Storage location instead, which needs no workspace.INFORMATION_SCHEMAwithout the GCP project) predates this PR and joins the BigQuery follow-up.Change type
Bug fix (plus the additive
--fqnoption and newtable-detailkeys).Justification
Every semantic model created through kbagent carried an fqn that resolves nowhere, which breaks every downstream SQL consumer of the semantic layer.
Deployment
Merge & automatic deploy.
Rollback plan
Revert of this PR.
Post release support plan
None.