Skip to content

Commit

Permalink
feat(trino): implement support for .sql table expression method
Browse files Browse the repository at this point in the history
  • Loading branch information
cpcloud committed Jul 19, 2023
1 parent b3778c7 commit 479bc60
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 8 deletions.
7 changes: 5 additions & 2 deletions ibis/backends/base/sql/alchemy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -797,12 +797,15 @@ def _create_temp_view(self, view: sa.Table, definition: sa.sql.Selectable) -> No
if raw_name not in self._temp_views and raw_name in self.list_tables():
raise ValueError(f"{raw_name} already exists as a table or view")
name = self._quote(raw_name)
self._execute_view_creation(name, definition)
self._temp_views.add(raw_name)
self._register_temp_view_cleanup(name, raw_name)

def _execute_view_creation(self, name, definition):
lines, params = self._get_compiled_statement(definition, name)
with self.begin() as con:
for line in lines:
con.exec_driver_sql(line, parameters=params or ())
self._temp_views.add(raw_name)
self._register_temp_view_cleanup(name, raw_name)

@abc.abstractmethod
def _metadata(self, query: str) -> Iterable[tuple[str, dt.DataType]]:
Expand Down
8 changes: 2 additions & 6 deletions ibis/backends/tests/test_dot_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ def test_con_dot_sql(backend, con, schema):
@dot_sql_notimpl
@dot_sql_notyet
@dot_sql_never
@pytest.mark.notimpl(["trino"])
@pytest.mark.notyet(["polars"], raises=PolarsComputeError)
def test_table_dot_sql(backend, con):
alltypes = con.table("functional_alltypes")
Expand Down Expand Up @@ -132,7 +131,6 @@ def test_table_dot_sql(backend, con):
@dot_sql_notimpl
@dot_sql_notyet
@dot_sql_never
@pytest.mark.notimpl(["trino"])
@pytest.mark.notyet(["polars"], raises=PolarsComputeError)
def test_table_dot_sql_with_join(backend, con):
alltypes = con.table("functional_alltypes")
Expand Down Expand Up @@ -181,7 +179,6 @@ def test_table_dot_sql_with_join(backend, con):
@dot_sql_notimpl
@dot_sql_notyet
@dot_sql_never
@pytest.mark.notimpl(["trino"])
@pytest.mark.notyet(["polars"], raises=PolarsComputeError)
def test_table_dot_sql_repr(con):
alltypes = con.table("functional_alltypes")
Expand Down Expand Up @@ -218,7 +215,7 @@ def test_table_dot_sql_does_not_clobber_existing_tables(con, temp_table):
@table_dot_sql_notimpl
@dot_sql_notimpl
@dot_sql_never
@pytest.mark.notimpl(["trino", "oracle"])
@pytest.mark.notimpl(["oracle"])
def test_dot_sql_alias_with_params(backend, alltypes, df):
t = alltypes
x = t.select(x=t.string_col + " abc").alias("foo")
Expand All @@ -230,7 +227,7 @@ def test_dot_sql_alias_with_params(backend, alltypes, df):
@table_dot_sql_notimpl
@dot_sql_notimpl
@dot_sql_never
@pytest.mark.notimpl(["trino", "oracle"])
@pytest.mark.notimpl(["oracle"])
def test_dot_sql_reuse_alias_with_different_types(backend, alltypes, df):
foo1 = alltypes.select(x=alltypes.string_col).alias("foo")
foo2 = alltypes.select(x=alltypes.bigint_col).alias("foo")
Expand All @@ -254,7 +251,6 @@ def test_dot_sql_reuse_alias_with_different_types(backend, alltypes, df):
],
)
@pytest.mark.broken(["clickhouse"], raises=DatabaseError)
@pytest.mark.notyet(["trino"], raises=NotImplementedError)
@pytest.mark.notyet(["polars"], raises=PolarsComputeError)
@table_dot_sql_notimpl
@dot_sql_notimpl
Expand Down
14 changes: 14 additions & 0 deletions ibis/backends/trino/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,17 @@ def _metadata(self, query: str) -> Iterator[tuple[str, dt.DataType]]:
(name, parse(trino_type).copy(nullable=True))
for name, trino_type in toolz.pluck(["Column Name", "Type"], mappings)
)

def _execute_view_creation(self, name, definition):
from sqlalchemy_views import CreateView

# NB: trino doesn't support temporary views so we use the less
# desirable method of cleaning up when the Python process exits using
# an atexit hook
#
# the method that defines the atexit hook is defined in the parent
# class
view = CreateView(sa.table(name), definition, or_replace=True)

with self.begin() as con:
con.execute(view)

0 comments on commit 479bc60

Please sign in to comment.