-
Notifications
You must be signed in to change notification settings - Fork 20
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
AST edit for container type #268
Comments
Edits can be done on any pythonized type, they should work fine. For certain edits you may need to edit the raw AST instead of using a mutator, the mutator is based on visitor functions that trigger only on certain nodes. So I think the issue in this case is that We would need to implement a mutate_query function that uses the associated visitor: https://docs.rs/sqlparser/latest/sqlparser/ast/trait.VisitorMut.html#method.post_visit_query, then you'd have full access to |
@wseaton true, modifying AST directly works well, my use case was mostly around finding the node, which would get extensive (but can also be wrapped): ...
new_ast = copy.deepcopy(ast)
buffer = [new_ast]
while buffer != []:
new_buffer = []
for item in buffer:
if isinstance(item, list):
new_buffer.extend(item)
elif isinstance(item, dict):
for key in item:
if key == "cte_tables":
item["cte_tables"] = list(sorted(item["cte_tables"], key=lambda x: x["alias"]["name"]["value"]))
elif isinstance(item[key], list):
new_buffer.extend(item[key])
elif isinstance(item[key], dict):
new_buffer.append(item[key])
# else don't care for primitive types
buffer = new_buffer
return new_ast maybe I could look into adding |
Would exposing a binding to https://docs.rs/sqlparser/latest/sqlparser/ast/fn.visit_statements_mut.html work? You'd still need to match on statement type equals SELECT, but that should let you mutate the order of the CTEs. |
@psukys here's the equivalent rust code as a PoC: use std::ops::ControlFlow;
use sqlparser::{
ast::{visit_statements_mut, Statement},
dialect::GenericDialect,
parser::Parser,
};
fn main() {
let sql =
"with my_cte2 as ( select 1 ), my_cte1 as ( select 2 ) select * from my_cte1 join my_cte2 ";
let mut statements = Parser::parse_sql(&GenericDialect {}, sql).unwrap();
visit_statements_mut(&mut statements, |stmt| {
if let Statement::Query(query) = stmt {
if let Some(with) = &mut query.with {
let _ = &with.cte_tables.sort_by(|a, b| a.alias.cmp(&b.alias));
}
}
ControlFlow::<()>::Continue(())
});
assert_eq!(
&statements[0].to_string(),
"WITH my_cte1 AS (SELECT 2), my_cte2 AS (SELECT 1) SELECT * FROM my_cte1 JOIN my_cte2"
);
} |
In example, as I understood, edits are applied only on textual/string data, can this be enhanced to other built-in types, such as lists? For example:
The text was updated successfully, but these errors were encountered: