Skip to content

Commit

Permalink
fix(mssql): ensure that dot-sql can be executed when column names are…
Browse files Browse the repository at this point in the history
… not provided (ibis-project#10028)

Closes ibis-project#10025.
  • Loading branch information
cpcloud authored Sep 5, 2024
1 parent 9ca92f0 commit 1936437
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
3 changes: 3 additions & 0 deletions ibis/backends/mssql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ def _get_schema_using_query(self, query: str) -> sch.Schema:
elif newtyp.is_timestamp():
newtyp = newtyp.copy(scale=scale)

if name is None:
name = util.gen_name("col")

schema[name] = newtyp

return sch.Schema(schema)
Expand Down
24 changes: 24 additions & 0 deletions ibis/backends/mssql/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,27 @@ def test_from_url():
)
result = new_con.sql("SELECT 1 AS [a]").to_pandas().a.iat[0]
assert result == 1


def test_dot_sql_with_unnamed_columns(con):
expr = con.sql(
"SELECT CAST('2024-01-01 00:00:00' AS DATETIMEOFFSET), 'a' + 'b', 1 AS [col42]"
)

schema = expr.schema()
names = schema.names

assert len(names) == 3

assert names[0].startswith("ibis_col")
assert names[1].startswith("ibis_col")
assert names[2] == "col42"

assert schema.types == (
dt.Timestamp(timezone="UTC", scale=7),
dt.String(nullable=False),
dt.Int32(nullable=False),
)

df = expr.execute()
assert len(df) == 1
29 changes: 28 additions & 1 deletion ibis/backends/tests/test_dot_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
from ibis import _
from ibis.backends import _get_backend_names
from ibis.backends.tests.base import PYTHON_SHORT_VERSION
from ibis.backends.tests.errors import GoogleBadRequest, OracleDatabaseError
from ibis.backends.tests.errors import (
ExaQueryError,
GoogleBadRequest,
OracleDatabaseError,
)

pd = pytest.importorskip("pandas")
tm = pytest.importorskip("pandas.testing")
Expand Down Expand Up @@ -330,3 +334,26 @@ def test_embedded_cte(alltypes, ftname_raw):
expr = alltypes.sql(sql, dialect="duckdb")
result = expr.head(1).execute()
assert len(result) == 1


@dot_sql_never
@pytest.mark.never(["exasol"], raises=ExaQueryError, reason="backend requires aliasing")
@pytest.mark.never(
["oracle"], raises=OracleDatabaseError, reason="backend requires aliasing"
)
def test_unnamed_columns(con):
sql = "SELECT 'a', 1 AS col42"
sgexpr = sg.parse_one(sql, read="duckdb")
expr = con.sql(sgexpr.sql(con.dialect))

schema = expr.schema()
names = schema.names
types = schema.types

assert len(names) == 2

assert names[0]
assert names[1] == "col42"

assert types[0].is_string()
assert types[1].is_integer()

0 comments on commit 1936437

Please sign in to comment.