Skip to content

fix: run BigQuery expectations on the data branch copy - #1851

Merged
hayssams merged 1 commit into
masterfrom
fix/bigquery-branch-expectations
Oct 20, 2026
Merged

hayssams merged 1 commit into
masterfrom
fix/bigquery-branch-expectations

Conversation

@hayssams

Copy link
Copy Markdown
Contributor

Problem

On a data branch (SL_DATA_BRANCH), native BigQuery transforms and native BigQuery loads write to <branch>.<table>, but their expectations still queried domain.table, i.e. the production table. A branch run could therefore pass its expectations on production data and never check what it actually wrote.

Fix

  • Transforms (AutoTask, BigQueryAutoTask): new overridable expectationTarget (database, domain, table), used by runExpectations and runAndSinkExpectations. It defaults to the task's target; BigQueryAutoTask returns its branch target when a branch is active.
  • Loads (IngestionExpectations): when the native BigQuery loader runs on a branch, expectations check <project>.<branch>.<table>. Spark loads never branch, so they keep checking the loaded table. The target resolution is shared with BigQueryNativeLoader via BigQueryNativeLoader.originalTableId.
  • IngestionExpectations.expectationJob(handler) is split out of runExpectationsWithHandler so tests can build the job without sinking reports.

Expectation reports on a branch now record the branch as their domain, which tells branch runs apart from production runs in the expectations audit table.

Tests

  • BigQueryBranchExpectationsSpec (transform): branch run checks prj.sl_branch.order_summary, non-branch run checks prj.kpi.order_summary.
  • BigQueryBranchLoadExpectationsSpec (load): native load on a branch checks prj.sl_branch.orders; native load without a branch and Spark load on a branch check sales.orders.
  • Both specs record the SQL handed to the assertion handler, no BigQuery access needed. Both failed before the fix on the branch cases only.
  • testOnly ai.starlake.job.ingest.* ai.starlake.job.transform.*: 101 passed. scalafmtCheckAll clean.
  • Not run: the live BigQueryBranchSpec (SL_REMOTE_TEST).

Suggested changelog entry (1.8.14)

Bug fix:

  • Expectations on a BigQuery data branch check the branch copy: with SL_DATA_BRANCH set, native BigQuery transforms and loads wrote to the branch dataset but ran their expectations against the production table. They now check the table the job actually wrote.

Follow-up

starlake-ai/starlake-docs#45 lists this as a limitation; update that line once this ships.

🤖 Generated with Claude Code

On a data branch (SL_DATA_BRANCH), native BigQuery transforms and native
BigQuery loads write to <branch>.<table>, but their expectations still
queried the production table, so a branch run could pass its checks on
production data.

- AutoTask: new overridable expectationTarget, used by runExpectations
  and runAndSinkExpectations; BigQueryAutoTask returns the branch target
  when a branch is active.
- IngestionExpectations: expectations of a native BigQuery load on a
  branch check the branch copy; Spark loads never branch and keep
  checking the loaded table. The load target resolution is shared with
  BigQueryNativeLoader through BigQueryNativeLoader.originalTableId.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hayssams added a commit to starlake-ai/starlake-docs that referenced this pull request Oct 20, 2026
starlake-ai/starflow#1851 makes expectations of branched native BigQuery
transforms and loads check the branch copy. The unreleased docs describe
the new behavior; the 1.8.9 docs keep the limitation, now covering loads
too, and point to the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hayssams
hayssams merged commit 8114462 into master Oct 20, 2026
2 checks passed
@hayssams
hayssams deleted the fix/bigquery-branch-expectations branch October 20, 2026 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant