feat(ext): add Google BigQuery database support (#569) - #593
Merged
Conversation
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>
There was a problem hiding this comment.
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
BigQuerySupportand selection logic, including BigQuery-specific type handling and a newprefersConnectionDefaultCommit()capability. - Adjust
DatabaseFillercommit-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.
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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, andgetPrimaryKeys/getImportedKeysread declaredNOT ENFORCEDconstraints. 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.
DatabaseSupportis already a capability interface (batchRewriteUrlParameter(),supportsBulkLoad(),readConstraints()), so these fit its existing idiom:prefersConnectionDefaultCommit()— keeps the engine out of transaction management. On BigQuery eachexecuteBatchis already one atomic query job, whilesetAutoCommit(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() → truewith no-op constraint handling. BigQuery keys are alwaysNOT 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
AbstractAnalyticalSupportbase class — one data point isn’t a pattern. If ClickHouse ends up overriding the same set, extract then.Type handling
TYPE_NAMEarrives as rawINFORMATION_SCHEMAtext (STRING(20),ARRAY<INT64>,RANGE<DATE>), so it is normalized before dispatch.COLUMN_SIZEis the type maximum, not a declared width — a bareSTRINGreports 2,097,152. Sizes clamp downward, leavingSTRING(20)honest while taming the bare form.BIGNUMERICreports (76, 38), but the driver binds everyBigDecimalasNUMERIC, so values clamp to (38, 9). Without this the generated value carries 25 fractional digits and is rejected as an out-of-rangeNUMERICparameter — note this is a scale problem, not a magnitude one, sinceBigDecimalGeneratoralready caps precision at 25.DATETIME,JSON,GEOGRAPHY,INTERVAL,RANGE,ARRAY,STRUCThave 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 theColumnConfigurationescape hatch.STRUCTexplicitly replaces the inheritedSqlStructGenerator, 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: avalueExpression()seam onDataGenerator, 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-coreHow Has This Been Tested?
./mvnw verifygreen 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
BigQueryFillerTestneeds a live project and is skipped by default. It is gated twice —BLOVIATE_BQ_PROJECTpresent and the driver on the classpath — so setting the env var without-Pbigqueryskips 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
bigqueryprofile rather than as an ordinary test dependency; a default build must stay resolvable for everyone. Docker-free unit tests carry the coverage floors.Checklist
./mvnw verifypasses locally (tests included)Additional Notes
AbstractDatabaseSupport.registerDefaultsand every existingio.bloviate.gengenerator are untouched, soSeedGoldenDumpTest’s byte-for-byte H2 golden dump is unaffected and needs no regeneration.The classpath script runner moves from
BaseEmbeddedTestup toBaseDatabaseTestCaseand 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:
GeneratorRegistryranks above the support’s type mapping, andbloviate-datafakerregisters column-name patterns that ignorejdbcType— so aGEOGRAPHYcolumn namedhome_addressgets a Datafaker string and fails at insert instead of at resolve.🤖 Generated with Claude Code