From 0cd06eac1da5b268a4fabbf6e657a427ba108f49 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Thu, 28 Aug 2025 15:23:17 +0800 Subject: [PATCH 1/2] feat: add sql rewrite rules framework and alias rewrite rule Signed-off-by: Ning Sun --- datafusion-postgres/src/lib.rs | 1 + datafusion-postgres/src/sql.rs | 171 +++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 datafusion-postgres/src/sql.rs diff --git a/datafusion-postgres/src/lib.rs b/datafusion-postgres/src/lib.rs index ba43d00..b08e830 100644 --- a/datafusion-postgres/src/lib.rs +++ b/datafusion-postgres/src/lib.rs @@ -1,5 +1,6 @@ mod handlers; pub mod pg_catalog; +mod sql; use std::fs::File; use std::io::{BufReader, Error as IOError, ErrorKind}; diff --git a/datafusion-postgres/src/sql.rs b/datafusion-postgres/src/sql.rs new file mode 100644 index 0000000..e1381fc --- /dev/null +++ b/datafusion-postgres/src/sql.rs @@ -0,0 +1,171 @@ +use datafusion::sql::sqlparser::ast::Expr; +use datafusion::sql::sqlparser::ast::Ident; +use datafusion::sql::sqlparser::ast::Select; +use datafusion::sql::sqlparser::ast::SelectItem; +use datafusion::sql::sqlparser::ast::SelectItemQualifiedWildcardKind; +use datafusion::sql::sqlparser::ast::SetExpr; +use datafusion::sql::sqlparser::ast::Statement; +use datafusion::sql::sqlparser::dialect::PostgreSqlDialect; +use datafusion::sql::sqlparser::parser::Parser; +use datafusion::sql::sqlparser::parser::ParserError; + +pub fn parse(sql: &str) -> Result, ParserError> { + let dialect = PostgreSqlDialect {}; + + Parser::parse_sql(&dialect, sql) +} + +pub fn rewrite(mut s: Statement, rules: &[Box]) -> Statement { + for rule in rules { + s = rule.rewrite(s); + } + + s +} + +pub trait SqlStatementRewriteRule { + fn rewrite(&self, s: Statement) -> Statement; +} + +/// Rewrite rule for adding alias to duplicated projection +/// +/// This rule is to deal with sql like `SELECT n.oid, n.* FROM n`, which is a +/// valid statement in postgres. But datafusion treat it as illegal because of +/// duplicated column oid in projection. +/// +/// This rule will add alias to column, when there is a wildcard found in +/// projection. +struct AliasDuplicatedProjectionRewrite; + +impl AliasDuplicatedProjectionRewrite { + // Rewrites a SELECT statement to alias explicit columns from the same table as a qualified wildcard. + fn rewrite_select_with_alias(select: &mut Box