Skip to content

Commit

Permalink
fix(postgres): allow inference of unknown types
Browse files Browse the repository at this point in the history
  • Loading branch information
cpcloud authored and gforsyth committed Mar 23, 2023
1 parent ab0df7a commit 343fb37
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 9 deletions.
5 changes: 5 additions & 0 deletions ci/schema/postgresql.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
CREATE EXTENSION IF NOT EXISTS hstore;
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE EXTENSION IF NOT EXISTS plpython3u;
CREATE EXTENSION IF NOT EXISTS vector;

DROP TABLE IF EXISTS diamonds CASCADE;

Expand Down Expand Up @@ -214,3 +215,7 @@ ADD search tsvector
GENERATED always AS (
setweight(to_tsvector('simple', notes), 'A') :: tsvector
) stored;

ALTER TABLE awards_players
ADD simvec vector
GENERATED always AS ('[1,2,3]' :: vector) stored;
7 changes: 6 additions & 1 deletion docker/postgres/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
FROM postgis/postgis:15-3.3-alpine
RUN apk add postgresql15-plpython3
RUN apk add --no-cache build-base clang15 llvm15 postgresql15-plpython3 python3 py3-pip && \
python3 -m pip install pgxnclient && \
pgxn install vector && \
python3 -m pip uninstall -y pgxnclient && \
rm -rf ~/.cache/pip && \
apk del build-base clang15 llvm15 python3 py3-pip
2 changes: 2 additions & 0 deletions ibis/backends/postgres/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ def _metadata(self, query: str) -> Iterable[tuple[str, dt.DataType]]:
AND attnum > 0
AND NOT attisdropped
ORDER BY attnum"""
if self.inspector.has_table(query):
query = f"TABLE {query}"
with self.begin() as con:
con.exec_driver_sql(f"CREATE TEMPORARY VIEW {name} AS {query}")
type_info = con.execute(
Expand Down
9 changes: 8 additions & 1 deletion ibis/backends/postgres/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,14 @@ def _get_type(typestr: str) -> dt.DataType:
is_array = typestr.endswith(_BRACKETS)
if (typ := _type_mapping.get(typestr.replace(_BRACKETS, ""))) is not None:
return dt.Array(typ) if is_array else typ
return _parse_numeric(typestr)
try:
return _parse_numeric(typestr)
except parsy.ParseError:
# postgres can have arbitrary types unknown to ibis, so we just
# consider them null since we can't know what to do with them without
# explicit support, return null to effectively give no public API to
# such columns
return dt.null


_type_mapping = {
Expand Down
8 changes: 8 additions & 0 deletions ibis/backends/postgres/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,11 @@ def test_get_schema_from_query(con, pg_type, expected_type):
expected_schema = ibis.schema(dict(x=expected_type, y=dt.Array(expected_type)))
result_schema = con._get_schema_using_query(f"SELECT x, y FROM {name}")
assert result_schema == expected_schema


@pytest.mark.parametrize(
("col", "expected_type"), [("search", dt.string), ("simvec", dt.null)]
)
def test_unknown_column_type(con, col, expected_type):
awards_players = con.table("awards_players")
assert awards_players[col].type() == expected_type
7 changes: 0 additions & 7 deletions ibis/backends/postgres/tests/test_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from pytest import param

import ibis
import ibis.expr.datatypes as dt


@pytest.mark.parametrize(
Expand All @@ -17,9 +16,3 @@ def test_special_strings(alltypes, data, data_type):
expr = alltypes[[alltypes.id, lit]].head(1)
df = expr.execute()
assert df['tmp'].iloc[0] == uuid.UUID(data)


def test_load_tsvector_table(con):
awards_players = con.table("awards_players")
assert "search" in awards_players.columns
assert awards_players.schema()["search"] == dt.String(nullable=True)

0 comments on commit 343fb37

Please sign in to comment.