{"record":{"id":"d00ec301476ed91a","repo":"risingwavelabs/risingwave","slug":"unknown-minimal-compatible-type-for-a-and-b","errorCode":null,"errorMessage":"unknown minimal compatible type for {a:?} and {b:?}","messagePattern":"unknown minimal compatible type for (.+?) and (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/expr/macro/src/types.rs","lineNumber":150,"sourceCode":"        (\"int256\", \"int4\") => \"int256\",\n        (\"int256\", \"int8\") => \"int256\",\n        (\"int256\", \"float8\") => \"float8\",\n        (\"float8\", \"int256\") => \"float8\",\n\n        (\"float4\", \"float4\") => \"float4\",\n        (\"float4\", \"float8\") => \"float8\",\n\n        (\"float8\", \"float4\") => \"float8\",\n        (\"float8\", \"float8\") => \"float8\",\n\n        (\"decimal\", \"decimal\") => \"decimal\",\n\n        (\"date\", \"timestamp\") => \"timestamp\",\n        (\"timestamp\", \"date\") => \"timestamp\",\n        (\"time\", \"interval\") => \"interval\",\n        (\"interval\", \"time\") => \"interval\",\n\n        (a, b) => panic!(\"unknown minimal compatible type for {a:?} and {b:?}\"),\n    }\n}\n","sourceCodeStart":132,"sourceCodeEnd":153,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/macro/src/types.rs#L132-L153","documentation":"This panic comes from `min_compatible_type` in RisingWave's type macro crate, which computes the minimal (least restrictive) common type that two scalar types can be coerced into. The function enumerates an exhaustive table of known compatible type pairs (e.g. date/timestamp -> timestamp, time/interval -> interval). When it receives a pair it has no mapping for, it panics with the debug-formatted pair, signaling an unhandled type combination rather than a user-facing error.","triggerScenarios":"Calling `min_compatible_type(a, b)` with a type pair absent from the match table, e.g. two unrelated primitive types like `varchar` and `timestamp` or custom/newly added types not yet registered in the compatibility table.","commonSituations":"Adding a new data type to RisingWave and forgetting to extend the compatibility table; planner/expr code paths performing implicit type unification on columns of mismatched types; tests feeding unusual type combinations.","solutions":["Add a mapping arm for the offending (a, b) pair in the match in src/expr/macro/src/types.rs returning the intended minimal type.","Explicitly cast one of the operands to a shared type upstream so the pair hits an existing arm.","If the pair is genuinely incompatible, reject it earlier with a proper error instead of reaching type unification."],"exampleFix":"// before\n(a, b) => panic!(\"unknown minimal compatible type for {a:?} and {b:?}\"),\n// after\n(\"varchar\", \"varchar\") => \"varchar\",\n(a, b) => panic!(\"unknown minimal compatible type for {a:?} and {b:?}\"),","handlingStrategy":"type-guard","validationCode":"// check pair is supported before calling\nfn is_supported(a: &DataType, b: &DataType) -> bool {\n    matches!((a, b), (DataType::Date, DataType::Timestamp) | (DataType::Time, DataType::Interval) | ..)\n}","typeGuard":"fn has_min_compatible(a: &DataType, b: &DataType) -> bool { MIN_COMPAT_TABLE.contains(&(a, b)) }","tryCatchPattern":"// panics instead of returning Result: pre-validate the pair, or wrap in catch_unwind for test harnesses\nlet compat = std::panic::catch_unwind(|| min_compatible_type(a, b));","preventionTips":["Enumerate all type pairs your queries can produce before relying on implicit unification","When adding a new DataType, grep min_compatible_type and extend the table in the same PR","Favor explicit CASTs in SQL over relying on implicit minimal-type resolution"],"tags":["types","type-coercion","panic","internal"],"backgroundTag":"internal-invariant-violation","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}