{"record":{"id":"3ee79a6fb9c9f37d","repo":"risingwavelabs/risingwave","slug":"can-t-convert-int-to-scalarimpl","errorCode":null,"errorMessage":"Can't convert int {} to ScalarImpl::{}","messagePattern":"Can't convert int (.+?) to ScalarImpl::(.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/connector/src/source/cdc/external/postgres.rs","lineNumber":833,"sourceCode":"            }\n            left = right;\n            right = left.map(|l| l.saturating_add(saturated_split_max_size));\n        }\n    }\n\n    fn split_column(&self, options: &CdcTableSnapshotSplitOption) -> Field {\n        self.rw_schema.fields[self.pk_indices[options.backfill_split_pk_column_index as usize]]\n            .clone()\n    }\n}\n\nfn to_int_scalar(i: i64, data_type: &DataType) -> ScalarImpl {\n    match data_type {\n        DataType::Int16 => ScalarImpl::Int16(i.try_into().unwrap()),\n        DataType::Int32 => ScalarImpl::Int32(i.try_into().unwrap()),\n        DataType::Int64 => ScalarImpl::Int64(i),\n        _ => {\n            panic!(\"Can't convert int {} to ScalarImpl::{}\", i, data_type)\n        }\n    }\n}\n\nfn try_increase_split_id(split_id: &mut i64) -> ConnectorResult<()> {\n    match split_id.checked_add(1) {\n        Some(s) => {\n            *split_id = s;\n            Ok(())\n        }\n        None => Err(anyhow::anyhow!(\"too many CDC snapshot splits\").into()),\n    }\n}\n\n/// Use the first column of primary keys to split table.\nfn is_supported_even_split_data_type(data_type: &DataType) -> bool {\n    matches!(\n        data_type,","sourceCodeStart":815,"sourceCodeEnd":851,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/source/cdc/external/postgres.rs#L815-L851","documentation":"`to_int_scalar` converts a Postgres integer read as i64 into a RisingWave `ScalarImpl` matching the declared column type. If the declared `DataType` is not Int16/Int32/Int64 the function panics with this message rather than returning an error. It indicates an internal mismatch between the type recorded in schema metadata and the actual key column type.","triggerScenarios":"`snapshot_read_inner` calls `to_int_scalar` for a split's PK boundary value whose `DataType` is anything other than Int16, Int32, or Int64 (e.g. UInt types, Decimal) — i.e. the split column was treated as an integer type but its metadata type differs.","commonSituations":"Schema drift changing a PK column type after splits were planned; metadata/type mapping bugs in `pg_type_to_rw_type`; using an uneven-split path on a column whose mapped type is not a signed integer.","solutions":["Report/fix the type mapping so only integer PK types take the integer-scalar path.","Refresh the CDC table schema (re-create the table) so metadata matches the upstream types.","Verify the split PK column is actually a smallint/integer/bigint upstream.","If you maintain the code, convert this panic into a `ConnectorError` for graceful handling."],"exampleFix":"// before (panic on mismatch)\n_ => panic!(\"Can't convert int {} to ScalarImpl::{}\", i, data_type),\n// after (graceful error)\n_ => return Err(ConnectorError::from(anyhow::anyhow!(\n    \"Can't convert int {} to ScalarImpl::{}\", i, data_type))),","handlingStrategy":"type-guard","validationCode":"// Only take the integer path when the mapped type is a signed integer\nif !matches!(data_type, DataType::Int16 | DataType::Int32 | DataType::Int64) {\n    return Err(\"split column is not an integer type\");\n}","typeGuard":"fn is_supported_int_type(dt: &DataType) -> bool {\n    matches!(dt, DataType::Int16 | DataType::Int32 | DataType::Int64)\n}","tryCatchPattern":"// The function panics, so guard callsites instead:\nif !is_supported_int_type(&pk_data_type) {\n    return Err(anyhow::anyhow!(\"integer split path not applicable to {}\", pk_data_type).into());\n}\nlet scalar = to_int_scalar(i, &pk_data_type);","preventionTips":["Only enable uneven integer splitting for smallint/integer/bigint PK columns.","Re-create CDC tables after upstream type changes to refresh metadata.","Prefer returning errors over panics in connector library code."],"tags":["cdc","postgres","type-mismatch","panic"],"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"}