Skip to content

feat(ext): add Google BigQuery database support (#569) - #593

Merged
timveil merged 2 commits into
mainfrom
feat/569-bigquery-support
Aug 3, 2026
Merged

feat(ext): add Google BigQuery database support (#569)#593
timveil merged 2 commits into
mainfrom
feat/569-bigquery-support

Conversation

@timveil

@timveil timveil commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Description

Adds BigQuerySupport, driven by tbc-bq-jdbc 4.3.0. Covers the natively bindable scalar types: STRING, BYTES, INT64, FLOAT64, NUMERIC, BIGNUMERIC, BOOL, DATE, TIME, TIMESTAMP.

All three driver-side blockers from #569 are resolved as of 4.3.0 — batch execution collapses into multi-row INSERT (plus an optional NDJSON load-job path), setAutoCommit(false) starts a session lazily, and getPrimaryKeys/getImportedKeys read declared NOT ENFORCED constraints. That last one means Bloviate’s FK-aware topological fill works on BigQuery, which is better than the issue hoped for.

Two general capabilities, not BigQuery special-cases

BigQuery is the first analytical engine Bloviate targets, and the gaps it exposes are general — a future ClickHouse implementation hits most of them. DatabaseSupport is already a capability interface (batchRewriteUrlParameter(), supportsBulkLoad(), readConstraints()), so these fit its existing idiom:

  • prefersConnectionDefaultCommit() — keeps the engine out of transaction management. On BigQuery each executeBatch is already one atomic query job, while setAutoCommit(false) starts a session (per-connection overhead and quota) and disables the driver’s fastest bulk-insert path. Consulted in exactly one place, DatabaseFiller.effectiveParallelCommitStrategy(); an explicitly configured strategy still wins, with a warning.
  • supportsBulkLoad() → true with no-op constraint handling. BigQuery keys are always NOT ENFORCED, so there is nothing to suspend — and foreign-key values are seeded from the parent primary-key column’s seed (TableFiller.java:160-162) rather than depending on insert order, so the unordered single-wave path is free here.

No speculative AbstractAnalyticalSupport base class — one data point isn’t a pattern. If ClickHouse ends up overriding the same set, extract then.

Type handling

  • TYPE_NAME arrives as raw INFORMATION_SCHEMA text (STRING(20), ARRAY<INT64>, RANGE<DATE>), so it is normalized before dispatch.
  • COLUMN_SIZE is the type maximum, not a declared width — a bare STRING reports 2,097,152. Sizes clamp downward, leaving STRING(20) honest while taming the bare form.
  • BIGNUMERIC reports (76, 38), but the driver binds every BigDecimal as NUMERIC, so values clamp to (38, 9). Without this the generated value carries 25 fractional digits and is rejected as an out-of-range NUMERIC parameter — note this is a scale problem, not a magnitude one, since BigDecimalGenerator already caps precision at 25.
  • DATETIME, JSON, GEOGRAPHY, INTERVAL, RANGE, ARRAY, STRUCT have no parameter binding and BigQuery will not coerce into them, so they throw at generator resolution — before any rows are written — naming the column and the ColumnConfiguration escape hatch. STRUCT explicitly replaces the inherited SqlStructGenerator, which cannot know a struct’s shape and would generate silent garbage.

Filling those types needs SQL-side construction (PARSE_JSON(?), CAST(? AS DATETIME)), which is a follow-up: a valueExpression() seam on DataGenerator, gated on tbc-bq-jdbc#302.

Related Issues

Closes #569
Depends on nothing; the follow-up work is gated on Two-Bear-Capital/tbc-bq-jdbc#302 and #301.

Type of Change

  • feat — new feature (minor)

Affected Module(s)

  • bloviate-core
  • Build / CI / tooling

How Has This Been Tested?

./mvnw verify green across the reactor: 299 core tests, 0 failures, spotless / PMD / CPD / SpotBugs / JaCoCo floors all pass. Default builds are unaffected — no new dependency resolves.

BigQuery has no usable emulator. The driver deliberately removed its emulator tier because the emulator diverged far enough from the service to hide real defects, so BigQueryFillerTest needs a live project and is skipped by default. It is gated twice — BLOVIATE_BQ_PROJECT present and the driver on the classpath — so setting the env var without -Pbigquery skips cleanly instead of failing with “No suitable driver”. I verified both gates. Nothing in the test imports a driver class, so it compiles in every build.

The driver is not on Maven Central yet, so it is declared only inside the opt-in bigquery profile rather than as an ordinary test dependency; a default build must stay resolvable for everyone. Docker-free unit tests carry the coverage floors.

⚠️ The live test has never actually run — I have no GCP credentials. Everything asserted end-to-end (metadata capture, the NOT ENFORCED FK graph, batch collapse against a backtick-qualified INSERT, clamps against the real service) is unverified against BigQuery itself.

Checklist

  • My PR title follows the Conventional Commits format
  • ./mvnw verify passes locally (tests included)
  • I have added or updated tests covering my changes
  • I have updated documentation as needed
  • My changes follow the existing code style and conventions

Additional Notes

AbstractDatabaseSupport.registerDefaults and every existing io.bloviate.gen generator are untouched, so SeedGoldenDumpTest’s byte-for-byte H2 golden dump is unaffected and needs no regeneration.

The classpath script runner moves from BaseEmbeddedTest up to BaseDatabaseTestCase and gains token substitution, so the BigQuery schema can use per-run table names without duplicating the reader (CPD is enforced).

Known sharp edge, documented rather than fixed: GeneratorRegistry ranks above the support’s type mapping, and bloviate-datafaker registers column-name patterns that ignore jdbcType — so a GEOGRAPHY column named home_address gets a Datafaker string and fails at insert instead of at resolve.

🤖 Generated with Claude Code

Adds BigQuerySupport, driven by tbc-bq-jdbc 4.3.0. Covers the natively
bindable scalar types: STRING, BYTES, INT64, FLOAT64, NUMERIC,
BIGNUMERIC, BOOL, DATE, TIME and TIMESTAMP.

BigQuery is the first analytical engine Bloviate targets, and the gaps it
exposes are general rather than vendor quirks, so they are addressed as
DatabaseSupport capabilities rather than special cases:

- prefersConnectionDefaultCommit() lets a support keep the engine out of
  transaction management. On BigQuery each executeBatch is already one
  atomic query job, while setAutoCommit(false) starts a session and
  disables the driver's NDJSON load-job path. Consulted only in
  effectiveParallelCommitStrategy(); an explicitly configured strategy
  still wins, with a warning.
- supportsBulkLoad() is enabled with no-op constraint handling. BigQuery
  keys are always NOT ENFORCED, so there is nothing to suspend, and
  foreign-key values are seeded from the parent primary-key column rather
  than depending on insert order.

Type handling notes:

- TYPE_NAME arrives as raw INFORMATION_SCHEMA text (STRING(20),
  ARRAY<INT64>, RANGE<DATE>), so it is normalized before dispatch.
- COLUMN_SIZE is the type maximum, not a declared width; sizes are
  clamped downward, leaving STRING(20) honest while taming bare STRING.
- BIGNUMERIC reports (76, 38) but the driver binds every BigDecimal as
  NUMERIC, so values are clamped to NUMERIC's (38, 9). Without this the
  generated value carries 25 fractional digits and is rejected as an
  out-of-range NUMERIC parameter.
- DATETIME, JSON, GEOGRAPHY, INTERVAL, RANGE, ARRAY and STRUCT have no
  parameter binding and BigQuery will not coerce into them, so they throw
  at generator resolution, before any rows are written, naming the column
  and the ColumnConfiguration escape hatch. STRUCT explicitly replaces
  the inherited SqlStructGenerator, which cannot know a struct's shape.

Testing: BigQuery has no usable emulator, so BigQueryFillerTest needs a
live project and is skipped by default. It is gated on both
BLOVIATE_BQ_PROJECT and the driver being on the classpath, so setting the
env var without -Pbigquery skips cleanly instead of failing with "No
suitable driver". The driver is not on Maven Central yet, so it is
declared only inside that opt-in profile and a default build stays
resolvable. Nothing in the test imports a driver class, so it always
compiles. Docker-free unit tests carry the coverage floors.

The classpath script runner moves from BaseEmbeddedTest up to
BaseDatabaseTestCase and gains token substitution, so the BigQuery schema
can use per-run table names without duplicating the reader.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 19:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class Google BigQuery support to bloviate-core via a new BigQuerySupport dialect and supporting engine/doc/test updates, while keeping the BigQuery JDBC driver dependency opt-in (since it’s not on Maven Central yet).

Changes:

  • Add BigQuerySupport and selection logic, including BigQuery-specific type handling and a new prefersConnectionDefaultCommit() capability.
  • Adjust DatabaseFiller commit-strategy selection/warnings and add unit coverage for the commit-strategy mapping.
  • Add BigQuery docs and an opt-in, gated live integration test + schema, with Maven profile wiring for the driver.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
README.md Mentions BigQuery in supported databases list.
pom.xml Adds tbc-bq-jdbc version + dependencyManagement entry (for opt-in profile use).
docs/DATABASE_SUPPORT.md Documents BigQuery support, limits, driver requirements, and tuning guidance.
docs/CONFIGURATION.md Adds BigQuery-specific batching/commit-strategy tuning note.
CONTRIBUTING.md Documents how the gated live BigQuery test is enabled and run.
CLAUDE.md Updates architecture list to include BigQuerySupport.
bloviate-core/src/test/resources/create_tables.bigquery.sql Adds BigQuery test schema used by the live integration test.
bloviate-core/src/test/java/io/bloviate/ext/DatabaseSupportSelectionTest.java Adds selection tests for BigQuery product-name matching.
bloviate-core/src/test/java/io/bloviate/ext/BigQuerySupportTest.java Adds unit tests for BigQuery type mapping/clamps and rejection behavior.
bloviate-core/src/test/java/io/bloviate/ext/BatchRewriteParameterTest.java Adds BigQuery assertion for no batch-rewrite URL parameter.
bloviate-core/src/test/java/io/bloviate/db/DatabaseFillerCommitStrategyTest.java Adds unit test coverage for effective parallel commit strategy selection.
bloviate-core/src/test/java/io/bloviate/db/BigQueryFillerTest.java Adds gated live BigQuery fill test (skipped by default).
bloviate-core/src/test/java/io/bloviate/db/BaseEmbeddedTest.java Removes duplicated script runner; relies on shared runner from BaseDatabaseTestCase.
bloviate-core/src/test/java/io/bloviate/db/BaseDatabaseTestCase.java Centralizes SQL script runner and adds token substitution support.
bloviate-core/src/main/java/io/bloviate/ext/DatabaseSupport.java Adds prefersConnectionDefaultCommit() capability and BigQuery selection note.
bloviate-core/src/main/java/io/bloviate/ext/BigQuerySupport.java Implements BigQuery-specific generator mapping, clamps, and capability overrides.
bloviate-core/src/main/java/io/bloviate/db/DatabaseFiller.java Adds warning when engine-managed transactions are discouraged; updates commit-strategy mapping logic.
bloviate-core/pom.xml Adds opt-in bigquery Maven profile to include the JDBC driver for tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread bloviate-core/src/main/java/io/bloviate/ext/BigQuerySupport.java Outdated
Comment thread docs/DATABASE_SUPPORT.md Outdated
Comment thread bloviate-core/src/main/java/io/bloviate/db/DatabaseFiller.java
Review follow-up, all three documentation-only.

warnIfEngineManagedCommitDiscouraged was inserted directly above
warnIfBulkIgnored's signature, which orphaned that method's javadoc: the
bulk-load block ended up documenting nothing while warnIfBulkIgnored had
no javadoc of its own. Reordered so each block sits with its method.

BigQuerySupport.batchRewriteUrlParameter opened with "Not overridden
deliberately" on a method that is, in fact, overridden. The intent was
that it changes no behaviour over the interface default; say that instead.

DATABASE_SUPPORT.md presented the 128-byte BYTES clamp as something a
user would observe, but ByteGenerator caps itself at 25 bytes, so that
clamp currently changes no generated value. The constant's own javadoc
already said so; the guide now agrees, and distinguishes the string clamp
(a real ~8x reduction under the generator's 2000-character limit) from
the BYTES one (a stated bound sitting above the generator's).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@timveil
timveil merged commit 7758988 into main Aug 3, 2026
10 checks passed
@timveil
timveil deleted the feat/569-bigquery-support branch August 3, 2026 19:55
timveil pushed a commit that referenced this pull request Aug 3, 2026
## [3.1.0](v3.0.4...v3.1.0) (2026-08-03)

### ✨ Features

* **ext:** add Google BigQuery database support ([#569](#569)) ([#593](#593)) ([7758988](7758988))
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.

feat(ext): add Google BigQuery support (via tbc-bq-jdbc)

2 participants