Skip to content

Scan relation row types as STRUCT (not VARCHAR)#475

Merged
staticlibs merged 1 commit into
duckdb:mainfrom
dialohq:main
May 25, 2026
Merged

Scan relation row types as STRUCT (not VARCHAR)#475
staticlibs merged 1 commit into
duckdb:mainfrom
dialohq:main

Conversation

@wokalski
Copy link
Copy Markdown
Contributor

@wokalski wokalski commented May 25, 2026

Fixes #474

This PR allows to use composite types from views/materialized views etc. Until now it was only possible for tables.

In postgres:

CREATE SCHEMA row_types;
CREATE TABLE row_types.widget(id INT, label VARCHAR);
CREATE VIEW row_types.widget_row AS SELECT w FROM row_types.widget AS w

In duckdb:

SELECT w.id, w.label FROM row_types.widget_row
----
1	hello

Every PG relation (table/view/matview/foreign/partitioned) has an implicit
row type with typtype='c'. The existing composite-type discovery query
filtered them out with pg_class.relkind='c', so a column whose declared
type was a relation row type (e.g. a view that aliases a table as a row
variable) fell back to VARCHAR even though the binary and text readers
already handle STRUCT recursively.

Widen the relkind filter to IN ('c','r','v','m','f','p') and add the
required attnum > 0 / NOT attisdropped filters so we skip system and
dropped columns on physical relations.
Copy link
Copy Markdown
Member

@staticlibs staticlibs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! It looks good to me.

@staticlibs staticlibs merged commit 8f299af into duckdb:main May 25, 2026
7 checks passed
adamchol pushed a commit to dialohq/duckdb-postgres that referenced this pull request May 26, 2026
Follow-up to duckdb#474 / duckdb#475. After PR duckdb#475, row types of relations are
discovered and registered under their own schema, so the in-schema
case works. But when a relation in schema B has a column whose type
is the row type of a relation in schema A, PostgresUtils::TypeToLogicalType
still looked up the type entry against the relation's schema (B). It
finds nothing there and falls back to VARCHAR.

Plumb the type's own namespace through PostgresTypeData. The two
discovery queries now join pg_namespace on pg_type.typnamespace and
expose nspname as the type's schema, and TypeToLogicalType uses
Catalog::GetSchema to resolve the lookup against that schema when it
differs from the relation's own.

Extend test/sql/storage/attach_types_table_row.test with a cross-
schema view and table; the existing test put both ends in the same
schema, which is why this slipped through.
adamchol added a commit to dialohq/duckdb-postgres that referenced this pull request May 26, 2026
Follow-up to duckdb#474 / duckdb#475. After PR duckdb#475, row types of relations are
discovered and registered under their own schema, so the in-schema
case works. But when a relation in schema B has a column whose type
is the row type of a relation in schema A, PostgresUtils::TypeToLogicalType
still looked up the type entry against the relation's schema (B). It
finds nothing there and falls back to VARCHAR.

Plumb the type's own namespace through PostgresTypeData. The two
discovery queries now join pg_namespace on pg_type.typnamespace and
expose nspname as the type's schema, and TypeToLogicalType uses
Catalog::GetSchema to resolve the lookup against that schema when it
differs from the relation's own.

Extend test/sql/storage/attach_types_table_row.test with a cross-
schema view and table; the existing test put both ends in the same
schema, which is why this slipped through.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

VIEW with table-type columns returns VARCHARs in DuckDB

2 participants