Repository navigation
Description
Sub-issue of #660. Found validating the official jaffle-shop project (ClickHouse profile) against dbt-core 2.0: dbt seed + dbt build work on dbt-clickhouse v1 but fail on v2. Root-causing the difference surfaced two previously untracked bugs (this issue) plus two already-tracked gaps (references at the bottom).
The headline: v2 could silently lose seed data while reporting success. Any statement the engine's SQL lexer cannot tokenize was dropped without executing and without any error — and the ClickHouse seed INSERT is such a statement whenever the CSV data contains a single quote. The generic silent drop is fixed on dbt-core main (merged, no public PR) and the ClickHouse-side half (lexer routing so ClickHouse SQL actually tokenizes, plus the unit-test fix) is merged in dbt-labs/dbt#16153: seed, run and build pass on main. The last seed-data gap (a ? in CSV data inserted doubled) is closed by dbt-labs/dbt#16156 (row below).
Status legend: ✅ implemented — merged and working on dbt-core 2.0 origin/main · 🟡 partial — partly working on origin/main; Notes say what works vs what fails · 🚧 in progress — implemented in an open PR (linked in Notes) · 🔴 not started — not working on origin/main · Combined status "A-🚧->B": the feature is at A on origin/main today; an open PR is driving it to B (🟡 partially working / ✅ fully working)
| Feature | Subfeatures / details | Status | Notes (PR) |
|---|---|---|---|
| jaffle-shop runs end-to-end on v2 | (overall) | ✅ | seed, run and build pass on main (the 2 unit tests run since dbt-labs/dbt#16153, #710; seed CSV values containing ? load byte-exact since dbt-labs/dbt#16156) |
| Engine drops unlexable statements as silent success | Adapter-agnostic dbt-core-v2 bug, upstream of any driver: execute_inner splits SQL via a dialect lexer (dialect_of has no ClickHouse arm → Trino fallback); on an unlexable token the splitter kept only the clean prefix, and an empty statement list returned Ok — the query was never sent, no error, no warning |
✅ | Merged on dbt-core main (no public PR; resolves the engine half of this issue): the splitter retains the unlexable remainder as the final statement, so it reaches the server and fails loudly — silent success is no longer possible (regression test test_split_unpaired_token_retains_partial_trailing; TestEscapeSingleQuotesBackslash passes on plain main). The remainder is passed through UNSPLIT — correct splitting of ClickHouse SQL with backslash escapes is the row below |
Seed rows silently lost when CSV data contains ' |
clickhouse__load_csv_rows escapes ' as \' (valid for the ClickHouse server); the engine's statement splitter has no ClickHouse dialect and falls back to the Trino lexer, which only understands '' doubling → the string looks unterminated → the whole INSERT is dropped before reaching the driver, and the seed reports success with 0 rows |
✅ | Merged: the data loss is gone on main (engine row above) — the seed INSERT, \' and all, reaches the server as a single retained statement, and the server accepts ClickHouse backslash escapes; dbt-labs/dbt#16153 routes ClickHouse to a lexer that tokenizes its escapes, so multi-statement ClickHouse SQL containing backslash escapes is split correctly as well (seed.sql keeps v1's \' escaping). The deferred return to v1's FORMAT CSV macro (#731) does NOT fix this by itself: raw CSV payload is even less lexable (bare ', ; in data) |
Seed values containing ? are inserted doubled |
clickhouse__load_csv_rows escapes ? as ?? because the 0.1.0 ADBC driver treated any literal ? as a bind param; driver 0.1.1 sends SQL verbatim and no longer unescapes ??, so the doubled ?? now reaches the server as data |
✅ | Driver 0.1.1 (adbc_clickhouse#53) via dbt-labs/dbt#16185 sends a literal ? verbatim, and dbt-labs/dbt#16156 retired seed.sql's ?? escape: ? in seed CSV data loads byte-exact, as in v1. The \x3F escapes elsewhere are server-side string escapes and were never affected |
Tracking note: the two seed data bugs above (
'loss,?doubling) are deliberately tracked HERE and not in the seed materialization issue (#709, closed) — an exception to the one-canonical-row rule. #709 stays as-is; both are fixed on main.
Repro
Seed data loss (no longer reproduces on main; kept so the original symptom is recognisable):
# raw_products.csv contains "kevin parker's favorite!"
dbt seed --full-refresh --vars '{"load_source_data": true}' # reported Succeeded
# raw.raw_products had 0 rows (v1: 10); no INSERT appeared in debug logsMinimal case was: any seed CSV with a ' in a string value → table created, 0 rows, exit 0. Downstream symptom that exposed it: dbt_utils_expression_is_true_orders_order_items_subtotal_subtotal failed with 61,465 bad rows (order items joined against the empty products table lose their prices).
# build failure (no longer reproduces on `main`; tracked in #710)
dbt build
# Failed [ 0.04s] unit_test default_dbt_test__audit.test_supply_costs_sum_correctly (models/marts/order_items.yml:126:11)
# Failed [ 0.58s] unit_test default_dbt_test__audit.test_does_location_opened_at_trunc_to_date (models/staging/stg_locations.yml:12:11)
# [error] [InvalidConfig (dbt1005)]: Invalid column name(s): 'order_id', 'product_id', 'supply_cost' in row 1 of unit test fixture for expected output. Accepted columns for expected output are: []
# [error] [InvalidConfig (dbt1005)]: Invalid column name(s): 'location_id', 'location_name', 'opened_date', 'tax_rate' in row 1 of unit test fixture for expected output. Accepted columns for expected output are: []
# → 20 downstream nodes skipped (stg_locations, locations, order_items, orders, customers + their tests)
# Summary: 43 total | 21 success | 2 error | 20 skippedRelated findings already tracked elsewhere
dbt buildunit-test failures (test_supply_costs_sum_correctly,test_does_location_opened_at_trunc_to_date):dbt1005 Invalid column name(s) … Accepted columns for expected output are: []— the unit-test expected-schema probe creates a session-scoped TEMPORARY table invisible insystem.columns. Tracked in dbt Core 2.0 parity: Tests / catalog / docs #710; fixed in [ClickHouse] dbt unit tests + correct splitting of statements containing backslash escapes dbt-labs/dbt#16153. Failed regardless of which binary produced the seeds, and skipped all downstream marts.- Seed column-type divergence: v2 infers
Int64/Float64/DateTime64(6)where v1 givesInt32/Float32/DateTime. Explicitly deferred, tracked in dbt Core 2.0 parity: future work (explicitly deferred items) #731 (and noted in dbt Core 2.0 parity: Materializationseed#709). Not the cause of the jaffle-shop failures.
Activity
[-]dbt Core 2.0: silent SQL statement drops — seed data loss with quotes in CSV data (jaffle-shop validation)[/-][+]dbt Core 2.0: jaffle-shop validation[/+]