{"record":{"id":"c2647d90ec37a11b","repo":"risingwavelabs/risingwave","slug":"join-key-types-are-not-aligned-lhs-outer-type","errorCode":null,"errorMessage":"Join key types are not aligned: LHS: {outer_type:?}, RHS: {inner_type:?}","messagePattern":"Join key types are not aligned: LHS: (.+?), RHS: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/batch/executors/src/executor/join/distributed_lookup_join.rs","lineNumber":340,"sourceCode":"        let mut scan_range = ScanRange::full_table_scan();\n\n        for ((datum, outer_type), inner_type) in key_datums\n            .into_iter()\n            .zip_eq_fast(\n                self.outer_side_key_types\n                    .iter()\n                    .take(self.lookup_prefix_len),\n            )\n            .zip_eq_fast(\n                self.inner_side_key_types\n                    .iter()\n                    .take(self.lookup_prefix_len),\n            )\n        {\n            let datum = if inner_type == outer_type {\n                datum\n            } else {\n                bail!(\"Join key types are not aligned: LHS: {outer_type:?}, RHS: {inner_type:?}\");\n            };\n\n            scan_range.eq_conds.push(datum);\n        }\n\n        let pk_prefix = OwnedRow::new(scan_range.eq_conds);\n\n        if self.lookup_prefix_len == self.table.pk_indices().len() {\n            let row = self.table.get_row(&pk_prefix, self.epoch.into()).await?;\n\n            if let Some(row) = row {\n                self.row_list.push(row);\n            }\n        } else {\n            let iter = self\n                .table\n                .batch_iter_with_pk_bounds(\n                    self.epoch.into(),","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/batch/executors/src/executor/join/distributed_lookup_join.rs#L322-L358","documentation":"When building scan ranges for the inner side of a distributed lookup join, each outer join-key Datum's type must exactly match the corresponding inner-side key column type; otherwise the datum would be pushed into an eq_cond with the wrong type. The code bails with this message naming the mismatched LHS (outer) and RHS (inner) types.","triggerScenarios":"add_scan_range is invoked with outer key datums whose DataType differs from the inner table's key column types — e.g. after a schema change of the materialized/inner table, or a planner bug producing mismatched key types between the join's two sides.","commonSituations":"Altering the inner table's column type after the join plan was created; stale plans referencing an old table schema; type coercion not applied in the lookup-prefix key extraction.","solutions":["Verify the inner table schema matches what the join plan was built against; refresh the plan","Recreate/refresh the materialized view or table so key column types align with the outer side","Ensure the frontend applies implicit casts so outer key datums match inner key types before lookup"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn keys_aligned(outer_types: &[DataType], inner_types: &[DataType]) -> bool {\n    outer_types.len() == inner_types.len()\n        && outer_types.iter().zip(inner_types).all(|(o, i)| o == i)\n}","typeGuard":null,"tryCatchPattern":"match executor_result {\n    Err(e) if e.to_string().contains(\"Join key types are not aligned\") => {\n        // re-plan with current schema / re-create lookup table before retrying\n    }\n    other => other?,\n}","preventionTips":["Apply implicit casts on join keys in the planner so both sides share one DataType","After altering a lookup table's column types, always re-plan queries touching it","Add a planner test asserting lookup join key types match across sides"],"tags":["rust","lookup-join","type-mismatch","schema"],"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"}