diff --git a/datafusion/sql/src/unparser/dialect.rs b/datafusion/sql/src/unparser/dialect.rs
index a3367dd96ce2..fa9d40c6c78a 100644
--- a/datafusion/sql/src/unparser/dialect.rs
+++ b/datafusion/sql/src/unparser/dialect.rs
@@ -24,7 +24,7 @@ use super::{
use arrow::array::timezone::Tz;
use arrow::datatypes::TimeUnit;
use chrono::DateTime;
-use datafusion_common::Result;
+use datafusion_common::{Result, internal_err};
use datafusion_expr::Expr;
use regex::Regex;
use sqlparser::tokenizer::Span;
@@ -351,6 +351,10 @@ impl Dialect for PostgreSqlDialect {
func_name: &str,
args: &[Expr],
) -> Result> {
+ if func_name == "array_has" {
+ return self.array_has_to_sql_any(unparser, args);
+ }
+
if func_name == "round" {
return Ok(Some(
self.round_to_sql_enforce_numeric(unparser, func_name, args)?,
@@ -362,6 +366,23 @@ impl Dialect for PostgreSqlDialect {
}
impl PostgreSqlDialect {
+ fn array_has_to_sql_any(
+ &self,
+ unparser: &Unparser,
+ args: &[Expr],
+ ) -> Result > {
+ let [haystack, needle] = args else {
+ return internal_err!("array_has expected 2 arguments, got {}", args.len());
+ };
+
+ Ok(Some(ast::Expr::AnyOp {
+ left: Box::new(unparser.expr_to_sql(needle)?),
+ compare_op: BinaryOperator::Eq,
+ right: Box::new(unparser.expr_to_sql(haystack)?),
+ is_some: false,
+ }))
+ }
+
fn round_to_sql_enforce_numeric(
&self,
unparser: &Unparser,
diff --git a/datafusion/sql/src/unparser/expr.rs b/datafusion/sql/src/unparser/expr.rs
index 686650b1c8c5..a4a231d9857c 100644
--- a/datafusion/sql/src/unparser/expr.rs
+++ b/datafusion/sql/src/unparser/expr.rs
@@ -1853,7 +1853,7 @@ mod tests {
use datafusion_functions::expr_fn::{get_field, named_struct};
use datafusion_functions_aggregate::count::count_udaf;
use datafusion_functions_aggregate::expr_fn::sum;
- use datafusion_functions_nested::expr_fn::{array_element, make_array};
+ use datafusion_functions_nested::expr_fn::{array_element, array_has, make_array};
use datafusion_functions_nested::map::map;
use datafusion_functions_window::rank::rank_udwf;
use datafusion_functions_window::row_number::row_number_udwf;
@@ -3074,6 +3074,24 @@ mod tests {
Ok(())
}
+ #[test]
+ fn test_postgres_array_has_to_any() -> Result<()> {
+ let default_dialect: Arc = Arc::new(DefaultDialect {});
+ let postgres_dialect: Arc = Arc::new(PostgreSqlDialect {});
+ let expr = array_has(col("items"), lit(1));
+
+ for (dialect, expected) in [
+ (default_dialect, "array_has(\"items\", 1)"),
+ (postgres_dialect, "1 = ANY(\"items\")"),
+ ] {
+ let unparser = Unparser::new(dialect.as_ref());
+ let actual = format!("{}", unparser.expr_to_sql(&expr)?);
+ assert_eq!(actual, expected);
+ }
+
+ Ok(())
+ }
+
#[test]
fn test_window_func_support_window_frame() -> Result<()> {
let default_dialect: Arc =
diff --git a/datafusion/sql/tests/cases/plan_to_sql.rs b/datafusion/sql/tests/cases/plan_to_sql.rs
index aefb404ba410..0dad48b16897 100644
--- a/datafusion/sql/tests/cases/plan_to_sql.rs
+++ b/datafusion/sql/tests/cases/plan_to_sql.rs
@@ -361,6 +361,17 @@ fn roundtrip_statement_with_dialect_3() -> Result<(), DataFusionError> {
Ok(())
}
+#[test]
+fn roundtrip_statement_postgres_any_array_expr() -> Result<(), DataFusionError> {
+ roundtrip_statement_with_dialect_helper!(
+ sql: "select left from array where 1 = any(left);",
+ parser_dialect: GenericDialect {},
+ unparser_dialect: UnparserPostgreSqlDialect {},
+ expected: @r#"SELECT "array"."left" FROM "array" WHERE 1 = ANY("array"."left")"#,
+ );
+ Ok(())
+}
+
#[test]
fn roundtrip_statement_with_dialect_4() -> Result<(), DataFusionError> {
roundtrip_statement_with_dialect_helper!(