Skip to content

fix(bigquery): format incremental cursor literal against the live column type - #68012

Merged
Gilbert09 merged 1 commit into
masterfrom
posthog-code/bigquery-incremental-date-cursor-cast
Jul 3, 2026
Merged

fix(bigquery): format incremental cursor literal against the live column type#68012
Gilbert09 merged 1 commit into
masterfrom
posthog-code/bigquery-incremental-date-cursor-cast

Conversation

@Gilbert09

Copy link
Copy Markdown
Member

Problem

BigQuery imports on incremental syncs are crashing with a BadRequest:

Could not cast literal "1970-01-01T00:00:00" to type DATE at [1:105]; reason: invalidQuery

Error tracking issue: https://us.posthog.com/project/2/error_tracking/019f244c-a6df-7d21-8b68-76deada789b3

The stack trace is entirely inside our code: _run_with_job_not_found_retry_query_result_with_job_retry_get_rows_to_sync in products/warehouse_sources/backend/temporal/data_imports/sources/bigquery/bigquery.py.

The incremental query builder (_get_query) formats the cursor bound purely from incremental_field_type, the type we recorded when the source was set up. When a column gets retyped to DATE in BigQuery after schema discovery (dbt-managed datasets do this), that stored type still says DateTime/Timestamp, so we emit a datetime-shaped literal (1970-01-01T00:00:00). BigQuery won't implicitly cast that to a DATE column, so the COUNT query — and the data-read query, which builds the same clause — fail on every attempt.

Changes

_get_query now formats the incremental cursor literal from the column's live BigQuery type (read off bq_table.schema), falling back to the stored incremental_field_type when the column isn't in the schema. This mirrors how _bq_row_filter_conditions already resolves column types.

  • DATE column: date-only literal (1970-01-01), which casts cleanly.
  • DATETIME column: timezone-naive literal (unchanged behavior).
  • TIMESTAMP column: keeps the offset (unchanged behavior).

This is a fixable bug, not a user/upstream error: our generated SQL was wrong for the column, and we already have the correct type in hand at query-build time.

How did you test this code?

Automated only (I, Claude, cannot run a live BigQuery sync). Added a parameterized regression test test_bigquery_get_query_date_column_with_datetime_cursor that builds _get_query against a DATE column with a DateTime/Timestamp cursor and asserts the literal is date-only (no T00:00:00, no +00:00) — this fails on the old code path and catches the exact cast crash. Updated the existing test_bigquery_get_query_datetime_cursor_timezone_offset to attach a realistic column schema so it now exercises the live-type lookup for matching DATETIME/TIMESTAMP columns.

Ran the bigquery source suite locally: 115 passed. ruff check/ruff format clean.

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

🤖 Agent context

Autonomy: Fully autonomous

Triaged from an error-tracking webhook by Claude (Claude Code). Confirmed the issue in PostHog error tracking (9 occurrences across 9 sources, all first seen the same day), read the full stack trace, and traced the failing query construction to _get_query. Skills invoked: /writing-tests.

Considered two fixes: (1) special-case only the datetime→DATE mismatch, or (2) drive all datetime-literal formatting off the live column type. Chose (2) — it's one coherent rule, matches what row filters already do, and also closes the symmetric latent crash (a Timestamp-stored cursor against a now-DATETIME column would fail the same way with an offset literal). Kept it scoped to literal formatting; did not touch the retry policy or the incremental operator selection.

…umn type

Incremental syncs built the cursor bound purely from the incremental_field_type
recorded at source setup. When a column was retyped to DATE in BigQuery after
schema discovery, that stored type still said DateTime/Timestamp, so we emitted a
datetime-shaped literal ("1970-01-01T00:00:00") that BigQuery refuses to cast to
DATE, failing every sync with a BadRequest.

Drive the literal off the column's live BigQuery type from bq_table.schema
(falling back to the stored type when the column isn't found), mirroring how
row-filter conditions already resolve column types. DATE columns now get a
date-only literal; DATETIME stays tz-naive; TIMESTAMP keeps its offset.

Generated-By: PostHog Code
Task-Id: cd4fe323-d03a-4406-8ae1-4bbd8a8c9d28
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Hey @Gilbert09! 👋

It looks like your git author email on this PR isn't your @posthog.com address (owerstom@gmail.com). Since you're on the PostHog team, it's worth pointing your local git author email at your @posthog.com address. Why it matters:

  • Consistent work identity in git history — internal tooling that attributes commits to team members keys off your @posthog.com address.
  • Keeps team contributions easy to tell apart from external community ones when scanning history.

You can fix it for this repo with:

git config user.email "you@posthog.com"

Or set it globally with git config --global user.email "you@posthog.com". No need to redo this PR — just a nudge for next time. 🙂

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team July 2, 2026 20:23
@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(bigquery): format incremental cursor..." | Re-trigger Greptile

@Gilbert09 Gilbert09 added the stamphog Request AI approval (no full review) label Jul 2, 2026 — with PostHog

@github-actions github-actions Bot left a comment

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.

Small, well-tested bug fix scoped to one file (plus tests) by an author on the owning team, with independent 👍 signals from Greptile and a security bot; no risk to production data or contracts.

@Gilbert09
Gilbert09 merged commit 426a211 into master Jul 3, 2026
303 checks passed
@Gilbert09
Gilbert09 deleted the posthog-code/bigquery-incremental-date-cursor-cast branch July 3, 2026 08:49
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 3, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-03 09:17 UTC Run
prod-us ✅ Deployed 2026-07-03 09:38 UTC Run
prod-eu ✅ Deployed 2026-07-03 09:43 UTC Run

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

Labels

stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant