From 8436f573b5819001595a5a8fe6803fbfaf282b2f Mon Sep 17 00:00:00 2001 From: Phillip Cloud <417981+cpcloud@users.noreply.github.com> Date: Fri, 14 Jul 2023 08:24:50 -0400 Subject: [PATCH] fix(duckdb): avoid double escaping backslashes for bind parameters --- ibis/backends/duckdb/__init__.py | 7 ++++--- ibis/backends/duckdb/tests/test_register.py | 8 ++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ibis/backends/duckdb/__init__.py b/ibis/backends/duckdb/__init__.py index 6355b77accd1..ff0b830794a5 100644 --- a/ibis/backends/duckdb/__init__.py +++ b/ibis/backends/duckdb/__init__.py @@ -53,9 +53,10 @@ def _format_kwargs(kwargs: Mapping[str, Any]): bindparams, pieces = [], [] for name, value in kwargs.items(): bindparam = sa.bindparam(name, value) - if not isinstance( - bindparam.type, sa.sql.sqltypes.NullType - ): # the parameter type is not null + if isinstance(paramtype := bindparam.type, sa.String): + # special case strings to avoid double escaping backslashes + pieces.append(f"{name} = '{value!s}'") + elif not isinstance(paramtype, sa.types.NullType): bindparams.append(bindparam) pieces.append(f"{name} = :{name}") else: # fallback to string strategy diff --git a/ibis/backends/duckdb/tests/test_register.py b/ibis/backends/duckdb/tests/test_register.py index effc0400893e..6989a6f0f6de 100644 --- a/ibis/backends/duckdb/tests/test_register.py +++ b/ibis/backends/duckdb/tests/test_register.py @@ -333,3 +333,11 @@ def test_register_recordbatchreader_warns(con): t = con.read_in_memory(reader, table_name=t.get_name()) res = t.execute() tm.assert_frame_equal(res, sol) + + +def test_csv_with_slash_n_null(con, tmp_path): + data_path = tmp_path / "data.csv" + data_path.write_text("a\n1\n3\n\\N\n") + t = con.read_csv(data_path, nullstr="\\N") + col = t.a.execute() + assert pd.isna(col.iat[-1])