Classify NULL-to-non-Nullable MV CDC errors#4464
Conversation
ClickHouse error code 349 (CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN, "Cannot convert NULL value to non-Nullable type") was surfacing as errorClass=OTHER / errorCode=UNKNOWN because it is not handled in the exception switch and is not wrapped as a ViewError/NormalizationError. PeerDB always creates Nullable destination columns, so a 349 only arises when a user-defined MV/view casts a nullable source column to a non-Nullable type. Classify it as NOTIFY_MV_OR_VIEW so the user is told their MV/view is the problem. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
1 similar comment
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
The mid-CDC failure surfaces at the classifier as a Temporal-serialized string with the underlying *clickhouse.Exception type stripped, so it fails every typed check and falls through to ErrorOther / "UNKNOWN" (matching the reported errorClass=OTHER / errorCode=UNKNOWN). The typed switch case for code 349 added earlier only fires when the cause is still typed, which is not the production path. Match the distinctive message "Cannot convert NULL value to non-Nullable type" on the raw error string and classify it as NOTIFY_MV_OR_VIEW (source clickhouse, code 349). PeerDB always creates Nullable destination columns, so this only arises through a user-defined MV/view casting a nullable source column to a non-Nullable type. Add a test covering the serialized (string-only) production path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Correction: the error is wrapped as a ViewError, and the original fix didn't actually fix itThanks to the review pointer (logs show I verified the real behavior empirically against the classifier:
Two conclusions:
Updated fixAdded a string-based match on the distinctive message The type-based switch case is kept as a defensive net (catches code 349 even if ClickHouse changes the message wording). Added a test covering the serialized (string-only) production path; the typed-path test is retained. Pushed in 58310d2. |
Problem
ClickHouse CDC failures with
code: 349, Cannot convert NULL value to non-Nullable typewere surfacing aserrorClass=OTHER/errorCode=UNKNOWN(DBI-863). This happens when a user-defined materialized view casts a nullable source column to a non-Nullable type (e.g.String), causing inserts pushed to the view to fail.Reported failing views/columns:
cdc_user_api.stg_cdc_user_api__customer_address_mv→streetcdc_otc_api.stg_cdc_otc_api__otc_otc_trade_mv→settlement_txn_id_incomingThe error code 349 (
CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN) is not handled in the ClickHouse exception switch inclassifier.go, and in this path the error is not wrapped as aViewError/NormalizationError, so it fell through to theOTHER/UNKNOWNcatch-all.Fix
Add an explicit case for
chproto.ErrCannotInsertNullInOrdinaryColumn(349) that classifies the error asNOTIFY_MV_OR_VIEW. PeerDB always creates Nullable destination columns, so a 349 only arises through a user-defined MV/view casting a column to a non-Nullable type — makingNOTIFY_MV_OR_VIEWthe correct, actionable classification.Tests
Added
TestCannotInsertNullInOrdinaryColumnShouldBeNotifyMVcovering the real-world error message shape (includingwhile pushing to view), assertingErrorNotifyMVOrViewwith sourceclickhouseand code349.🤖 Generated with Claude Code