Skip to content

Commit b35eaf9

Browse files
committed
Fix concatenating Arrow result chunks with duplicate column names
Signed-off-by: adityaanikam <adityanikam9502@gmail.com>
1 parent 285a74c commit b35eaf9

3 files changed

Lines changed: 44 additions & 1 deletion

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Release History
22

33
# Unreleased
4+
- Fix fetching results that contain duplicate column names, which failed with `ArrowInvalid: Can't unify schema with duplicate field names` since 4.2.6.
45

56
# 4.7.0 (2026-10-20)
67
- Upgrade Databricks SQL Kernel to 1.2.0.

‎src/databricks/sql/utils.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,11 @@ def _concat_arrow_tables(table_chunks: List["pyarrow.Table"]) -> "pyarrow.Table"
927927
raises ``TypeError: unexpected keyword argument``. Fall back to the legacy
928928
``promote=True`` there (equivalent to ``promote_options="default"``).
929929
"""
930+
first_schema = table_chunks[0].schema
931+
if all(chunk.schema.equals(first_schema) for chunk in table_chunks[1:]):
932+
# Nothing to promote. Schema unification rejects duplicate column names
933+
# (e.g. SELECT 1 AS a, 2 AS a), so skip it when the chunks already agree.
934+
return pyarrow.concat_tables(table_chunks)
930935
try:
931936
return pyarrow.concat_tables(table_chunks, promote_options="default")
932937
except TypeError:

‎tests/unit/test_util.py‎

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,51 @@ def test_concat_table_chunks_arrow_table(self):
152152
assert result_table.column("col1").to_pylist() == [1, 2, 3, 4]
153153
assert result_table.column("col2").to_pylist() == [5, 6, 7, 8]
154154

155+
@pytest.mark.skipif(pyarrow is None, reason="PyArrow is not installed")
156+
def test_concat_table_chunks_arrow_table_duplicate_column_names(self):
157+
arrow_table1 = pyarrow.Table.from_arrays(
158+
[pyarrow.array([1]), pyarrow.array([2])], names=["a", "a"]
159+
)
160+
arrow_table2 = pyarrow.Table.from_arrays(
161+
[pyarrow.array([3]), pyarrow.array([4])], names=["a", "a"]
162+
)
163+
164+
result_table = concat_table_chunks([arrow_table1, arrow_table2])
165+
166+
assert result_table.column_names == ["a", "a"]
167+
assert result_table.column(0).to_pylist() == [1, 3]
168+
assert result_table.column(1).to_pylist() == [2, 4]
169+
170+
@pytest.mark.skipif(pyarrow is None, reason="PyArrow is not installed")
171+
def test_concat_table_chunks_arrow_table_promotes_nullability(self):
172+
nullable = pyarrow.Table.from_arrays(
173+
[pyarrow.array(["x"])],
174+
schema=pyarrow.schema([pyarrow.field("col1", pyarrow.string())]),
175+
)
176+
not_null = pyarrow.Table.from_arrays(
177+
[pyarrow.array(["y"])],
178+
schema=pyarrow.schema(
179+
[pyarrow.field("col1", pyarrow.string(), nullable=False)]
180+
),
181+
)
182+
183+
result_table = concat_table_chunks([nullable, not_null])
184+
185+
assert result_table.column("col1").to_pylist() == ["x", "y"]
186+
155187
@pytest.mark.skipif(pyarrow is None, reason="PyArrow is not installed")
156188
def test_concat_table_chunks_arrow_old_pyarrow_fallback(self, monkeypatch):
157189
# pyarrow < 14 has no `promote_options` kwarg; a base connector install
158190
# can run against a runtime's old bundled pyarrow (e.g. DBR 13.3/14.3).
159191
# concat_table_chunks must fall back to the legacy `promote=True` API
160192
# rather than raise TypeError (regression: DBR LTS install check).
161193
arrow_table1 = pyarrow.Table.from_pydict({"col1": [1, 2]})
162-
arrow_table2 = pyarrow.Table.from_pydict({"col1": [3, 4]})
194+
arrow_table2 = pyarrow.Table.from_arrays(
195+
[pyarrow.array([3, 4])],
196+
schema=pyarrow.schema(
197+
[pyarrow.field("col1", pyarrow.int64(), nullable=False)]
198+
),
199+
)
163200

164201
real_concat = pyarrow.concat_tables
165202

0 commit comments

Comments
 (0)