risingwavelabs/risingwave · error
join plan cannot be generated, tables not connected.
Error message
join plan cannot be generated, tables not connected.
What it means
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.
Source
Thrown at src/frontend/src/optimizer/delta_join_solver.rs:391
// step 4: place arrangements according to the arrange strategy, update current
// distribution and current table set.
for table in &solver_env.arrange_placement_order {
if let Some(edge) = reachable_tables.get(table) {
current_table_set.insert(edge.right);
path.push(edge.right);
current_distribution.clear();
current_distribution.push((edge.right, edge.right_join_key.clone()));
continue 'next_table;
}
}
// step 5: no tables can be joined any more, what happened?
if self.join_order.len() - 1 == path.len() {
break;
} else {
// no table can be joined, while path is still incomplete
return Err(anyhow!(
"join plan cannot be generated, tables not connected."
));
}
}
Ok(LookupPath(input_stream, path))
}
pub fn solve(&self) -> Result<Vec<LookupPath>> {
let solver_env = SolverEnv::build_from(self);
solver_env
.stream_placement_order
.iter()
.map(|x| self.find_lookup_path(&solver_env, *x))
.collect()
}
View on GitHub (pinned to 6469eb736d)
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.
Defensive patterns
Strategy: validation
Validate before calling
-- ensure all joined tables have indexes on equality join keys before creating the MV SELECT name FROM rw_catalog.rw_indexes WHERE ... ;
Try / catch
match create_mv_result {
Err(e) if e.to_string().contains("tables not connected") => {
eprintln!("Delta join requires index-connected tables; add missing indexes or rewrite joins");
}
other => other?,
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- only inner join without non-equal condition is supported for
- Row sequential scan should not have input executor!
- Source should not have input executor!
- Row sequential scan should not have input executor!
- GenerateSeriesExecutor should not have child!
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/d4057d7eae1d9795.
Report an issue: GitHub.