Skip to content

Commit 2650693

Browse files
committed
deallocate before run
1 parent 8074465 commit 2650693

File tree

2 files changed

+85
-78
lines changed

2 files changed

+85
-78
lines changed

index_advisor--0.1.0.sql

Lines changed: 78 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -16,89 +16,90 @@ declare
1616
statements text[] = '{}';
1717
begin
1818

19-
-- Disallow multiple statements
20-
if query ilike '%;%' then
21-
raise exception 'query must not contain a semicolon';
22-
end if;
19+
-- Disallow multiple statements
20+
if query ilike '%;%' then
21+
raise exception 'query must not contain a semicolon';
22+
end if;
2323

24-
-- Create a prepared statement for the given query
25-
execute format('prepare %I as %s', prepared_statement_name, query);
24+
-- Create a prepared statement for the given query
25+
deallocate all;
26+
execute format('prepare %I as %s', prepared_statement_name, query);
2627

27-
-- Detect how many arguments are present in the prepared statement
28-
n_args = (
29-
select
30-
coalesce(array_length(parameter_types, 1), 0)
31-
from
32-
pg_prepared_statements
33-
where
34-
name = prepared_statement_name
35-
limit
36-
1
37-
);
28+
-- Detect how many arguments are present in the prepared statement
29+
n_args = (
30+
select
31+
coalesce(array_length(parameter_types, 1), 0)
32+
from
33+
pg_prepared_statements
34+
where
35+
name = prepared_statement_name
36+
limit
37+
1
38+
);
3839

39-
-- Create a SQL statement that can be executed to collect the explain plan
40-
explain_plan_statement = format(
41-
'set local plan_cache_mode = force_generic_plan; explain (format json) execute %I%s',
42-
--'explain (format json) execute %I%s',
43-
prepared_statement_name,
44-
case
45-
when n_args = 0 then ''
46-
else format(
47-
'(%s)', array_to_string(array_fill('null'::text, array[n_args]), ',')
48-
)
49-
end
50-
);
40+
-- Create a SQL statement that can be executed to collect the explain plan
41+
explain_plan_statement = format(
42+
'set local plan_cache_mode = force_generic_plan; explain (format json) execute %I%s',
43+
--'explain (format json) execute %I%s',
44+
prepared_statement_name,
45+
case
46+
when n_args = 0 then ''
47+
else format(
48+
'(%s)', array_to_string(array_fill('null'::text, array[n_args]), ',')
49+
)
50+
end
51+
);
5152

52-
-- Store the query plan before any new indexes
53-
execute explain_plan_statement into plan_initial;
53+
-- Store the query plan before any new indexes
54+
execute explain_plan_statement into plan_initial;
5455

55-
-- Create possible indexes
56-
for rec in (
57-
with extension_regclass as (
58-
select
59-
distinct objid as oid
60-
from
61-
pg_depend
62-
where
63-
deptype = 'e'
64-
)
56+
-- Create possible indexes
57+
for rec in (
58+
with extension_regclass as (
6559
select
66-
pc.relnamespace::regnamespace::text as schema_name,
67-
pc.relname as table_name,
68-
pa.attname as column_name,
69-
format(
70-
'select %I.hypopg_create_index($i$create index on %I.%I(%I)$i$)',
71-
hypopg_schema_name,
72-
pc.relnamespace::regnamespace::text,
73-
pc.relname,
74-
pa.attname
75-
) hypopg_statement
60+
distinct objid as oid
7661
from
77-
pg_catalog.pg_class pc
78-
join pg_catalog.pg_attribute pa
79-
on pc.oid = pa.attrelid
80-
left join extension_regclass er
81-
on pc.oid = er.oid
82-
left join pg_index pi
83-
on pc.oid = pi.indrelid
84-
and (select array_agg(x) from unnest(pi.indkey) v(x)) = array[pa.attnum]
85-
and pi.indexprs is null -- ignore expression indexes
86-
and pi.indpred is null -- ignore partial indexes
62+
pg_depend
8763
where
88-
pc.relnamespace::regnamespace::text not in ( -- ignore schema list
89-
'pg_catalog', 'pg_toast', 'information_schema'
90-
)
91-
and er.oid is null -- ignore entities owned by extensions
92-
and pc.relkind in ('r', 'm') -- regular tables, and materialized views
93-
and pc.relpersistence = 'p' -- permanent tables (not unlogged or temporary)
94-
and pa.attnum > 0
95-
and not pa.attisdropped
96-
and pi.indrelid is null
64+
deptype = 'e'
65+
)
66+
select
67+
pc.relnamespace::regnamespace::text as schema_name,
68+
pc.relname as table_name,
69+
pa.attname as column_name,
70+
format(
71+
'select %I.hypopg_create_index($i$create index on %I.%I(%I)$i$)',
72+
hypopg_schema_name,
73+
pc.relnamespace::regnamespace::text,
74+
pc.relname,
75+
pa.attname
76+
) hypopg_statement
77+
from
78+
pg_catalog.pg_class pc
79+
join pg_catalog.pg_attribute pa
80+
on pc.oid = pa.attrelid
81+
left join extension_regclass er
82+
on pc.oid = er.oid
83+
left join pg_index pi
84+
on pc.oid = pi.indrelid
85+
and (select array_agg(x) from unnest(pi.indkey) v(x)) = array[pa.attnum]
86+
and pi.indexprs is null -- ignore expression indexes
87+
and pi.indpred is null -- ignore partial indexes
88+
where
89+
pc.relnamespace::regnamespace::text not in ( -- ignore schema list
90+
'pg_catalog', 'pg_toast', 'information_schema'
9791
)
98-
loop
99-
-- Create the hypothetical index
100-
execute rec.hypopg_statement;
101-
end loop;
92+
and er.oid is null -- ignore entities owned by extensions
93+
and pc.relkind in ('r', 'm') -- regular tables, and materialized views
94+
and pc.relpersistence = 'p' -- permanent tables (not unlogged or temporary)
95+
and pa.attnum > 0
96+
and not pa.attisdropped
97+
and pi.indrelid is null
98+
)
99+
loop
100+
-- Create the hypothetical index
101+
execute rec.hypopg_statement;
102+
end loop;
102103

103104
/*
104105
for rec in select * from hypopg()
@@ -132,8 +133,9 @@ begin
132133

133134
-- Reset all hypothetical indexes
134135
perform hypopg_reset();
135-
-- Delete the prepared statement
136-
perform format('deallocate %I', prepared_statement_name);
136+
137+
-- Reset prepared statements
138+
deallocate all;
137139

138140
return query select * from unnest(statements);
139141

test/expected/integration.out

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
begin;
22
create extension index_advisor cascade;
33
NOTICE: installing required extension "hypopg"
4-
create table if not exists public.book(id int, name text);
5-
select index_advisor($$ select * from book where id = $1 $$);
4+
create table public.book(
5+
id int,
6+
name text
7+
);
8+
select index_advisor($$
9+
select * from book where id = $1
10+
$$);
611
index_advisor
712
----------------------------------------------
813
CREATE INDEX ON public.book USING btree (id)

0 commit comments

Comments
 (0)