From 7197858e21ebe4396a125da0ac3818c344c7c14e Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sun, 15 Feb 2026 15:29:25 +0800 Subject: [PATCH] fix: add support for moving nested cast --- datafusion-pg-catalog/src/sql/rules.rs | 22 ++++++++++++++++++++++ datafusion-postgres/tests/pgadbc.rs | 24 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 datafusion-postgres/tests/pgadbc.rs diff --git a/datafusion-pg-catalog/src/sql/rules.rs b/datafusion-pg-catalog/src/sql/rules.rs index 91c6553..6853700 100644 --- a/datafusion-pg-catalog/src/sql/rules.rs +++ b/datafusion-pg-catalog/src/sql/rules.rs @@ -361,6 +361,7 @@ impl VisitorMut for RemoveUnsupportedTypesVisitor<'_> { .unsupported_types .contains(data_type.to_string().to_lowercase().as_str()) { + self.remove_nested_unsupported_casts(value); *expr = *value.clone(); } } @@ -372,6 +373,25 @@ impl VisitorMut for RemoveUnsupportedTypesVisitor<'_> { } } +impl RemoveUnsupportedTypesVisitor<'_> { + fn remove_nested_unsupported_casts(&mut self, expr: &mut Expr) { + if let Expr::Cast { + data_type, + expr: value, + .. + } = expr + { + if self + .unsupported_types + .contains(data_type.to_string().to_lowercase().as_str()) + { + self.remove_nested_unsupported_casts(value); + *expr = *value.clone(); + } + } + } +} + impl SqlStatementRewriteRule for RemoveUnsupportedTypes { fn rewrite(&self, mut statement: Statement) -> Statement { let mut visitor = RemoveUnsupportedTypesVisitor { @@ -995,6 +1015,8 @@ mod tests { WHERE c.oid = '16386'", "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, false AS relhasoids, c.relispartition, '', c.reltablespace, CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::TEXT END, c.relpersistence, c.relreplident, am.amname FROM pg_catalog.pg_class AS c LEFT JOIN pg_catalog.pg_class AS tc ON (c.reltoastrelid = tc.oid) LEFT JOIN pg_catalog.pg_am AS am ON (c.relam = am.oid) WHERE c.oid = '16386'" ); + + assert_rewrite!(&rules, "SELECT $1::regclass::oid", "SELECT $1"); } #[test] diff --git a/datafusion-postgres/tests/pgadbc.rs b/datafusion-postgres/tests/pgadbc.rs new file mode 100644 index 0000000..24db14a --- /dev/null +++ b/datafusion-postgres/tests/pgadbc.rs @@ -0,0 +1,24 @@ +use pgwire::api::query::SimpleQueryHandler; + +use datafusion_postgres::testing::*; + +const PGADBC_QUERIES: &[&str] = &[ + "SELECT attname, atttypid FROM pg_catalog.pg_class AS cls INNER JOIN pg_catalog.pg_attribute AS attr ON cls.oid = attr.attrelid INNER JOIN pg_catalog.pg_type AS typ ON attr.atttypid = typ.oid WHERE attr.attnum >= 0 AND cls.oid = 1602::regclass::oid ORDER BY attr.attnum", + + +]; + +#[tokio::test] +pub async fn test_pgadbc_metadata_sql() { + env_logger::init(); + let service = setup_handlers(); + let mut client = MockClient::new(); + + for query in PGADBC_QUERIES { + SimpleQueryHandler::do_query(&service, &mut client, query) + .await + .unwrap_or_else(|e| { + panic!("failed to run sql:\n--------------\n {query}\n--------------\n{e}") + }); + } +}