{"record":{"id":"6fde8ba38e3e75dd","repo":"risingwavelabs/risingwave","slug":"column-data-type-is-incompatible-with-down","errorCode":null,"errorMessage":"column {} data type {:?} is incompatible with downstream SQL Server type {}","messagePattern":"column (.+?) data type (.+?) is incompatible with downstream SQL Server type (.+?)","errorType":"validation","errorClass":"SinkError::SqlServer","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/sqlserver.rs","lineNumber":957,"sourceCode":"    }\n}\n\nfn normalize_sql_server_column_name(column_name: &str) -> String {\n    // SQL Server identifiers are usually case-insensitive depending on database collation.\n    // Match metadata by a case-insensitive key so validation follows that common behavior.\n    column_name.to_lowercase()\n}\n\nfn validate_data_type_compatibility(\n    column_name: &str,\n    rw_data_type: &DataType,\n    sql_server_data_type: &str,\n) -> Result<()> {\n    if sql_server_data_type_is_compatible(rw_data_type, sql_server_data_type) {\n        return Ok(());\n    }\n\n    Err(SinkError::SqlServer(anyhow!(format!(\n        \"column {} data type {:?} is incompatible with downstream SQL Server type {}\",\n        column_name, rw_data_type, sql_server_data_type\n    ))))\n}\n\nfn sql_server_data_type_is_compatible(rw_data_type: &DataType, sql_server_data_type: &str) -> bool {\n    match rw_data_type {\n        DataType::Boolean => sql_server_data_type == \"bit\",\n        DataType::Int16 => matches!(sql_server_data_type, \"smallint\" | \"int\" | \"bigint\"),\n        DataType::Int32 => matches!(sql_server_data_type, \"int\" | \"bigint\"),\n        DataType::Int64 => sql_server_data_type == \"bigint\",\n        DataType::Float32 => matches!(sql_server_data_type, \"real\" | \"float\"),\n        DataType::Float64 => sql_server_data_type == \"float\",\n        DataType::Decimal => matches!(sql_server_data_type, \"decimal\" | \"numeric\"),\n        DataType::Date => sql_server_data_type == \"date\",\n        DataType::Varchar => matches!(\n            sql_server_data_type,\n            \"char\" | \"nchar\" | \"varchar\" | \"nvarchar\" | \"text\" | \"ntext\"","sourceCodeStart":939,"sourceCodeEnd":975,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/sqlserver.rs#L939-L975","documentation":"During sink validation, each RisingWave column's data type is compared against the downstream SQL Server column's type via `sql_server_data_type_is_compatible`. If incompatible, this error names the column, the RW type (`{:?}` debug format), and the SQL Server type string. This preflight prevents runtime write failures or silent data corruption from type mismatches.","triggerScenarios":"`validate` -> `validate_data_type_compatibility`: e.g. RW `Int32` column vs downstream `nvarchar`, RW `Varchar` vs `int`, RW `Decimal` vs `float`, RW `Boolean` vs `int`, etc. — any pair the compatibility matrix rejects.","commonSituations":"Downstream table created with different types than the RW schema; user altered one side after sink creation; copy-pasted DDL where `BIGINT` became `INT`; RW migrations changed a column type while downstream stayed fixed.","solutions":["ALTER the downstream SQL Server column type to match the RW type shown in the error (e.g. `ALTER TABLE t ALTER COLUMN c BIGINT;`).","Or cast the column in the RW materialized view to match the downstream type before sinking.","Compare against the compatibility matrix in `sql_server_data_type_is_compatible` to pick a supported pair.","Drop and recreate the sink after aligning schemas so validation re-runs cleanly."],"exampleFix":"// RW column: amount DECIMAL(18,2), downstream: FLOAT\n-- before\nCREATE TABLE dbo.orders (amount FLOAT);\n-- after\nALTER TABLE dbo.orders ALTER COLUMN amount DECIMAL(18,2);","handlingStrategy":"validation","validationCode":"-- compare column types on both sides before CREATE SINK\nSELECT c.name, ty.name AS sqlserver_type\nFROM sys.columns c JOIN sys.types ty ON ty.user_type_id = c.user_type_id\nJOIN sys.tables t ON t.object_id = c.object_id\nWHERE t.name = 'orders';","typeGuard":null,"tryCatchPattern":"match sink.validate().await {\n    Err(e) if e.to_string().contains(\"is incompatible with downstream SQL Server type\") => {\n        reconcile_column_types(&parse_column_from_error(&e.to_string()));\n    }\n    other => other,\n}","preventionTips":["Generate downstream DDL from the RW schema automatically","Run sink validate in CI against the real SQL Server schema","Coordinate any type change with a paired downstream ALTER","Prefer exact type pairing per the compatibility matrix rather than 'close enough' types"],"tags":["sqlserver","sink","data-type","schema-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}