{"record":{"id":"d4057d7eae1d9795","repo":"risingwavelabs/risingwave","slug":"join-plan-cannot-be-generated-tables-not-connecte","errorCode":null,"errorMessage":"join plan cannot be generated, tables not connected.","messagePattern":"join plan cannot be generated, tables not connected\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/delta_join_solver.rs","lineNumber":391,"sourceCode":"\n            // step 4: place arrangements according to the arrange strategy, update current\n            // distribution and current table set.\n            for table in &solver_env.arrange_placement_order {\n                if let Some(edge) = reachable_tables.get(table) {\n                    current_table_set.insert(edge.right);\n                    path.push(edge.right);\n                    current_distribution.clear();\n                    current_distribution.push((edge.right, edge.right_join_key.clone()));\n                    continue 'next_table;\n                }\n            }\n\n            // step 5: no tables can be joined any more, what happened?\n            if self.join_order.len() - 1 == path.len() {\n                break;\n            } else {\n                // no table can be joined, while path is still incomplete\n                return Err(anyhow!(\n                    \"join plan cannot be generated, tables not connected.\"\n                ));\n            }\n        }\n\n        Ok(LookupPath(input_stream, path))\n    }\n\n    pub fn solve(&self) -> Result<Vec<LookupPath>> {\n        let solver_env = SolverEnv::build_from(self);\n\n        solver_env\n            .stream_placement_order\n            .iter()\n            .map(|x| self.find_lookup_path(&solver_env, *x))\n            .collect()\n    }\n","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/delta_join_solver.rs#L373-L409","documentation":"find_lookup_path builds a join order for a delta join by repeatedly finding a lookup-joinable connection between indexed tables. If, after a step, not all tables have been placed in the path yet but no more joins can be added, the tables are disconnected and no lookup join plan exists.","triggerScenarios":"Creating a materialized view over base tables where some index-connected tables share no join predicates that allow lookup joins, so the delta join solver cannot connect every table in one path (solve -> find_lookup_path).","commonSituations":"Delta join (index-based MVs) where the query joins tables that are only connected via non-indexed columns or via a third table not included; cross joins or predicates the delta join solver does not recognize.","solutions":["Create indexes on the join columns of the disconnected tables so lookup joins become possible.","Rewrite the query so tables are connected through indexed equality join predicates.","Remove the intermediate table if it is not needed, or include the connecting table in the query.","Fall back to a standard (non-delta-join) MV plan by not relying on index lookup joins."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"-- ensure all joined tables have indexes on equality join keys before creating the MV\nSELECT name FROM rw_catalog.rw_indexes WHERE ... ;","typeGuard":null,"tryCatchPattern":"match create_mv_result {\n    Err(e) if e.to_string().contains(\"tables not connected\") => {\n        eprintln!(\"Delta join requires index-connected tables; add missing indexes or rewrite joins\");\n    }\n    other => other?,\n}","preventionTips":["Create an index on every table's equality join keys used in the delta-join query.","Avoid cross joins and non-equality joins in index-backed MVs.","Verify the join graph is connected across all base tables before enabling delta joins."],"tags":["delta-join","planner","join","index"],"backgroundTag":"unsupported-operation","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"}