Skip to content

Commit bfcca99

Browse files
committed
Fix
1 parent e7587bf commit bfcca99

File tree

4 files changed

+36
-18
lines changed

4 files changed

+36
-18
lines changed

datafusion-postgres/src/encoder/struct_encoder.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ use std::{error::Error, sync::Arc};
22

33
use bytes::{BufMut, BytesMut};
44
use datafusion::arrow::array::{Array, StructArray};
5-
use pgwire::{api::results::FieldFormat, error::PgWireResult, types::ToSqlText};
5+
use pgwire::{
6+
api::results::FieldFormat,
7+
error::PgWireResult,
8+
types::{ToSqlText, QUOTE_CHECK, QUOTE_ESCAPE},
9+
};
610
use postgres_types::{Field, IsNull, ToSql, Type};
711

812
use super::{encode_value, EncodedValue};
@@ -58,7 +62,21 @@ impl super::Encoder for StructEncoder {
5862
if self.curr_col == 0 {
5963
self.row_buffer.put_slice(b"(");
6064
}
61-
value.to_sql_text(data_type, &mut self.row_buffer)?;
65+
// encode value in an intermediate buf
66+
let mut buf = BytesMut::new();
67+
value.to_sql_text(data_type, &mut buf)?;
68+
let encoded_value_as_str = String::from_utf8_lossy(&buf);
69+
if QUOTE_CHECK.is_match(&encoded_value_as_str) {
70+
self.row_buffer.put_u8(b'"');
71+
self.row_buffer.put_slice(
72+
QUOTE_ESCAPE
73+
.replace_all(&encoded_value_as_str, r#"\$1"#)
74+
.as_bytes(),
75+
);
76+
self.row_buffer.put_u8(b'"');
77+
} else {
78+
self.row_buffer.put_slice(&buf);
79+
}
6280
if self.curr_col == self.num_cols - 1 {
6381
self.row_buffer.put_slice(b")");
6482
} else {
485 Bytes
Binary file not shown.

tests-integration/create_arrow_testfile.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
pa.field("nested_str", pa.string()),
1919
pa.field("nested_date32", pa.date32()),
2020
pa.field("nested_timestamp", pa.timestamp("ms")),
21+
pa.field("nested_array", pa.list_(pa.int64())),
2122
]
2223
)
2324
)
@@ -81,6 +82,7 @@
8182
"nested_str": "x",
8283
"nested_date32": date(2012, 1, 1),
8384
"nested_timestamp": datetime(2012, 1, 1),
85+
"nested_array": [1, 2],
8486
}
8587
],
8688
[
@@ -89,6 +91,7 @@
8991
"nested_str": "y",
9092
"nested_date32": date(2012, 1, 2),
9193
"nested_timestamp": datetime(2012, 1, 2),
94+
"nested_array": [3, 4],
9295
}
9396
],
9497
[
@@ -97,6 +100,7 @@
97100
"nested_str": "z",
98101
"nested_date32": date(2012, 1, 3),
99102
"nested_timestamp": datetime(2012, 1, 3),
103+
"nested_array": [5, 6],
100104
}
101105
],
102106
],

tests-integration/test_all_types.py

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ def assert_select_all(results: list[psycopg.rows.Row], format: str):
2323
else ("10", "x", "2012-01-01", "2012-01-01 00:00:00.000000")
2424
),
2525
(
26-
[(10, "x", date(2012, 1, 1), datetime(2012, 1, 1))]
26+
[(10, "x", date(2012, 1, 1), datetime(2012, 1, 1), [1, 2])]
2727
if format == "binary"
28-
else [("10", "x", "2012-01-01", "2012-01-01 00:00:00.000000")]
28+
else [("10", "x", "2012-01-01", "2012-01-01 00:00:00.000000", "{1,2}")]
2929
),
3030
),
3131
(
@@ -41,13 +41,11 @@ def assert_select_all(results: list[psycopg.rows.Row], format: str):
4141
if format == "binary"
4242
else ("20", "y", "2012-01-02", "2012-01-02 00:00:00.000000")
4343
),
44-
[
45-
(
46-
(20, "y", date(2012, 1, 2), datetime(2012, 1, 2, 0, 0))
47-
if format == "binary"
48-
else ("20", "y", "2012-01-02", "2012-01-02 00:00:00.000000")
49-
),
50-
],
44+
(
45+
[(20, "y", date(2012, 1, 2), datetime(2012, 1, 2, 0, 0), [3, 4])]
46+
if format == "binary"
47+
else [("20", "y", "2012-01-02", "2012-01-02 00:00:00.000000", "{3,4}")]
48+
),
5149
),
5250
(
5351
3,
@@ -62,13 +60,11 @@ def assert_select_all(results: list[psycopg.rows.Row], format: str):
6260
if format == "binary"
6361
else ("30", "z", "2012-01-03", "2012-01-03 00:00:00.000000")
6462
),
65-
[
66-
(
67-
(30, "z", date(2012, 1, 3), datetime(2012, 1, 3, 0, 0))
68-
if format == "binary"
69-
else ("30", "z", "2012-01-03", "2012-01-03 00:00:00.000000")
70-
),
71-
],
63+
(
64+
[(30, "z", date(2012, 1, 3), datetime(2012, 1, 3, 0, 0), [5, 6])]
65+
if format == "binary"
66+
else [("30", "z", "2012-01-03", "2012-01-03 00:00:00.000000", "{5,6}")]
67+
),
7268
),
7369
]
7470

0 commit comments

Comments
 (0)