-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix a cte block with same name for many times #1639
Conversation
It is a unreasonable behavior that a single cte block with the same name for many times. But currently, datafusion doesn't process it correctly. // datafusion
❯ create table t1 as select '123' as c;
0 rows in set. Query took 0.005 seconds.
❯ create table t3 as select '12' as c;
0 rows in set. Query took 0.005 seconds.
❯ with a as (select * from t1), a as (select * from t3) select * from a;
+----+
| c |
+----+
| 12 |
+----+
1 row in set. Query took 0.007 seconds.
//postgres
postgres=# with a as (select * from t1), a as (select * from t2) select * from a;
ERROR: WITH query name "a" specified more than once
LINE 1: with a as (select * from t1), a as (select * from t2) select... |
datafusion/src/sql/planner.rs
Outdated
// Process CTEs from top to bottom | ||
// do not allow self-references | ||
for cte in &with.cte_tables { | ||
let cte_name = cte.alias.name.value.clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you do need a hashtable in this function, I think you can avoid cloning the string here (and just store &str
in the set):
let cte_name = cte.alias.name.value.clone(); | |
let cte_name = cte.alias.name.value.as_ref(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @xudong963 👍
datafusion/src/sql/planner.rs
Outdated
@@ -213,9 +213,19 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { | |||
) -> Result<LogicalPlan> { | |||
let set_expr = &query.body; | |||
if let Some(with) = &query.with { | |||
// a `WITH` block can't use the same name for many times | |||
let mut cte_names = HashSet::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this function gets a hashtable called ctes
as a parameter, I wonder if you could check for the name in that hashtable rather than making a new one?
ctes: &mut HashMap<String, LogicalPlan>,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, good catch, we can reuse ctes
!
Fixed, plz take another look when you have time @alamb |
Thanks @xudong963 , @Dandandan and @houqp ! |
Which issue does this PR close?
Fix a cte block with same name for many times
Rationale for this change
What changes are included in this PR?
Are there any user-facing changes?