Skip to content

fix(introspection): expose columns of Postgres functions returning table rows - #693

Open
officialasishkumar wants to merge 1 commit into
dosco:masterfrom
officialasishkumar:fix/postgres-functions-returning-table-rows
Open

officialasishkumar wants to merge 1 commit into
dosco:masterfrom
officialasishkumar:fix/postgres-functions-returning-table-rows

Conversation

@officialasishkumar

Copy link
Copy Markdown

Fixes #424.

Postgres functions that return rows of a table could not be queried. RETURNS TABLE (LIKE users) was discovered as one output column named like, so selecting a real column failed with field 'id' is not a column or a function; available columns: like. RETURNS SETOF users and RETURNS users were discovered with no output columns and were not exposed at all.

The cause is in function discovery: row columns came from information_schema.attributes, which only lists standalone composite types (CREATE TYPE ... AS (...)), never the row type of a table or view.

Changes

  • postgres_functions.sql reads row columns from pg_attribute through the return type's typrelid. It covers tables, views, materialized views, foreign and partitioned tables and composite types, skips dropped columns, and uses format_type for column types, as table discovery does. The single OUT parameter that holds the whole row (the like column above) is not reported, because Postgres expands it into the row's columns. Enum and domain RETURNS TABLE outputs behave as before.
  • Function output columns now carry the array flag (so filters like contains work on text[] columns) and honour the configured blocklist. A function returning users no longer bypasses a blocklist entry such as password.
  • Array-typed function parameters are written to the schema DDL with the same [Type] syntax as table columns, and the DDL parser reads them back. The old Text[] output was not valid DDL. It never showed up before because Postgres reported array parameters as ARRAY. With real types it broke reloading db.ddl under enable_schema (TestEnableSchema).

Function names in the blocklist still decide whether a function is exposed. The function's return type does not, which matches how RETURNS TABLE (...) functions already work.

Tests

  • tests/postgres.sql adds get_users_up_to (RETURNS TABLE (LIKE users)), get_products_up_to (RETURNS SETOF products) and get_user_row (RETURNS users).
  • New examples in tests/query_pg_test.go cover each form, including an array contains filter and a blocklisted column. They fail on master and pass with this change.
  • New unit tests: TestNewDBInfoFunctionOutputColumns (blocklist and array flag) and TestCreateSchemaFunctionArrayParams (DDL round trip).
  • I ran the full tests suite with -db=postgres on Postgres 15, before and after the change. The only new results are the four new examples passing. The geo tests fail in both runs because my local database had no PostGIS. I also ran the function examples and TestEnableSchema on Postgres 12, plus the core, sdata, qcode, introspection and psql packages.
  • On the test database the new discovery query takes about 20 ms, compared with 40 ms for the old one.

…ble rows

Postgres functions that return rows of a table were not queryable through
GraphJin. `RETURNS TABLE (LIKE users)` was discovered as a single output
column named "like", so selecting any real column failed with
"field 'id' is not a column or a function; available columns: like".
`RETURNS SETOF users` and `RETURNS users` were discovered with no output
columns at all and were not exposed.

Function discovery read row columns from information_schema.attributes,
which only lists standalone composite types, never the row types of
tables, views or materialized views. Read them from pg_attribute through
the return type's typrelid instead. This covers tables, views,
materialized views, foreign and partitioned tables and composite types,
skips dropped columns, and reports column types with format_type like
table discovery does. The single OUT parameter that holds the whole row
is no longer reported as a column, because Postgres expands it into the
row's columns. Enum and domain outputs keep their existing behaviour.

Function output columns now also carry the array flag and honour the
configured blocklist, so table columns such as passwords stay blocked
when a function returns the same row. Function parameters with array
types now use the same `[Type]` list syntax as table columns in the
generated schema DDL, and the DDL parser reads it back; `Text[]` was not
valid DDL and broke loading db.ddl with enable_schema.

Fixes dosco#424

This branch has not been deployed

No deployments
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.

Support returns table (like <tablename>) in stored procedure record returns.

1 participant