Repository: SeaQL/sea-query (language: rust)

Issue:
Empty PostgreSQL ARRAY should be printed with a cast
Otherwise, it will fail with "cannot determine type of empty array".

For example, an empty string vec will be converted to `ARRAY []` but PG needs `ARRAY[]::TEXT[]` or things like that for understanding the type.


Discussion / hints:
Or use `{}` as reported at https://github.com/graphile/crystal/issues/406.

Fix patch:
diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs
index 41cac862..a4f0b443 100644
--- a/src/backend/query_builder.rs
+++ b/src/backend/query_builder.rs
@@ -1104,15 +1104,21 @@ pub trait QueryBuilder:
             #[cfg(feature = "with-uuid")]
             Value::Uuid(Some(v)) => write!(s, "'{v}'").unwrap(),
             #[cfg(feature = "postgres-array")]
-            Value::Array(_, Some(v)) => write!(
-                s,
-                "ARRAY [{}]",
-                v.iter()
-                    .map(|element| self.value_to_string(element))
-                    .collect::<Vec<String>>()
-                    .join(",")
-            )
-            .unwrap(),
+            Value::Array(_, Some(v)) => {
+                if v.is_empty() {
+                    write!(s, "'{{}}'").unwrap()
+                } else {
+                    write!(
+                        s,
+                        "ARRAY [{}]",
+                        v.iter()
+                            .map(|element| self.value_to_string(element))
+                            .collect::<Vec<String>>()
+                            .join(",")
+                    )
+                    .unwrap()
+                }
+            }
             #[cfg(feature = "postgres-vector")]
             Value::Vector(Some(v)) => {
                 write!(s, "'[").unwrap();
diff --git a/src/value.rs b/src/value.rs
index 1499a331..e2e2f02a 100644
--- a/src/value.rs
+++ b/src/value.rs
@@ -849,7 +849,7 @@ pub mod with_array {
     use super::*;
     use crate::RcOrArc;
 
-    // We only imlement conversion from Vec<T> to Array when T is not u8.
+    // We only implement conversion from Vec<T> to Array when T is not u8.
     // This is because for u8's case, there is already conversion to Byte defined above.
     // TODO When negative trait becomes a stable feature, following code can be much shorter.
     pub trait NotU8 {}


Test patch:
diff --git a/tests/postgres/query.rs b/tests/postgres/query.rs
index 804818b1..e3a1b993 100644
--- a/tests/postgres/query.rs
+++ b/tests/postgres/query.rs
@@ -1275,6 +1275,20 @@ fn insert_10() {
     );
 }
 
+// regression tests for https://github.com/SeaQL/sea-query/issues/853
+#[test]
+#[cfg(feature = "postgres-array")]
+fn insert_issue_853() {
+    assert_eq!(
+        Query::insert()
+            .into_table(Glyph::Table)
+            .columns([Glyph::Aspect, Glyph::Tokens])
+            .values_panic([3.1415.into(), Vec::<String>::new().into()])
+            .to_string(PostgresQueryBuilder),
+        r#"INSERT INTO "glyph" ("aspect", "tokens") VALUES (3.1415, '{}')"#
+    );
+}
+
 #[test]
 #[allow(clippy::approx_constant)]
 fn insert_on_conflict_1() {