From 1f576593ec77fef03cbadd2ddc98051bbf3b6eef Mon Sep 17 00:00:00 2001 From: RS2007 Date: Tue, 14 Oct 2025 01:33:39 +0530 Subject: [PATCH] adding duplicate cte name checks in planner.rs --- core/translate/planner.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/core/translate/planner.rs b/core/translate/planner.rs index 0409ae786..ee5fe7bcc 100644 --- a/core/translate/planner.rs +++ b/core/translate/planner.rs @@ -644,12 +644,13 @@ pub fn parse_from( return Ok(()); } - let mut ctes_as_subqueries = vec![]; + let mut ctes_as_subqueries: Vec = vec![]; if let Some(with) = with { if with.recursive { crate::bail_parse_error!("Recursive CTEs are not yet supported"); } + for cte in with.ctes { if cte.materialized == Materialized::Yes { crate::bail_parse_error!("Materialized CTEs are not yet supported"); @@ -662,6 +663,13 @@ pub fn parse_from( // TODO: sqlite actually allows overriding a catalog table with a CTE. // We should carry over the 'Scope' struct to all of our identifier resolution. let cte_name_normalized = normalize_ident(cte.tbl_name.as_str()); + if ctes_as_subqueries + .iter() + .any(|t| t.table.get_name() == cte_name_normalized.to_string()) + { + crate::bail_parse_error!("duplicate WITH table name: {}", cte.tbl_name.as_str()); + } + if resolver.schema.get_table(&cte_name_normalized).is_some() { crate::bail_parse_error!( "CTE name {} conflicts with catalog table name", @@ -702,6 +710,7 @@ pub fn parse_from( let Plan::Select(cte_plan) = cte_plan else { crate::bail_parse_error!("Only SELECT queries are currently supported in CTEs"); }; + ctes_as_subqueries.push(JoinedTable::new_subquery( cte_name_normalized, cte_plan,