Skip to content

Commit 1936437

Browse files
authored
fix(mssql): ensure that dot-sql can be executed when column names are not provided (#10028)
Closes #10025.
1 parent 9ca92f0 commit 1936437

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

ibis/backends/mssql/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ def _get_schema_using_query(self, query: str) -> sch.Schema:
307307
elif newtyp.is_timestamp():
308308
newtyp = newtyp.copy(scale=scale)
309309

310+
if name is None:
311+
name = util.gen_name("col")
312+
310313
schema[name] = newtyp
311314

312315
return sch.Schema(schema)

ibis/backends/mssql/tests/test_client.py

+24
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,27 @@ def test_from_url():
241241
)
242242
result = new_con.sql("SELECT 1 AS [a]").to_pandas().a.iat[0]
243243
assert result == 1
244+
245+
246+
def test_dot_sql_with_unnamed_columns(con):
247+
expr = con.sql(
248+
"SELECT CAST('2024-01-01 00:00:00' AS DATETIMEOFFSET), 'a' + 'b', 1 AS [col42]"
249+
)
250+
251+
schema = expr.schema()
252+
names = schema.names
253+
254+
assert len(names) == 3
255+
256+
assert names[0].startswith("ibis_col")
257+
assert names[1].startswith("ibis_col")
258+
assert names[2] == "col42"
259+
260+
assert schema.types == (
261+
dt.Timestamp(timezone="UTC", scale=7),
262+
dt.String(nullable=False),
263+
dt.Int32(nullable=False),
264+
)
265+
266+
df = expr.execute()
267+
assert len(df) == 1

ibis/backends/tests/test_dot_sql.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
from ibis import _
1414
from ibis.backends import _get_backend_names
1515
from ibis.backends.tests.base import PYTHON_SHORT_VERSION
16-
from ibis.backends.tests.errors import GoogleBadRequest, OracleDatabaseError
16+
from ibis.backends.tests.errors import (
17+
ExaQueryError,
18+
GoogleBadRequest,
19+
OracleDatabaseError,
20+
)
1721

1822
pd = pytest.importorskip("pandas")
1923
tm = pytest.importorskip("pandas.testing")
@@ -330,3 +334,26 @@ def test_embedded_cte(alltypes, ftname_raw):
330334
expr = alltypes.sql(sql, dialect="duckdb")
331335
result = expr.head(1).execute()
332336
assert len(result) == 1
337+
338+
339+
@dot_sql_never
340+
@pytest.mark.never(["exasol"], raises=ExaQueryError, reason="backend requires aliasing")
341+
@pytest.mark.never(
342+
["oracle"], raises=OracleDatabaseError, reason="backend requires aliasing"
343+
)
344+
def test_unnamed_columns(con):
345+
sql = "SELECT 'a', 1 AS col42"
346+
sgexpr = sg.parse_one(sql, read="duckdb")
347+
expr = con.sql(sgexpr.sql(con.dialect))
348+
349+
schema = expr.schema()
350+
names = schema.names
351+
types = schema.types
352+
353+
assert len(names) == 2
354+
355+
assert names[0]
356+
assert names[1] == "col42"
357+
358+
assert types[0].is_string()
359+
assert types[1].is_integer()

0 commit comments

Comments
 (0)