Summary
json_array_to_pg_literal has no empty-array special case. An empty JSON array [] produces ARRAY[] (an ARRAY[] constructor with no elements), where the built-in driver returns {} — the canonical PostgreSQL empty-array literal that the server always accepts. ARRAY[] is accepted only when the target column type is unambiguous; in many contexts it is a syntax/type error.
Builtin behavior (upstream main)
src-tauri/src/drivers/postgres/helpers.rs::json_array_to_pg_literal:
pub fn json_array_to_pg_literal(arr: &[serde_json::Value]) -> Result<String, String> {
if arr.is_empty() {
return Ok("{}".to_string());
}
// … ARRAY[...] for non-empty
}
Plugin behavior (this repo)
src/binding.rs:333 — json_array_to_pg_literal has no is_empty() guard. An empty [] skips the loop (parts stays empty) and returns format!("ARRAY[{}]", "") = ARRAY[]. The non-empty path matches the builtin exactly (ARRAY[...]); only the empty case diverges.
This is reached both from the Value::Array arm in bind_pg_value (src/binding.rs:106) and the inline array-literal parse in bind_pg_string (:287).
Reproduction
CREATE TABLE t (ids int[]);
Inserting {"ids": []}:
- Builtin:
INSERT INTO "s"."t" (ids) VALUES ({}) → succeeds.
- Plugin:
INSERT INTO "s"."t" (ids) VALUES (ARRAY[]) → syntax error at or near "]" / cannot determine type of empty array depending on context.
Impact
- Severity: Medium. INSERT/UPDATE of an empty array into an array column fails server-side where the builtin succeeds. The error message is a generic syntax/type error, not clearly tied to the empty array.
- Not caught by the parity suite (no empty-array bind test).
Fix
Add the empty-array guard at the top of json_array_to_pg_literal (src/binding.rs:333):
if arr.is_empty() {
return Ok("{}".to_string());
}
Add a unit test in binding_tests.rs: a Value::Array(vec![]) binds to {}, not ARRAY[].
Related
- Builtin reference:
TabularisDB/tabularis drivers/postgres/helpers.rs::json_array_to_pg_literal.
Summary
json_array_to_pg_literalhas no empty-array special case. An empty JSON array[]producesARRAY[](anARRAY[]constructor with no elements), where the built-in driver returns{}— the canonical PostgreSQL empty-array literal that the server always accepts.ARRAY[]is accepted only when the target column type is unambiguous; in many contexts it is a syntax/type error.Builtin behavior (upstream
main)src-tauri/src/drivers/postgres/helpers.rs::json_array_to_pg_literal:Plugin behavior (this repo)
src/binding.rs:333—json_array_to_pg_literalhas nois_empty()guard. An empty[]skips the loop (partsstays empty) and returnsformat!("ARRAY[{}]", "")=ARRAY[]. The non-empty path matches the builtin exactly (ARRAY[...]); only the empty case diverges.This is reached both from the
Value::Arrayarm inbind_pg_value(src/binding.rs:106) and the inline array-literal parse inbind_pg_string(:287).Reproduction
Inserting
{"ids": []}:INSERT INTO "s"."t" (ids) VALUES ({})→ succeeds.INSERT INTO "s"."t" (ids) VALUES (ARRAY[])→syntax error at or near "]"/cannot determine type of empty arraydepending on context.Impact
Fix
Add the empty-array guard at the top of
json_array_to_pg_literal(src/binding.rs:333):Add a unit test in
binding_tests.rs: aValue::Array(vec![])binds to{}, notARRAY[].Related
TabularisDB/tabularisdrivers/postgres/helpers.rs::json_array_to_pg_literal.