Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:20 as build
FROM node:20 AS build
WORKDIR /usr/src/app
# Do `npm ci` separately so we can cache `node_modules`
# https://nodejs.org/en/docs/guides/nodejs-docker-webapp/
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"gen:types:go": "PG_META_GENERATE_TYPES=go node --loader ts-node/esm src/server/server.ts",
"gen:types:swift": "PG_META_GENERATE_TYPES=swift node --loader ts-node/esm src/server/server.ts",
"start": "node dist/server/server.js",
"dev": "trap 'npm run db:clean' INT && run-s db:clean db:run && nodemon --exec node --loader ts-node/esm src/server/server.ts | pino-pretty --colorize",
"dev": "trap 'npm run db:clean' INT && run-s db:clean db:run && run-s dev:code",
"dev:code": "nodemon --exec node --loader ts-node/esm src/server/server.ts | pino-pretty --colorize",
"test": "run-s db:clean db:run test:run db:clean",
"db:clean": "cd test/db && docker compose down",
"db:run": "cd test/db && docker compose up --detach --wait",
Expand Down
2 changes: 1 addition & 1 deletion src/lib/PostgresMetaTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default class PostgresMetaTypes {
t.typrelid = 0
or (
select
c.relkind ${includeTableTypes ? `in ('c', 'r')` : `= 'c'`}
c.relkind ${includeTableTypes ? `in ('c', 'r', 'v')` : `= 'c'`}
Copy link
Member Author

Choose a reason for hiding this comment

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

comment

Include functions that loops to a view for embedded functions.

from
pg_class c
where
Expand Down
75 changes: 55 additions & 20 deletions src/lib/sql/functions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,25 @@ select
pg_get_function_result(f.oid) as return_type,
nullif(rt.typrelid::int8, 0) as return_type_relation_id,
f.proretset as is_set_returning_function,
case
when f.proretset and rt.typrelid != 0 and exists (
select 1 from pg_class c
where c.oid = rt.typrelid
-- exclude custom types relation from what is considered a set of table
and c.relkind in ('r', 'p', 'v', 'm', 'f')
Copy link
Member Author

Choose a reason for hiding this comment

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

comment

All possible function embeding relations:

r | ordinary table
p | partitioned table
v | view
m | materialized view
f | foreign table

) then true
else false
end as returns_set_of_table,
case
when rt.typrelid != 0 then
(select relname from pg_class where oid = rt.typrelid)
else null
end as return_table_name,
case
when f.proretset then
coalesce(f.prorows, 0) > 1
else false
end as returns_multiple_rows,
case
when f.provolatile = 'i' then 'IMMUTABLE'
when f.provolatile = 's' then 'STABLE'
Expand Down Expand Up @@ -76,32 +95,48 @@ from
select
oid,
jsonb_agg(jsonb_build_object(
'mode', t2.mode,
'mode', mode,
'name', name,
'type_id', type_id,
'has_default', has_default
'has_default', has_default,
'table_name', table_name
)) as args
from
(
select
oid,
unnest(arg_modes) as mode,
unnest(arg_names) as name,
unnest(arg_types)::int8 as type_id,
unnest(arg_has_defaults) as has_default
from
functions
) as t1,
lateral (
select
t1.oid,
t2.mode,
t1.name,
t1.type_id,
t1.has_default,
case
when t1.mode = 'i' then 'in'
when t1.mode = 'o' then 'out'
when t1.mode = 'b' then 'inout'
when t1.mode = 'v' then 'variadic'
else 'table'
end as mode
) as t2
when pt.typrelid != 0 then pc.relname
else null
end as table_name
from
(
select
oid,
unnest(arg_modes) as mode,
unnest(arg_names) as name,
unnest(arg_types)::int8 as type_id,
unnest(arg_has_defaults) as has_default
from
functions
) as t1
cross join lateral (
select
case
when t1.mode = 'i' then 'in'
when t1.mode = 'o' then 'out'
when t1.mode = 'b' then 'inout'
when t1.mode = 'v' then 'variadic'
else 'table'
end as mode
) as t2
left join pg_type pt on pt.oid = t1.type_id
left join pg_class pc on pc.oid = pt.typrelid
) sub
group by
t1.oid
oid
) f_args on f_args.oid = f.oid
4 changes: 4 additions & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ const postgresFunctionSchema = Type.Object({
name: Type.String(),
type_id: Type.Number(),
has_default: Type.Boolean(),
table_name: Type.Union([Type.String(), Type.Null()]),
})
),
argument_types: Type.String(),
Expand All @@ -156,6 +157,9 @@ const postgresFunctionSchema = Type.Object({
return_type: Type.String(),
return_type_relation_id: Type.Union([Type.Integer(), Type.Null()]),
is_set_returning_function: Type.Boolean(),
returns_set_of_table: Type.Boolean(),
return_table_name: Type.Union([Type.String(), Type.Null()]),
returns_multiple_rows: Type.Boolean(),
behavior: Type.Union([
Type.Literal('IMMUTABLE'),
Type.Literal('STABLE'),
Expand Down
4 changes: 4 additions & 0 deletions src/server/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ export const GENERATE_TYPES_SWIFT_ACCESS_CONTROL = process.env
? (process.env.PG_META_GENERATE_TYPES_SWIFT_ACCESS_CONTROL as AccessControl)
: 'internal'

// json/jsonb/text types
export const VALID_UNNAMED_FUNCTION_ARG_TYPES = new Set([114, 3802, 25])
export const VALID_FUNCTION_ARGS_MODE = new Set(['in', 'inout', 'variadic'])

export const PG_META_MAX_RESULT_SIZE = process.env.PG_META_MAX_RESULT_SIZE_MB
? // Node-postgres get a maximum size in bytes make the conversion from the env variable
// from MB to Bytes
Expand Down
Loading