Skip to content

Commit 552622f

Browse files
merge
2 parents 2f18db5 + 0df473b commit 552622f

File tree

10 files changed

+252
-268
lines changed

10 files changed

+252
-268
lines changed

crates/pg_schema_cache/src/functions.rs

Lines changed: 3 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -110,141 +110,8 @@ impl SchemaCacheItem for Function {
110110
type Item = Function;
111111

112112
async fn load(pool: &PgPool) -> Result<Vec<Function>, sqlx::Error> {
113-
sqlx::query_as!(
114-
Function,
115-
r#"
116-
with functions as (
117-
select
118-
oid,
119-
proname,
120-
prosrc,
121-
prorettype,
122-
proretset,
123-
provolatile,
124-
prosecdef,
125-
prolang,
126-
pronamespace,
127-
proconfig,
128-
129-
-- proargmodes is null when all arg modes are IN
130-
coalesce(
131-
p.proargmodes,
132-
array_fill(
133-
'i' :: text,
134-
array [cardinality(coalesce(p.proallargtypes, p.proargtypes))]
135-
)
136-
) as arg_modes,
137-
-- proargnames is null when all args are unnamed
138-
coalesce(
139-
p.proargnames,
140-
array_fill(
141-
'' :: text,
142-
array [cardinality(coalesce(p.proallargtypes, p.proargtypes))]
143-
)
144-
) as arg_names,
145-
-- proallargtypes is null when all arg modes are IN
146-
coalesce(p.proallargtypes, p.proargtypes) as arg_types,
147-
array_cat(
148-
array_fill(false, array [pronargs - pronargdefaults]),
149-
array_fill(true, array [pronargdefaults])
150-
) as arg_has_defaults
151-
from
152-
pg_proc as p
153-
where
154-
p.prokind = 'f'
155-
)
156-
select
157-
f.oid :: int8 as "id!",
158-
n.nspname as "schema!",
159-
f.proname as "name!",
160-
l.lanname as "language!",
161-
case
162-
when l.lanname = 'internal' then ''
163-
else f.prosrc
164-
end as body,
165-
case
166-
when l.lanname = 'internal' then ''
167-
else pg_get_functiondef(f.oid)
168-
end as definition,
169-
coalesce(f_args.args, '[]') as args,
170-
nullif(pg_get_function_arguments(f.oid), '') as argument_types,
171-
nullif(pg_get_function_identity_arguments(f.oid), '') as identity_argument_types,
172-
f.prorettype :: int8 as "return_type_id!",
173-
pg_get_function_result(f.oid) as "return_type!",
174-
nullif(rt.typrelid :: int8, 0) as return_type_relation_id,
175-
f.proretset as is_set_returning_function,
176-
case
177-
when f.provolatile = 'i' then 'IMMUTABLE'
178-
when f.provolatile = 's' then 'STABLE'
179-
when f.provolatile = 'v' then 'VOLATILE'
180-
end as behavior,
181-
f.prosecdef as security_definer
182-
from
183-
functions f
184-
left join pg_namespace n on f.pronamespace = n.oid
185-
left join pg_language l on f.prolang = l.oid
186-
left join pg_type rt on rt.oid = f.prorettype
187-
left join (
188-
select
189-
oid,
190-
jsonb_object_agg(param, value) filter (
191-
where
192-
param is not null
193-
) as config_params
194-
from
195-
(
196-
select
197-
oid,
198-
(string_to_array(unnest(proconfig), '=')) [1] as param,
199-
(string_to_array(unnest(proconfig), '=')) [2] as value
200-
from
201-
functions
202-
) as t
203-
group by
204-
oid
205-
) f_config on f_config.oid = f.oid
206-
left join (
207-
select
208-
oid,
209-
jsonb_agg(
210-
jsonb_build_object(
211-
'mode',
212-
t2.mode,
213-
'name',
214-
name,
215-
'type_id',
216-
type_id,
217-
'has_default',
218-
has_default
219-
)
220-
) as args
221-
from
222-
(
223-
select
224-
oid,
225-
unnest(arg_modes) as mode,
226-
unnest(arg_names) as name,
227-
unnest(arg_types) :: int8 as type_id,
228-
unnest(arg_has_defaults) as has_default
229-
from
230-
functions
231-
) as t1,
232-
lateral (
233-
select
234-
case
235-
when t1.mode = 'i' then 'in'
236-
when t1.mode = 'o' then 'out'
237-
when t1.mode = 'b' then 'inout'
238-
when t1.mode = 'v' then 'variadic'
239-
else 'table'
240-
end as mode
241-
) as t2
242-
group by
243-
t1.oid
244-
) f_args on f_args.oid = f.oid;
245-
"#
246-
)
247-
.fetch_all(pool)
248-
.await
113+
sqlx::query_file_as!(Function, "src/queries/functions.sql")
114+
.fetch_all(pool)
115+
.await
249116
}
250117
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
with functions as (
2+
select
3+
*,
4+
-- proargmodes is null when all arg modes are IN
5+
coalesce(
6+
p.proargmodes,
7+
array_fill(
8+
'i' :: text,
9+
array [cardinality(coalesce(p.proallargtypes, p.proargtypes))]
10+
)
11+
) as arg_modes,
12+
-- proargnames is null when all args are unnamed
13+
coalesce(
14+
p.proargnames,
15+
array_fill(
16+
'' :: text,
17+
array [cardinality(coalesce(p.proallargtypes, p.proargtypes))]
18+
)
19+
) as arg_names,
20+
-- proallargtypes is null when all arg modes are IN
21+
coalesce(p.proallargtypes, p.proargtypes) as arg_types,
22+
array_cat(
23+
array_fill(false, array [pronargs - pronargdefaults]),
24+
array_fill(true, array [pronargdefaults])
25+
) as arg_has_defaults
26+
from
27+
pg_proc as p
28+
where
29+
p.prokind = 'f'
30+
)
31+
select
32+
f.oid :: int8 as id,
33+
n.nspname as schema,
34+
f.proname as name,
35+
l.lanname as language,
36+
case
37+
when l.lanname = 'internal' then ''
38+
else f.prosrc
39+
end as definition,
40+
case
41+
when l.lanname = 'internal' then f.prosrc
42+
else pg_get_functiondef(f.oid)
43+
end as complete_statement,
44+
coalesce(f_args.args, '[]') as args,
45+
pg_get_function_arguments(f.oid) as argument_types,
46+
pg_get_function_identity_arguments(f.oid) as identity_argument_types,
47+
f.prorettype :: int8 as return_type_id,
48+
pg_get_function_result(f.oid) as return_type,
49+
nullif(rt.typrelid :: int8, 0) as return_type_relation_id,
50+
f.proretset as is_set_returning_function,
51+
case
52+
when f.provolatile = 'i' then 'IMMUTABLE'
53+
when f.provolatile = 's' then 'STABLE'
54+
when f.provolatile = 'v' then 'VOLATILE'
55+
end as behavior,
56+
f.prosecdef as security_definer
57+
from
58+
functions f
59+
left join pg_namespace n on f.pronamespace = n.oid
60+
left join pg_language l on f.prolang = l.oid
61+
left join pg_type rt on rt.oid = f.prorettype
62+
left join (
63+
select
64+
oid,
65+
jsonb_object_agg(param, value) filter (
66+
where
67+
param is not null
68+
) as config_params
69+
from
70+
(
71+
select
72+
oid,
73+
(string_to_array(unnest(proconfig), '=')) [1] as param,
74+
(string_to_array(unnest(proconfig), '=')) [2] as value
75+
from
76+
functions
77+
) as t
78+
group by
79+
oid
80+
) f_config on f_config.oid = f.oid
81+
left join (
82+
select
83+
oid,
84+
jsonb_agg(
85+
jsonb_build_object(
86+
'mode',
87+
t2.mode,
88+
'name',
89+
name,
90+
'type_id',
91+
type_id,
92+
'has_default',
93+
has_default
94+
)
95+
) as args
96+
from
97+
(
98+
select
99+
oid,
100+
unnest(arg_modes) as mode,
101+
unnest(arg_names) as name,
102+
unnest(arg_types) :: int8 as type_id,
103+
unnest(arg_has_defaults) as has_default
104+
from
105+
functions
106+
) as t1,
107+
lateral (
108+
select
109+
case
110+
when t1.mode = 'i' then 'in'
111+
when t1.mode = 'o' then 'out'
112+
when t1.mode = 'b' then 'inout'
113+
when t1.mode = 'v' then 'variadic'
114+
else 'table'
115+
end as mode
116+
) as t2
117+
group by
118+
t1.oid
119+
) f_args on f_args.oid = f.oid;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
select
2+
n.oid :: int8 as "id!",
3+
n.nspname as name,
4+
u.rolname as "owner!"
5+
from
6+
pg_namespace n,
7+
pg_roles u
8+
where
9+
n.nspowner = u.oid
10+
and (
11+
pg_has_role(n.nspowner, 'USAGE')
12+
or has_schema_privilege(n.oid, 'CREATE, USAGE')
13+
)
14+
and not pg_catalog.starts_with(n.nspname, 'pg_temp_')
15+
and not pg_catalog.starts_with(n.nspname, 'pg_toast_temp_');
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
select
2+
c.oid :: int8 as "id!",
3+
nc.nspname as schema,
4+
c.relname as name,
5+
c.relrowsecurity as rls_enabled,
6+
c.relforcerowsecurity as rls_forced,
7+
case
8+
when c.relreplident = 'd' then 'DEFAULT'
9+
when c.relreplident = 'i' then 'INDEX'
10+
when c.relreplident = 'f' then 'FULL'
11+
else 'NOTHING'
12+
end as "replica_identity!",
13+
pg_total_relation_size(format('%I.%I', nc.nspname, c.relname)) :: int8 as "bytes!",
14+
pg_size_pretty(
15+
pg_total_relation_size(format('%I.%I', nc.nspname, c.relname))
16+
) as "size!",
17+
pg_stat_get_live_tuples(c.oid) as "live_rows_estimate!",
18+
pg_stat_get_dead_tuples(c.oid) as "dead_rows_estimate!",
19+
obj_description(c.oid) as comment
20+
from
21+
pg_namespace nc
22+
join pg_class c on nc.oid = c.relnamespace
23+
where
24+
c.relkind in ('r', 'p')
25+
and not pg_is_other_temp_schema(nc.oid)
26+
and (
27+
pg_has_role(c.relowner, 'USAGE')
28+
or has_table_privilege(
29+
c.oid,
30+
'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'
31+
)
32+
or has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES')
33+
)
34+
group by
35+
c.oid,
36+
c.relname,
37+
c.relrowsecurity,
38+
c.relforcerowsecurity,
39+
c.relreplident,
40+
nc.nspname;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
select
2+
t.oid :: int8 as "id!",
3+
t.typname as name,
4+
n.nspname as "schema!",
5+
format_type (t.oid, null) as "format!",
6+
coalesce(t_enums.enums, '[]') as enums,
7+
coalesce(t_attributes.attributes, '[]') as attributes,
8+
obj_description (t.oid, 'pg_type') as comment
9+
from
10+
pg_type t
11+
left join pg_namespace n on n.oid = t.typnamespace
12+
left join (
13+
select
14+
enumtypid,
15+
jsonb_agg(
16+
enumlabel
17+
order by
18+
enumsortorder
19+
) as enums
20+
from
21+
pg_enum
22+
group by
23+
enumtypid
24+
) as t_enums on t_enums.enumtypid = t.oid
25+
left join (
26+
select
27+
oid,
28+
jsonb_agg(
29+
jsonb_build_object('name', a.attname, 'type_id', a.atttypid :: int8)
30+
order by
31+
a.attnum asc
32+
) as attributes
33+
from
34+
pg_class c
35+
join pg_attribute a on a.attrelid = c.oid
36+
where
37+
c.relkind = 'c'
38+
and not a.attisdropped
39+
group by
40+
c.oid
41+
) as t_attributes on t_attributes.oid = t.typrelid
42+
where
43+
(
44+
t.typrelid = 0
45+
or (
46+
select
47+
c.relkind = 'c'
48+
from
49+
pg_class c
50+
where
51+
c.oid = t.typrelid
52+
)
53+
);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
select
2+
version(),
3+
current_setting('server_version_num') :: int8 AS version_num,
4+
(
5+
select
6+
count(*) :: int8 AS active_connections
7+
FROM
8+
pg_stat_activity
9+
) AS active_connections,
10+
current_setting('max_connections') :: int8 AS max_connections;

0 commit comments

Comments
 (0)