Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 1261 pg custom query without creating view #1353

Merged
Merged
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions third_party/ibis/ibis_postgres/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,23 @@ def connect(dbapi_connection, connection_record):


def _metadata(self, query: str) -> sch.Schema:
sundar-mudupalli-work marked this conversation as resolved.
Show resolved Hide resolved
raw_name = util.guid()
name = self._quote(raw_name)
type_info_sql = """\
SELECT
attname,
format_type(atttypid, atttypmod) AS type
FROM pg_attribute
WHERE attrelid = CAST(:raw_name AS regclass)
AND attnum > 0
AND NOT attisdropped
ORDER BY attnum"""
with self.begin() as con:
con.exec_driver_sql(f"CREATE TEMPORARY VIEW {name} AS {query}")
type_info = con.execute(sa.text(type_info_sql).bindparams(raw_name=raw_name))
yield from ((col, _get_type(typestr)) for col, typestr in type_info)
con.exec_driver_sql(f"DROP VIEW IF EXISTS {name}")
cur = con.exec_driver_sql(f"select * from ({query}) t0 limit 0")
sundar-mudupalli-work marked this conversation as resolved.
Show resolved Hide resolved
qry_cols = [
f"('{column.name}'::text, {column.type_code},"
+ f"{column.table_oid if column.table_oid else 'NULL'}::int,"
+ f"{column.table_column if column.table_column else 'NULL'}::int, {idx})"
for idx, column in enumerate(cur.cursor.description)
]
type_info = con.exec_driver_sql(
f"""select name, CASE WHEN t0.attrelid is NULL
sundar-mudupalli-work marked this conversation as resolved.
Show resolved Hide resolved
THEN format_type(t0.type_code, NULL)
ELSE format_type(t1.atttypid, t1.atttypmod) END as type
from unnest(array[{','.join(qry_cols)}])
as t0(name text, type_code int, attrelid int, attnum int, col_ord int)
left join pg_attribute t1 using (attrelid, attnum) order by col_ord"""
sundar-mudupalli-work marked this conversation as resolved.
Show resolved Hide resolved
)
yield from ((col, _get_type(typestr)) for col, typestr in type_info)


def _get_type(typestr: str) -> dt.DataType:
Expand Down