fix: detect the correct base type of recursive domains in schema cache for tables and views
In OpenAPI it shows the correct base type in properties' definitions (including enums).
This commit is contained in:
@@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix `max-affected` preference not failing with RPC when `handling=strict` by @taimoorzaeem in #4100
|
- Fix `max-affected` preference not failing with RPC when `handling=strict` by @taimoorzaeem in #4100
|
||||||
|
- Fix a property definition's type in OpenAPI not showing the correct base type of a recursive domain by @laurenceisla in #4136
|
||||||
|
|
||||||
## [13.0.2] - 2025-06-02
|
## [13.0.2] - 2025-06-02
|
||||||
|
|
||||||
|
|||||||
@@ -375,32 +375,40 @@ accessibleFuncs = SQL.Statement sql params decodeFuncs
|
|||||||
(snd >$< arrayParam HE.text)
|
(snd >$< arrayParam HE.text)
|
||||||
sql = funcsSqlQuery <> " AND has_function_privilege(p.oid, 'execute')"
|
sql = funcsSqlQuery <> " AND has_function_privilege(p.oid, 'execute')"
|
||||||
|
|
||||||
funcsSqlQuery :: SqlQuery
|
baseTypesCte :: Text
|
||||||
funcsSqlQuery = encodeUtf8 [trimming|
|
baseTypesCte = [trimming|
|
||||||
-- Recursively get the base types of domains
|
-- Recursively get the base types of domains
|
||||||
WITH
|
|
||||||
base_types AS (
|
base_types AS (
|
||||||
WITH RECURSIVE
|
WITH RECURSIVE
|
||||||
recurse AS (
|
recurse AS (
|
||||||
SELECT
|
SELECT
|
||||||
oid,
|
oid,
|
||||||
typbasetype,
|
typbasetype,
|
||||||
COALESCE(NULLIF(typbasetype, 0), oid) AS base
|
typnamespace AS base_namespace,
|
||||||
|
COALESCE(NULLIF(typbasetype, 0), oid) AS base_type
|
||||||
FROM pg_type
|
FROM pg_type
|
||||||
UNION
|
UNION
|
||||||
SELECT
|
SELECT
|
||||||
t.oid,
|
t.oid,
|
||||||
b.typbasetype,
|
b.typbasetype,
|
||||||
COALESCE(NULLIF(b.typbasetype, 0), b.oid) AS base
|
b.typnamespace AS base_namespace,
|
||||||
|
COALESCE(NULLIF(b.typbasetype, 0), b.oid) AS base_type
|
||||||
FROM recurse t
|
FROM recurse t
|
||||||
JOIN pg_type b ON t.typbasetype = b.oid
|
JOIN pg_type b ON t.typbasetype = b.oid
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
oid,
|
oid,
|
||||||
base
|
base_namespace,
|
||||||
|
base_type
|
||||||
FROM recurse
|
FROM recurse
|
||||||
WHERE typbasetype = 0
|
WHERE typbasetype = 0
|
||||||
),
|
)
|
||||||
|
|]
|
||||||
|
|
||||||
|
funcsSqlQuery :: SqlQuery
|
||||||
|
funcsSqlQuery = encodeUtf8 [trimming|
|
||||||
|
WITH
|
||||||
|
$baseTypesCte,
|
||||||
arguments AS (
|
arguments AS (
|
||||||
SELECT
|
SELECT
|
||||||
oid,
|
oid,
|
||||||
@@ -440,7 +448,7 @@ funcsSqlQuery = encodeUtf8 [trimming|
|
|||||||
-- if any TABLE, INOUT or OUT arguments present, treat as composite
|
-- if any TABLE, INOUT or OUT arguments present, treat as composite
|
||||||
or COALESCE(proargmodes::text[] && '{t,b,o}', false)
|
or COALESCE(proargmodes::text[] && '{t,b,o}', false)
|
||||||
) AS rettype_is_composite,
|
) AS rettype_is_composite,
|
||||||
bt.oid <> bt.base as rettype_is_composite_alias,
|
bt.oid <> bt.base_type as rettype_is_composite_alias,
|
||||||
p.provolatile,
|
p.provolatile,
|
||||||
p.provariadic > 0 as hasvariadic,
|
p.provariadic > 0 as hasvariadic,
|
||||||
lower((regexp_split_to_array((regexp_split_to_array(iso_config, '='))[2], ','))[1]) AS transaction_isolation_level,
|
lower((regexp_split_to_array((regexp_split_to_array(iso_config, '='))[2], ','))[1]) AS transaction_isolation_level,
|
||||||
@@ -449,7 +457,7 @@ funcsSqlQuery = encodeUtf8 [trimming|
|
|||||||
LEFT JOIN arguments a ON a.oid = p.oid
|
LEFT JOIN arguments a ON a.oid = p.oid
|
||||||
JOIN pg_namespace pn ON pn.oid = p.pronamespace
|
JOIN pg_namespace pn ON pn.oid = p.pronamespace
|
||||||
JOIN base_types bt ON bt.oid = p.prorettype
|
JOIN base_types bt ON bt.oid = p.prorettype
|
||||||
JOIN pg_type t ON t.oid = bt.base
|
JOIN pg_type t ON t.oid = bt.base_type
|
||||||
JOIN pg_namespace tn ON tn.oid = t.typnamespace
|
JOIN pg_namespace tn ON tn.oid = t.typnamespace
|
||||||
LEFT JOIN pg_class comp ON comp.oid = t.typrelid
|
LEFT JOIN pg_class comp ON comp.oid = t.typrelid
|
||||||
LEFT JOIN pg_description as d ON d.objoid = p.oid AND d.classoid = 'pg_proc'::regclass
|
LEFT JOIN pg_description as d ON d.objoid = p.oid AND d.classoid = 'pg_proc'::regclass
|
||||||
@@ -615,6 +623,7 @@ tablesSqlQuery =
|
|||||||
-- generated columns are only available from pg >= 10 but the query is agnostic to versions. dep.deptype = 'i' is done because there are other 'a' dependencies on PKs
|
-- generated columns are only available from pg >= 10 but the query is agnostic to versions. dep.deptype = 'i' is done because there are other 'a' dependencies on PKs
|
||||||
encodeUtf8 [trimming|
|
encodeUtf8 [trimming|
|
||||||
WITH
|
WITH
|
||||||
|
$baseTypesCte,
|
||||||
columns AS (
|
columns AS (
|
||||||
SELECT
|
SELECT
|
||||||
c.oid AS relid,
|
c.oid AS relid,
|
||||||
@@ -631,7 +640,7 @@ tablesSqlQuery =
|
|||||||
CASE
|
CASE
|
||||||
WHEN t.typtype = 'd' THEN
|
WHEN t.typtype = 'd' THEN
|
||||||
CASE
|
CASE
|
||||||
WHEN bt.typnamespace = 'pg_catalog'::regnamespace THEN format_type(t.typbasetype, NULL::integer)
|
WHEN bt.base_namespace = 'pg_catalog'::regnamespace THEN format_type(bt.base_type, NULL::integer)
|
||||||
ELSE format_type(a.atttypid, a.atttypmod)
|
ELSE format_type(a.atttypid, a.atttypmod)
|
||||||
END
|
END
|
||||||
ELSE
|
ELSE
|
||||||
@@ -645,7 +654,7 @@ tablesSqlQuery =
|
|||||||
information_schema._pg_truetypid(a.*, t.*),
|
information_schema._pg_truetypid(a.*, t.*),
|
||||||
information_schema._pg_truetypmod(a.*, t.*)
|
information_schema._pg_truetypmod(a.*, t.*)
|
||||||
)::integer AS character_maximum_length,
|
)::integer AS character_maximum_length,
|
||||||
COALESCE(bt.oid, t.oid) AS base_type,
|
bt.base_type,
|
||||||
a.attnum::integer AS position
|
a.attnum::integer AS position
|
||||||
FROM pg_attribute a
|
FROM pg_attribute a
|
||||||
LEFT JOIN pg_description AS d
|
LEFT JOIN pg_description AS d
|
||||||
@@ -656,8 +665,8 @@ tablesSqlQuery =
|
|||||||
ON a.attrelid = c.oid
|
ON a.attrelid = c.oid
|
||||||
JOIN pg_type t
|
JOIN pg_type t
|
||||||
ON a.atttypid = t.oid
|
ON a.atttypid = t.oid
|
||||||
LEFT JOIN pg_type bt
|
LEFT JOIN base_types bt
|
||||||
ON t.typtype = 'd' AND t.typbasetype = bt.oid
|
ON t.oid = bt.oid
|
||||||
LEFT JOIN pg_depend seq
|
LEFT JOIN pg_depend seq
|
||||||
ON seq.refobjid = a.attrelid and seq.refobjsubid = a.attnum and seq.deptype = 'i'
|
ON seq.refobjid = a.attrelid and seq.refobjsubid = a.attnum and seq.deptype = 'i'
|
||||||
WHERE
|
WHERE
|
||||||
|
|||||||
Reference in New Issue
Block a user