Revision | c45371c527de71c2c19bf1c808e8819b15b86ac0 (tree) |
---|---|
Time | 2016-01-15 16:50:08 |
Author | Kyotaro Horiguchi <horiguchi.kyotaro@lab....> |
Commiter | Kyotaro Horiguchi |
Refactor Makefile
Simplified Makefile. Makefile gets too complex and ugly so refactored
it for readability. This change also allows to share some script among
multiple PG versions if possible.
@@ -1,8 +1,11 @@ | ||
1 | 1 | # pg_dbms_stats/Makefile |
2 | 2 | |
3 | +DBMSSTATSVER = 1.3.6 | |
4 | +PGVERS = 91 92 93 94 | |
5 | +IS_PRE_95 = $(filter 0,$(shell test "$(MAJORVERSION)" \< "9.5"; echo $$?)) | |
6 | + | |
3 | 7 | MODULE_big = pg_dbms_stats |
4 | 8 | OBJS = pg_dbms_stats.o dump.o import.o |
5 | -DBMSSTATSVER = 1.3.6 | |
6 | 9 | DOCDIR = doc |
7 | 10 | EXTDIR = ext_scripts |
8 | 11 |
@@ -12,7 +15,6 @@ endif | ||
12 | 15 | |
13 | 16 | LAST_LIBPATH=$(shell echo $(LD_LIBRARY_PATH) | sed -e "s/^.*;//") |
14 | 17 | CHECKING=$(shell echo $(LAST_LIBPATH)| grep './tmp_check/install/' | wc -l) |
15 | - | |
16 | 18 | EXTENSION = pg_dbms_stats |
17 | 19 | |
18 | 20 | REGRESS = init-common ut_fdw_init init-$(REGTESTVER) ut-common \ |
@@ -20,19 +22,20 @@ REGRESS = init-common ut_fdw_init init-$(REGTESTVER) ut-common \ | ||
20 | 22 | EXTRA_INSTALL = contrib/file_fdw |
21 | 23 | |
22 | 24 | # Before 9.5 needs extra-install flag for pg_regress |
23 | -REGRESS_OPTS = --encoding=UTF8 --temp-config=regress.conf $(if $(filter 0,$(shell test "$(MAJORVERSION)" \< "9.5"; echo $$?)),--extra-install=$(EXTRA_INSTALL)) | |
25 | +REGRESS_OPTS = --encoding=UTF8 --temp-config=regress.conf $(if $(IS_PRE_95),--extra-install=$(EXTRA_INSTALL)) | |
24 | 26 | |
25 | -DATA = pg_dbms_stats--1.3.6.sql pg_dbms_stats--1.0--1.3.2.sql pg_dbms_stats--1.3.2--1.3.3.sql pg_dbms_stats--1.3.3--1.3.4.sql pg_dbms_stats--1.3.4--1.3.5.sql pg_dbms_stats--1.3.5--1.3.6.sql | |
27 | +# Pick up only the install scripts needed for the PG version. | |
28 | +DATA = $(subst -$(MAJORVERSION).sql,.sql,$(filter %-$(MAJORVERSION).sql,$(notdir $(wildcard ext_scripts/*.sql)))) | |
26 | 29 | |
27 | 30 | DOCS = $(DOCDIR)/export_effective_stats-$(MAJORVERSION).sql.sample \ |
28 | 31 | $(DOCDIR)/export_plain_stats-$(MAJORVERSION).sql.sample |
29 | 32 | |
33 | +# Source tarballs required for rpmbuild | |
30 | 34 | STARBALL = pg_dbms_stats-$(DBMSSTATSVER).tar.gz |
31 | -STARBALL94 = pg_dbms_stats94-$(DBMSSTATSVER).tar.gz | |
32 | -STARBALL93 = pg_dbms_stats93-$(DBMSSTATSVER).tar.gz | |
33 | -STARBALL92 = pg_dbms_stats92-$(DBMSSTATSVER).tar.gz | |
34 | -STARBALL91 = pg_dbms_stats91-$(DBMSSTATSVER).tar.gz | |
35 | -STARBALLS = $(STARBALL) $(STARBALL94) $(STARBALL93) $(STARBALL92) $(STARBALL91) | |
35 | +STARBALLS = $(STARBALL) $(foreach v,$(PGVERS),pg_dbms_stats$(v)-$(DBMSSTATSVER).tar.gz) | |
36 | + | |
37 | +# Generate RPM target names for all target PG versions | |
38 | +RPMS = $(foreach v,$(PGVERS),rpm$(v)) | |
36 | 39 | |
37 | 40 | EXTRA_CLEAN = sql/ut_anyarray-*.sql expected/ut_anyarray-*.out \ |
38 | 41 | sql/ut_imp_exp-*.sql expected/ut_imp_exp-*.out \ |
@@ -57,8 +60,8 @@ include $(top_builddir)/src/Makefile.global | ||
57 | 60 | include $(top_srcdir)/contrib/contrib-global.mk |
58 | 61 | endif |
59 | 62 | |
60 | -# Some versions makes no difference in regard to regression test | |
61 | -REGTESTVER = $(if $(filter 0,$(shell test "$(MAJORVERSION)" \< "9.4"; echo $$?)),$(MAJORVERSION),9.4) | |
63 | +# 9.5 has no difference from 9.4 in regard to regression test | |
64 | +REGTESTVER = $(if $(IS_PRE_95),$(MAJORVERSION),9.4) | |
62 | 65 | |
63 | 66 | TARSOURCES = Makefile *.c *.h \ |
64 | 67 | $(EXTDIR)/pg_dbms_stats--*-9.*.sql \ |
@@ -70,13 +73,16 @@ TARSOURCES = Makefile *.c *.h \ | ||
70 | 73 | |
71 | 74 | all: $(DATA) $(DOCS) |
72 | 75 | |
73 | -rpms: rpm94 rpm93 rpm92 rpm91 | |
76 | +rpms: $(RPMS) | |
74 | 77 | |
75 | 78 | sourcetar: $(STARBALL) |
76 | 79 | |
77 | -$(DATA): %.sql: $(EXTDIR)/%-$(REGTESTVER).sql | |
80 | +$(DATA): %.sql: $(EXTDIR)/%-$(MAJORVERSION).sql | |
78 | 81 | cp $< $@ |
79 | 82 | |
83 | +# Source tar balls are the same for all target PG versions. | |
84 | +# This is because rpmbuild requires a tar ball with the same base name | |
85 | +# with target rpm file. | |
80 | 86 | $(STARBALLS): $(TARSOURCES) |
81 | 87 | if [ -h $(subst .tar.gz,,$@) ]; then rm $(subst .tar.gz,,$@); fi |
82 | 88 | if [ -e $(subst .tar.gz,,$@) ]; then \ |
@@ -87,14 +93,6 @@ $(STARBALLS): $(TARSOURCES) | ||
87 | 93 | tar -chzf $@ $(addprefix $(subst .tar.gz,,$@)/, $^) |
88 | 94 | rm $(subst .tar.gz,,$@) |
89 | 95 | |
90 | -rpm94: $(STARBALL94) | |
91 | - MAKE_ROOT=`pwd` rpmbuild -bb SPECS/pg_dbms_stats94.spec | |
92 | - | |
93 | -rpm93: $(STARBALL93) | |
94 | - MAKE_ROOT=`pwd` rpmbuild -bb SPECS/pg_dbms_stats93.spec | |
95 | - | |
96 | -rpm92: $(STARBALL92) | |
97 | - MAKE_ROOT=`pwd` rpmbuild -bb SPECS/pg_dbms_stats92.spec | |
96 | +$(RPMS): rpm% : SPECS/pg_dbms_stats%.spec pg_dbms_stats%-$(DBMSSTATSVER).tar.gz | |
97 | + MAKE_ROOT=`pwd` rpmbuild -bb $< | |
98 | 98 | |
99 | -rpm91: $(STARBALL91) | |
100 | - MAKE_ROOT=`pwd` rpmbuild -bb SPECS/pg_dbms_stats91.spec |
@@ -1,4 +0,0 @@ | ||
1 | -/* pg_dbms_stats/pg_dbms_stats--1.0--1.3.2.sql */ | |
2 | - | |
3 | --- complain if script is sourced in psql, rather than via CREATE EXTENSION | |
4 | -\echo Use "ALTER EXTENSION pg_dbms_stats UPDATE TO '1.3.2'" to load this file. \quit |
@@ -1,1039 +0,0 @@ | ||
1 | -/* pg_dbms_stats/pg_dbms_stats--1.3.2--1.3.3.sql */ | |
2 | - | |
3 | --- complain if script is sourced in psql, rather than via CREATE EXTENSION | |
4 | -\echo Use "ALTER EXTENSION pg_dbms_stats UPDATE TO '1.3.3'" to load this file. \quit | |
5 | - | |
6 | -CREATE OR REPLACE FUNCTION dbms_stats.backup( | |
7 | - backup_id int8, | |
8 | - relid regclass, | |
9 | - attnum int2 | |
10 | -) RETURNS int8 AS | |
11 | -$$ | |
12 | -/* Lock the backup id */ | |
13 | -SELECT * from dbms_stats.backup_history | |
14 | - WHERE id = $1 FOR UPDATE; | |
15 | - | |
16 | -INSERT INTO dbms_stats.relation_stats_backup | |
17 | - SELECT $1, v.relid, v.relname, v.relpages, v.reltuples, v.relallvisible, | |
18 | - v.curpages, v.last_analyze, v.last_autoanalyze | |
19 | - FROM pg_catalog.pg_class c, | |
20 | - dbms_stats.relation_stats_effective v | |
21 | - WHERE c.oid = v.relid | |
22 | - AND dbms_stats.is_target_relkind(relkind) | |
23 | - AND NOT dbms_stats.is_system_catalog(v.relid) | |
24 | - AND (v.relid = $2 OR $2 IS NULL); | |
25 | - | |
26 | -INSERT INTO dbms_stats.column_stats_backup | |
27 | - SELECT $1, atttypid, s.* | |
28 | - FROM pg_catalog.pg_class c, | |
29 | - dbms_stats.column_stats_effective s, | |
30 | - pg_catalog.pg_attribute a | |
31 | - WHERE c.oid = starelid | |
32 | - AND starelid = attrelid | |
33 | - AND staattnum = attnum | |
34 | - AND dbms_stats.is_target_relkind(relkind) | |
35 | - AND NOT dbms_stats.is_system_catalog(c.oid) | |
36 | - AND ($2 IS NULL OR starelid = $2) | |
37 | - AND ($3 IS NULL OR staattnum = $3); | |
38 | - | |
39 | -SELECT $1; | |
40 | -$$ | |
41 | -LANGUAGE sql; | |
42 | - | |
43 | -CREATE OR REPLACE FUNCTION dbms_stats.backup( | |
44 | - relid regclass DEFAULT NULL, | |
45 | - attname text DEFAULT NULL, | |
46 | - comment text DEFAULT NULL | |
47 | -) RETURNS int8 AS | |
48 | -$$ | |
49 | -DECLARE | |
50 | - backup_id int8; | |
51 | - backup_relkind "char"; | |
52 | - set_attnum int2; | |
53 | - unit_type char; | |
54 | -BEGIN | |
55 | - IF $1 IS NULL AND $2 IS NOT NULL THEN | |
56 | - RAISE EXCEPTION 'relation required'; | |
57 | - END IF; | |
58 | - IF $1 IS NOT NULL THEN | |
59 | - SELECT relkind INTO backup_relkind | |
60 | - FROM pg_catalog.pg_class WHERE oid = $1 FOR SHARE; | |
61 | - IF NOT FOUND THEN | |
62 | - RAISE EXCEPTION 'relation "%" not found', $1; | |
63 | - END IF; | |
64 | - IF NOT dbms_stats.is_target_relkind(backup_relkind) THEN | |
65 | - RAISE EXCEPTION 'relation of relkind "%" cannot have statistics to backup: "%"', | |
66 | - backup_relkind, $1 | |
67 | - USING HINT = 'Only tables(r), materialized views(m), foreign tables(f) and indexes(i) are allowed.'; | |
68 | - END IF; | |
69 | - IF dbms_stats.is_system_catalog($1) THEN | |
70 | - RAISE EXCEPTION 'backing up statistics is inhibited for system catalogs: "%"', $1; | |
71 | - END IF; | |
72 | - IF $2 IS NOT NULL THEN | |
73 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
74 | - WHERE a.attrelid = $1 AND a.attname = $2 FOR SHARE; | |
75 | - IF set_attnum IS NULL THEN | |
76 | - RAISE EXCEPTION 'column "%" not found in relation "%"', $2, $1; | |
77 | - END IF; | |
78 | - IF NOT EXISTS(SELECT * FROM dbms_stats.column_stats_effective WHERE starelid = $1 AND staattnum = set_attnum) THEN | |
79 | - RAISE EXCEPTION 'no statistics available for column "%" of relation "%"', $2, $1; | |
80 | - END IF; | |
81 | - unit_type = 'c'; | |
82 | - ELSE | |
83 | - unit_type = 't'; | |
84 | - END IF; | |
85 | - ELSE | |
86 | - unit_type = 'd'; | |
87 | - END IF; | |
88 | - | |
89 | - INSERT INTO dbms_stats.backup_history(time, unit, comment) | |
90 | - VALUES (current_timestamp, unit_type, $3) | |
91 | - RETURNING dbms_stats.backup(id, $1, set_attnum) INTO backup_id; | |
92 | - RETURN backup_id; | |
93 | -END; | |
94 | -$$ | |
95 | -LANGUAGE plpgsql; | |
96 | - | |
97 | -CREATE OR REPLACE FUNCTION dbms_stats.backup_schema_stats( | |
98 | - schemaname text, | |
99 | - comment text | |
100 | -) RETURNS int8 AS | |
101 | -$$ | |
102 | -DECLARE | |
103 | - backup_id int8; | |
104 | -BEGIN | |
105 | - IF NOT EXISTS(SELECT * FROM pg_namespace WHERE nspname = $1 FOR SHARE) | |
106 | - THEN | |
107 | - RAISE EXCEPTION 'schema "%" not found', $1; | |
108 | - END IF; | |
109 | - IF dbms_stats.is_system_schema($1) THEN | |
110 | - RAISE EXCEPTION 'backing up statistics is inhibited for system schemas: "%"', $1; | |
111 | - END IF; | |
112 | - | |
113 | - INSERT INTO dbms_stats.backup_history(time, unit, comment) | |
114 | - VALUES (current_timestamp, 's', comment) | |
115 | - RETURNING id INTO backup_id; | |
116 | - | |
117 | - PERFORM dbms_stats.backup(backup_id, cn.oid, NULL) | |
118 | - FROM (SELECT c.oid | |
119 | - FROM pg_catalog.pg_class c, | |
120 | - pg_catalog.pg_namespace n | |
121 | - WHERE n.nspname = schemaname | |
122 | - AND c.relnamespace = n.oid | |
123 | - AND dbms_stats.is_target_relkind(c.relkind) | |
124 | - ORDER BY c.oid | |
125 | - ) cn; | |
126 | - | |
127 | - RETURN backup_id; | |
128 | -END; | |
129 | -$$ | |
130 | -LANGUAGE plpgsql; | |
131 | - | |
132 | -CREATE OR REPLACE FUNCTION dbms_stats.restore( | |
133 | - backup_id int8, | |
134 | - relid regclass DEFAULT NULL, | |
135 | - attname text DEFAULT NULL | |
136 | -) RETURNS SETOF regclass AS | |
137 | -$$ | |
138 | -DECLARE | |
139 | - restore_id int8; | |
140 | - restore_relid regclass; | |
141 | - restore_attnum int2; | |
142 | - set_attnum int2; | |
143 | - restore_attname text; | |
144 | - restore_type regtype; | |
145 | - cur_type regtype; | |
146 | -BEGIN | |
147 | - IF $1 IS NULL THEN | |
148 | - RAISE EXCEPTION 'backup id required'; | |
149 | - END IF; | |
150 | - IF $2 IS NULL AND $3 IS NOT NULL THEN | |
151 | - RAISE EXCEPTION 'relation required'; | |
152 | - END IF; | |
153 | - IF NOT EXISTS(SELECT * FROM dbms_stats.backup_history | |
154 | - WHERE id <= $1 FOR SHARE) THEN | |
155 | - RAISE EXCEPTION 'backup id % not found', $1; | |
156 | - END IF; | |
157 | - IF $2 IS NOT NULL THEN | |
158 | - IF NOT EXISTS(SELECT * FROM pg_catalog.pg_class | |
159 | - WHERE oid = $2 FOR SHARE) THEN | |
160 | - RAISE EXCEPTION 'relation "%" not found', $2; | |
161 | - END IF; | |
162 | - -- Grabbing all backups for the relation which is not used in restore. | |
163 | - IF NOT EXISTS(SELECT * FROM dbms_stats.relation_stats_backup b | |
164 | - WHERE b.id <= $1 AND b.relid = $2 FOR SHARE) THEN | |
165 | - RAISE EXCEPTION 'statistics of relation "%" not found in any backups before backup id = %', $2, $1; | |
166 | - END IF; | |
167 | - IF $3 IS NOT NULL THEN | |
168 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
169 | - WHERE a.attrelid = $2 AND a.attname = $3; | |
170 | - IF set_attnum IS NULL THEN | |
171 | - RAISE EXCEPTION 'column "%" not found in relation %', $3, $2; | |
172 | - END IF; | |
173 | - IF NOT EXISTS(SELECT * FROM dbms_stats.column_stats_backup WHERE id <= $1 AND starelid = $2 AND staattnum = set_attnum) THEN | |
174 | - RAISE EXCEPTION 'statistics of column "%" of relation "%" are not found in any backups before',$3, $2, $1; | |
175 | - END IF; | |
176 | - END IF; | |
177 | - PERFORM * FROM dbms_stats._relation_stats_locked r | |
178 | - WHERE r.relid = $2 FOR UPDATE; | |
179 | - ELSE | |
180 | - /* Lock the whole relation stats if relation is not specified.*/ | |
181 | - LOCK dbms_stats._relation_stats_locked IN EXCLUSIVE MODE; | |
182 | - END IF; | |
183 | - | |
184 | - FOR restore_id, restore_relid IN | |
185 | - SELECT max(id), coid FROM | |
186 | - (SELECT b.id as id, c.oid as coid | |
187 | - FROM pg_class c, dbms_stats.relation_stats_backup b | |
188 | - WHERE (c.oid = $2 OR $2 IS NULL) | |
189 | - AND c.oid = b.relid | |
190 | - AND dbms_stats.is_target_relkind(c.relkind) | |
191 | - AND NOT dbms_stats.is_system_catalog(c.oid) | |
192 | - AND b.id <= $1 | |
193 | - FOR SHARE) t | |
194 | - GROUP BY coid | |
195 | - ORDER BY coid::regclass::text | |
196 | - LOOP | |
197 | - UPDATE dbms_stats._relation_stats_locked r | |
198 | - SET relid = b.relid, | |
199 | - relname = b.relname, | |
200 | - relpages = b.relpages, | |
201 | - reltuples = b.reltuples, | |
202 | - relallvisible = b.relallvisible, | |
203 | - curpages = b.curpages, | |
204 | - last_analyze = b.last_analyze, | |
205 | - last_autoanalyze = b.last_autoanalyze | |
206 | - FROM dbms_stats.relation_stats_backup b | |
207 | - WHERE r.relid = restore_relid | |
208 | - AND b.id = restore_id | |
209 | - AND b.relid = restore_relid; | |
210 | - IF NOT FOUND THEN | |
211 | - INSERT INTO dbms_stats._relation_stats_locked | |
212 | - SELECT b.relid, | |
213 | - b.relname, | |
214 | - b.relpages, | |
215 | - b.reltuples, | |
216 | - b.relallvisible, | |
217 | - b.curpages, | |
218 | - b.last_analyze, | |
219 | - b.last_autoanalyze | |
220 | - FROM dbms_stats.relation_stats_backup b | |
221 | - WHERE b.id = restore_id | |
222 | - AND b.relid = restore_relid; | |
223 | - END IF; | |
224 | - RETURN NEXT restore_relid; | |
225 | - END LOOP; | |
226 | - | |
227 | - FOR restore_id, restore_relid, restore_attnum, restore_type, cur_type IN | |
228 | - SELECT t.id, t.oid, t.attnum, b.statypid, a.atttypid | |
229 | - FROM pg_attribute a, | |
230 | - dbms_stats.column_stats_backup b, | |
231 | - (SELECT max(b.id) AS id, c.oid, a.attnum | |
232 | - FROM pg_class c, pg_attribute a, dbms_stats.column_stats_backup b | |
233 | - WHERE (c.oid = $2 OR $2 IS NULL) | |
234 | - AND c.oid = a.attrelid | |
235 | - AND c.oid = b.starelid | |
236 | - AND (a.attnum = set_attnum OR set_attnum IS NULL) | |
237 | - AND a.attnum = b.staattnum | |
238 | - AND NOT a.attisdropped | |
239 | - AND dbms_stats.is_target_relkind(c.relkind) | |
240 | - AND b.id <= $1 | |
241 | - GROUP BY c.oid, a.attnum) t | |
242 | - WHERE a.attrelid = t.oid | |
243 | - AND a.attnum = t.attnum | |
244 | - AND b.id = t.id | |
245 | - AND b.starelid = t.oid | |
246 | - AND b.staattnum = t.attnum | |
247 | - LOOP | |
248 | - IF restore_type <> cur_type THEN | |
249 | - SELECT a.attname INTO restore_attname | |
250 | - FROM pg_catalog.pg_attribute a | |
251 | - WHERE a.attrelid = restore_relid | |
252 | - AND a.attnum = restore_attnum; | |
253 | - RAISE WARNING 'data type of column "%.%" is inconsistent between database(%) and backup (%). Skip.', | |
254 | - restore_relid, restore_attname, cur_type, restore_type; | |
255 | - ELSE | |
256 | - DELETE FROM dbms_stats._column_stats_locked | |
257 | - WHERE starelid = restore_relid | |
258 | - AND staattnum = restore_attnum; | |
259 | - INSERT INTO dbms_stats._column_stats_locked | |
260 | - SELECT starelid, staattnum, stainherit, | |
261 | - stanullfrac, stawidth, stadistinct, | |
262 | - stakind1, stakind2, stakind3, stakind4, stakind5, | |
263 | - staop1, staop2, staop3, staop4, staop5, | |
264 | - stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, | |
265 | - stavalues1, stavalues2, stavalues3, stavalues4, stavalues5 | |
266 | - FROM dbms_stats.column_stats_backup | |
267 | - WHERE id = restore_id | |
268 | - AND starelid = restore_relid | |
269 | - AND staattnum = restore_attnum; | |
270 | - END IF; | |
271 | - END LOOP; | |
272 | -EXCEPTION | |
273 | - WHEN unique_violation THEN | |
274 | - RAISE EXCEPTION 'This operation is canceled by simultaneous lock or restore operation on the same relation.'; | |
275 | -END; | |
276 | -$$ | |
277 | -LANGUAGE plpgsql; | |
278 | - | |
279 | -CREATE OR REPLACE FUNCTION dbms_stats.restore_database_stats( | |
280 | - as_of_timestamp timestamp with time zone | |
281 | -) RETURNS SETOF regclass AS | |
282 | -$$ | |
283 | -SELECT dbms_stats.restore(m.id, m.relid) | |
284 | - FROM (SELECT max(id) AS id, relid | |
285 | - FROM (SELECT r.id, r.relid | |
286 | - FROM pg_class c, dbms_stats.relation_stats_backup r, | |
287 | - dbms_stats.backup_history b | |
288 | - WHERE c.oid = r.relid | |
289 | - AND r.id = b.id | |
290 | - AND b.time <= $1 | |
291 | - FOR SHARE) t1 | |
292 | - GROUP BY t1.relid | |
293 | - ORDER BY t1.relid) m; | |
294 | -$$ | |
295 | -LANGUAGE sql STRICT; | |
296 | - | |
297 | -CREATE OR REPLACE FUNCTION dbms_stats.restore_schema_stats( | |
298 | - schemaname text, | |
299 | - as_of_timestamp timestamp with time zone | |
300 | -) RETURNS SETOF regclass AS | |
301 | -$$ | |
302 | -BEGIN | |
303 | - IF NOT EXISTS(SELECT * FROM pg_namespace WHERE nspname = $1) THEN | |
304 | - RAISE EXCEPTION 'schema "%" not found', $1; | |
305 | - END IF; | |
306 | - IF dbms_stats.is_system_schema($1) THEN | |
307 | - RAISE EXCEPTION 'restoring statistics is inhibited for system schemas: "%"', $1; | |
308 | - END IF; | |
309 | - | |
310 | - RETURN QUERY | |
311 | - SELECT dbms_stats.restore(m.id, m.relid) | |
312 | - FROM (SELECT max(id) AS id, relid | |
313 | - FROM (SELECT r.id, r.relid | |
314 | - FROM pg_class c, pg_namespace n, | |
315 | - dbms_stats.relation_stats_backup r, | |
316 | - dbms_stats.backup_history b | |
317 | - WHERE c.oid = r.relid | |
318 | - AND c.relnamespace = n.oid | |
319 | - AND n.nspname = $1 | |
320 | - AND r.id = b.id | |
321 | - AND b.time <= $2 | |
322 | - FOR SHARE) t1 | |
323 | - GROUP BY t1.relid | |
324 | - ORDER BY t1.relid) m; | |
325 | -END; | |
326 | -$$ | |
327 | -LANGUAGE plpgsql STRICT; | |
328 | - | |
329 | -CREATE OR REPLACE FUNCTION dbms_stats.restore_stats( | |
330 | - backup_id int8 | |
331 | -) RETURNS SETOF regclass AS | |
332 | -$$ | |
333 | -DECLARE | |
334 | - restore_relid regclass; | |
335 | - restore_attnum int2; | |
336 | - restore_attname text; | |
337 | - restore_type regtype; | |
338 | - cur_type regtype; | |
339 | -BEGIN | |
340 | - IF NOT EXISTS(SELECT * FROM dbms_stats.backup_history WHERE id = $1) THEN | |
341 | - RAISE EXCEPTION 'backup id % not found', $1; | |
342 | - END IF; | |
343 | - | |
344 | - /* Lock the backup */ | |
345 | - PERFORM * from dbms_stats.relation_stats_backup b | |
346 | - WHERE id = $1 FOR SHARE; | |
347 | - | |
348 | - /* Locking only _relation_stats_locked is sufficient */ | |
349 | - LOCK dbms_stats._relation_stats_locked IN EXCLUSIVE MODE; | |
350 | - | |
351 | - FOR restore_relid IN | |
352 | - SELECT b.relid | |
353 | - FROM pg_class c | |
354 | - JOIN dbms_stats.relation_stats_backup b ON (c.oid = b.relid) | |
355 | - WHERE b.id = $1 | |
356 | - ORDER BY c.oid::regclass::text | |
357 | - LOOP | |
358 | - UPDATE dbms_stats._relation_stats_locked r | |
359 | - SET relid = b.relid, | |
360 | - relname = b.relname, | |
361 | - relpages = b.relpages, | |
362 | - reltuples = b.reltuples, | |
363 | - relallvisible = b.relallvisible, | |
364 | - curpages = b.curpages, | |
365 | - last_analyze = b.last_analyze, | |
366 | - last_autoanalyze = b.last_autoanalyze | |
367 | - FROM dbms_stats.relation_stats_backup b | |
368 | - WHERE r.relid = restore_relid | |
369 | - AND b.id = $1 | |
370 | - AND b.relid = restore_relid; | |
371 | - IF NOT FOUND THEN | |
372 | - INSERT INTO dbms_stats._relation_stats_locked | |
373 | - SELECT b.relid, | |
374 | - b.relname, | |
375 | - b.relpages, | |
376 | - b.reltuples, | |
377 | - b.relallvisible, | |
378 | - b.curpages, | |
379 | - b.last_analyze, | |
380 | - b.last_autoanalyze | |
381 | - FROM dbms_stats.relation_stats_backup b | |
382 | - WHERE b.id = $1 | |
383 | - AND b.relid = restore_relid; | |
384 | - END IF; | |
385 | - RETURN NEXT restore_relid; | |
386 | - END LOOP; | |
387 | - | |
388 | - FOR restore_relid, restore_attnum, restore_type, cur_type IN | |
389 | - SELECT c.oid, a.attnum, b.statypid, a.atttypid | |
390 | - FROM pg_class c | |
391 | - JOIN dbms_stats.column_stats_backup b ON (c.oid = b.starelid) | |
392 | - JOIN pg_attribute a ON (b.starelid = attrelid | |
393 | - AND b.staattnum = a.attnum) | |
394 | - WHERE b.id = $1 | |
395 | - LOOP | |
396 | - IF restore_type <> cur_type THEN | |
397 | - SELECT attname INTO restore_attname | |
398 | - FROM pg_catalog.pg_attribute | |
399 | - WHERE attrelid = restore_relid | |
400 | - AND attnum = restore_attnum; | |
401 | - RAISE WARNING 'data type of column "%.%" is inconsistent between database(%) and backup (%). Skip.', | |
402 | - restore_relid, restore_attname, cur_type, restore_type; | |
403 | - ELSE | |
404 | - DELETE FROM dbms_stats._column_stats_locked | |
405 | - WHERE starelid = restore_relid | |
406 | - AND staattnum = restore_attnum; | |
407 | - INSERT INTO dbms_stats._column_stats_locked | |
408 | - SELECT starelid, staattnum, stainherit, | |
409 | - stanullfrac, stawidth, stadistinct, | |
410 | - stakind1, stakind2, stakind3, stakind4, stakind5, | |
411 | - staop1, staop2, staop3, staop4, staop5, | |
412 | - stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, | |
413 | - stavalues1, stavalues2, stavalues3, stavalues4, stavalues5 | |
414 | - FROM dbms_stats.column_stats_backup | |
415 | - WHERE id = $1 | |
416 | - AND starelid = restore_relid | |
417 | - AND staattnum = restore_attnum; | |
418 | - END IF; | |
419 | - END LOOP; | |
420 | - | |
421 | -END; | |
422 | -$$ | |
423 | -LANGUAGE plpgsql STRICT; | |
424 | - | |
425 | -CREATE OR REPLACE FUNCTION dbms_stats.lock( | |
426 | - relid regclass, | |
427 | - attname text | |
428 | -) RETURNS regclass AS | |
429 | -$$ | |
430 | -DECLARE | |
431 | - lock_relkind "char"; | |
432 | - set_attnum int2; | |
433 | - r record; | |
434 | -BEGIN | |
435 | - IF $1 IS NULL THEN | |
436 | - RAISE EXCEPTION 'relation required'; | |
437 | - END IF; | |
438 | - IF $2 IS NULL THEN | |
439 | - RETURN dbms_stats.lock($1); | |
440 | - END IF; | |
441 | - SELECT relkind INTO lock_relkind FROM pg_catalog.pg_class WHERE oid = $1; | |
442 | - IF NOT FOUND THEN | |
443 | - RAISE EXCEPTION 'relation "%" not found', $1; | |
444 | - END IF; | |
445 | - IF NOT dbms_stats.is_target_relkind(lock_relkind) THEN | |
446 | - RAISE EXCEPTION '"%" must be a table or an index', $1; | |
447 | - END IF; | |
448 | - IF EXISTS(SELECT * FROM pg_catalog.pg_index WHERE lock_relkind = 'i' AND indexrelid = $1 AND indexprs IS NULL) THEN | |
449 | - RAISE EXCEPTION '"%" must be an expression index', $1; | |
450 | - END IF; | |
451 | - IF dbms_stats.is_system_catalog($1) THEN | |
452 | - RAISE EXCEPTION 'locking statistics is inhibited for system catalogs: "%"', $1; | |
453 | - END IF; | |
454 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
455 | - WHERE a.attrelid = $1 AND a.attname = $2; | |
456 | - IF set_attnum IS NULL THEN | |
457 | - RAISE EXCEPTION 'column "%" not found in relation "%"', $2, $1; | |
458 | - END IF; | |
459 | - | |
460 | - /* | |
461 | - * If we don't have per-table statistics, create new one which has NULL for | |
462 | - * every statistic value for column_stats_effective. | |
463 | - */ | |
464 | - IF NOT EXISTS(SELECT * FROM dbms_stats._relation_stats_locked ru | |
465 | - WHERE ru.relid = $1 FOR SHARE) THEN | |
466 | - INSERT INTO dbms_stats._relation_stats_locked | |
467 | - SELECT $1, dbms_stats.relname(nspname, relname), | |
468 | - NULL, NULL, NULL, NULL, NULL | |
469 | - FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n | |
470 | - WHERE c.relnamespace = n.oid | |
471 | - AND c.oid = $1; | |
472 | - END IF; | |
473 | - | |
474 | - /* | |
475 | - * Process for per-column statistics | |
476 | - */ | |
477 | - FOR r IN | |
478 | - SELECT stainherit, stanullfrac, stawidth, stadistinct, | |
479 | - stakind1, stakind2, stakind3, stakind4, stakind5, | |
480 | - staop1, staop2, staop3, staop4, staop5, | |
481 | - stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, | |
482 | - stavalues1, stavalues2, stavalues3, stavalues4, stavalues5 | |
483 | - FROM dbms_stats.column_stats_effective | |
484 | - WHERE starelid = $1 | |
485 | - AND staattnum = set_attnum | |
486 | - LOOP | |
487 | - UPDATE dbms_stats._column_stats_locked c | |
488 | - SET stanullfrac = r.stanullfrac, | |
489 | - stawidth = r.stawidth, | |
490 | - stadistinct = r.stadistinct, | |
491 | - stakind1 = r.stakind1, | |
492 | - stakind2 = r.stakind2, | |
493 | - stakind3 = r.stakind3, | |
494 | - stakind4 = r.stakind4, | |
495 | - stakind5 = r.stakind5, | |
496 | - staop1 = r.staop1, | |
497 | - staop2 = r.staop2, | |
498 | - staop3 = r.staop3, | |
499 | - staop4 = r.staop4, | |
500 | - staop5 = r.staop5, | |
501 | - stanumbers1 = r.stanumbers1, | |
502 | - stanumbers2 = r.stanumbers2, | |
503 | - stanumbers3 = r.stanumbers3, | |
504 | - stanumbers4 = r.stanumbers4, | |
505 | - stanumbers5 = r.stanumbers5, | |
506 | - stavalues1 = r.stavalues1, | |
507 | - stavalues2 = r.stavalues2, | |
508 | - stavalues3 = r.stavalues3, | |
509 | - stavalues4 = r.stavalues4, | |
510 | - stavalues5 = r.stavalues5 | |
511 | - WHERE c.starelid = $1 | |
512 | - AND c.staattnum = set_attnum | |
513 | - AND c.stainherit = r.stainherit; | |
514 | - | |
515 | - IF NOT FOUND THEN | |
516 | - INSERT INTO dbms_stats._column_stats_locked | |
517 | - VALUES ($1, | |
518 | - set_attnum, | |
519 | - r.stainherit, | |
520 | - r.stanullfrac, | |
521 | - r.stawidth, | |
522 | - r.stadistinct, | |
523 | - r.stakind1, | |
524 | - r.stakind2, | |
525 | - r.stakind3, | |
526 | - r.stakind4, | |
527 | - r.stakind5, | |
528 | - r.staop1, | |
529 | - r.staop2, | |
530 | - r.staop3, | |
531 | - r.staop4, | |
532 | - r.staop5, | |
533 | - r.stanumbers1, | |
534 | - r.stanumbers2, | |
535 | - r.stanumbers3, | |
536 | - r.stanumbers4, | |
537 | - r.stanumbers5, | |
538 | - r.stavalues1, | |
539 | - r.stavalues2, | |
540 | - r.stavalues3, | |
541 | - r.stavalues4, | |
542 | - r.stavalues5); | |
543 | - END IF; | |
544 | - END LOOP; | |
545 | - | |
546 | - /* If we don't have statistics at all, raise error. */ | |
547 | - IF NOT FOUND THEN | |
548 | - RAISE EXCEPTION 'no statistics available for column "%" of relation "%"', $2, $1::regclass; | |
549 | - END IF; | |
550 | - | |
551 | - RETURN $1; | |
552 | -EXCEPTION | |
553 | - WHEN unique_violation THEN | |
554 | - RAISE EXCEPTION 'This operation is canceled by simultaneous lock or restore operation on the same relation.'; | |
555 | -END; | |
556 | -$$ | |
557 | -LANGUAGE plpgsql; | |
558 | - | |
559 | -CREATE OR REPLACE FUNCTION dbms_stats.lock(relid regclass) | |
560 | - RETURNS regclass AS | |
561 | -$$ | |
562 | -DECLARE | |
563 | - lock_relkind "char"; | |
564 | - i record; | |
565 | -BEGIN | |
566 | - IF $1 IS NULL THEN | |
567 | - RAISE EXCEPTION 'relation required'; | |
568 | - END IF; | |
569 | - SELECT relkind INTO lock_relkind FROM pg_catalog.pg_class WHERE oid = $1; | |
570 | - IF NOT FOUND THEN | |
571 | - RAISE EXCEPTION 'relation "%" not found', $1; | |
572 | - END IF; | |
573 | - IF NOT dbms_stats.is_target_relkind(lock_relkind) THEN | |
574 | - RAISE EXCEPTION 'locking statistics is not allowed for relations with relkind "%": "%"', lock_relkind, $1 | |
575 | - USING HINT = 'Only tables(r, m, f) and indexes(i) are lockable.'; | |
576 | - END IF; | |
577 | - IF dbms_stats.is_system_catalog($1) THEN | |
578 | - RAISE EXCEPTION 'locking statistics is not allowed for system catalogs: "%"', $1; | |
579 | - END IF; | |
580 | - | |
581 | - UPDATE dbms_stats._relation_stats_locked r | |
582 | - SET relname = dbms_stats.relname(nspname, c.relname), | |
583 | - relpages = v.relpages, | |
584 | - reltuples = v.reltuples, | |
585 | - relallvisible = v.relallvisible, | |
586 | - curpages = v.curpages, | |
587 | - last_analyze = v.last_analyze, | |
588 | - last_autoanalyze = v.last_autoanalyze | |
589 | - FROM pg_catalog.pg_class c, | |
590 | - pg_catalog.pg_namespace n, | |
591 | - dbms_stats.relation_stats_effective v | |
592 | - WHERE r.relid = $1 | |
593 | - AND c.oid = $1 | |
594 | - AND c.relnamespace = n.oid | |
595 | - AND v.relid = $1; | |
596 | - IF NOT FOUND THEN | |
597 | - INSERT INTO dbms_stats._relation_stats_locked | |
598 | - SELECT $1, dbms_stats.relname(nspname, c.relname), | |
599 | - v.relpages, v.reltuples, v.relallvisible, v.curpages, | |
600 | - v.last_analyze, v.last_autoanalyze | |
601 | - FROM pg_catalog.pg_class c, | |
602 | - pg_catalog.pg_namespace n, | |
603 | - dbms_stats.relation_stats_effective v | |
604 | - WHERE c.oid = $1 | |
605 | - AND c.relnamespace = n.oid | |
606 | - AND v.relid = $1; | |
607 | - END IF; | |
608 | - | |
609 | - IF EXISTS(SELECT * | |
610 | - FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index ind | |
611 | - ON c.oid = ind.indexrelid | |
612 | - WHERE c.oid = $1 | |
613 | - AND c.relkind = 'i' | |
614 | - AND ind.indexprs IS NULL) THEN | |
615 | - RETURN $1; | |
616 | - END IF; | |
617 | - | |
618 | - FOR i IN | |
619 | - SELECT staattnum, stainherit, stanullfrac, | |
620 | - stawidth, stadistinct, | |
621 | - stakind1, stakind2, stakind3, stakind4, stakind5, | |
622 | - staop1, staop2, staop3, staop4, staop5, | |
623 | - stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, | |
624 | - stavalues1, stavalues2, stavalues3, stavalues4, stavalues5 | |
625 | - FROM dbms_stats.column_stats_effective | |
626 | - WHERE starelid = $1 | |
627 | - LOOP | |
628 | - UPDATE dbms_stats._column_stats_locked c | |
629 | - SET stanullfrac = i.stanullfrac, | |
630 | - stawidth = i.stawidth, | |
631 | - stadistinct = i.stadistinct, | |
632 | - stakind1 = i.stakind1, | |
633 | - stakind2 = i.stakind2, | |
634 | - stakind3 = i.stakind3, | |
635 | - stakind4 = i.stakind4, | |
636 | - stakind5 = i.stakind5, | |
637 | - staop1 = i.staop1, | |
638 | - staop2 = i.staop2, | |
639 | - staop3 = i.staop3, | |
640 | - staop4 = i.staop4, | |
641 | - staop5 = i.staop5, | |
642 | - stanumbers1 = i.stanumbers1, | |
643 | - stanumbers2 = i.stanumbers2, | |
644 | - stanumbers3 = i.stanumbers3, | |
645 | - stanumbers4 = i.stanumbers4, | |
646 | - stanumbers5 = i.stanumbers5, | |
647 | - stavalues1 = i.stavalues1, | |
648 | - stavalues2 = i.stavalues2, | |
649 | - stavalues3 = i.stavalues3, | |
650 | - stavalues4 = i.stavalues4, | |
651 | - stavalues5 = i.stavalues5 | |
652 | - WHERE c.starelid = $1 | |
653 | - AND c.staattnum = i.staattnum | |
654 | - AND c.stainherit = i.stainherit; | |
655 | - | |
656 | - IF NOT FOUND THEN | |
657 | - INSERT INTO dbms_stats._column_stats_locked | |
658 | - VALUES ($1, | |
659 | - i.staattnum, | |
660 | - i.stainherit, | |
661 | - i.stanullfrac, | |
662 | - i.stawidth, | |
663 | - i.stadistinct, | |
664 | - i.stakind1, | |
665 | - i.stakind2, | |
666 | - i.stakind3, | |
667 | - i.stakind4, | |
668 | - i.stakind5, | |
669 | - i.staop1, | |
670 | - i.staop2, | |
671 | - i.staop3, | |
672 | - i.staop4, | |
673 | - i.staop5, | |
674 | - i.stanumbers1, | |
675 | - i.stanumbers2, | |
676 | - i.stanumbers3, | |
677 | - i.stanumbers4, | |
678 | - i.stanumbers5, | |
679 | - i.stavalues1, | |
680 | - i.stavalues2, | |
681 | - i.stavalues3, | |
682 | - i.stavalues4, | |
683 | - i.stavalues5); | |
684 | - END IF; | |
685 | - END LOOP; | |
686 | - | |
687 | - RETURN $1; | |
688 | -EXCEPTION | |
689 | - WHEN unique_violation THEN | |
690 | - RAISE EXCEPTION 'This operation is canceled by simultaneous lock operation on the same relation.'; | |
691 | -END; | |
692 | -$$ | |
693 | -LANGUAGE plpgsql; | |
694 | - | |
695 | -CREATE OR REPLACE FUNCTION dbms_stats.lock_schema_stats( | |
696 | - schemaname text | |
697 | -) RETURNS SETOF regclass AS | |
698 | -$$ | |
699 | -BEGIN | |
700 | - IF NOT EXISTS(SELECT * FROM pg_namespace WHERE nspname = $1) THEN | |
701 | - RAISE EXCEPTION 'schema "%" not found', $1; | |
702 | - END IF; | |
703 | - IF dbms_stats.is_system_schema($1) THEN | |
704 | - RAISE EXCEPTION 'locking statistics is not allowed for system schemas: "%"', $1; | |
705 | - END IF; | |
706 | - | |
707 | - RETURN QUERY | |
708 | - SELECT dbms_stats.lock(cn.oid) | |
709 | - FROM (SELECT c.oid | |
710 | - FROM pg_class c, pg_namespace n | |
711 | - WHERE c.relnamespace = n.oid | |
712 | - AND dbms_stats.is_target_relkind(c.relkind) | |
713 | - AND n.nspname = $1 | |
714 | - ORDER BY c.oid | |
715 | - ) cn; | |
716 | -END; | |
717 | -$$ | |
718 | -LANGUAGE plpgsql STRICT; | |
719 | - | |
720 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock( | |
721 | - relid regclass DEFAULT NULL, | |
722 | - attname text DEFAULT NULL | |
723 | -) RETURNS SETOF regclass AS | |
724 | -$$ | |
725 | -DECLARE | |
726 | - set_attnum int2; | |
727 | - unlock_id int8; | |
728 | -BEGIN | |
729 | - IF $1 IS NULL AND $2 IS NOT NULL THEN | |
730 | - RAISE EXCEPTION 'relation required'; | |
731 | - END IF; | |
732 | - | |
733 | - /* | |
734 | - * Lock the target relation to prevent conflicting with stats lock/restore | |
735 | - */ | |
736 | - PERFORM * FROM dbms_stats._relation_stats_locked ru | |
737 | - WHERE (ru.relid = $1 OR $1 IS NULL) FOR UPDATE; | |
738 | - | |
739 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
740 | - WHERE a.attrelid = $1 AND a.attname = $2; | |
741 | - IF $2 IS NOT NULL AND set_attnum IS NULL THEN | |
742 | - RAISE EXCEPTION 'column "%" not found in relation "%"', $2, $1; | |
743 | - END IF; | |
744 | - | |
745 | - DELETE FROM dbms_stats._column_stats_locked | |
746 | - WHERE (starelid = $1 OR $1 IS NULL) | |
747 | - AND (staattnum = set_attnum OR $2 IS NULL); | |
748 | - | |
749 | - IF $1 IS NOT NULL AND $2 IS NOT NULL THEN | |
750 | - RETURN QUERY | |
751 | - SELECT $1; | |
752 | - END IF; | |
753 | - FOR unlock_id IN | |
754 | - SELECT ru.relid | |
755 | - FROM dbms_stats._relation_stats_locked ru | |
756 | - WHERE (ru.relid = $1 OR $1 IS NULL) AND ($2 IS NULL) | |
757 | - ORDER BY ru.relid | |
758 | - LOOP | |
759 | - DELETE FROM dbms_stats._relation_stats_locked ru | |
760 | - WHERE ru.relid = unlock_id; | |
761 | - RETURN NEXT unlock_id; | |
762 | - END LOOP; | |
763 | -END; | |
764 | -$$ | |
765 | -LANGUAGE plpgsql; | |
766 | - | |
767 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_database_stats() | |
768 | - RETURNS SETOF regclass AS | |
769 | -$$ | |
770 | -DECLARE | |
771 | - unlock_id int8; | |
772 | -BEGIN | |
773 | - LOCK dbms_stats._relation_stats_locked IN EXCLUSIVE MODE; | |
774 | - | |
775 | - FOR unlock_id IN | |
776 | - SELECT relid | |
777 | - FROM dbms_stats._relation_stats_locked | |
778 | - ORDER BY relid | |
779 | - LOOP | |
780 | - DELETE FROM dbms_stats._relation_stats_locked | |
781 | - WHERE relid = unlock_id; | |
782 | - RETURN NEXT unlock_id; | |
783 | - END LOOP; | |
784 | -END; | |
785 | -$$ | |
786 | -LANGUAGE plpgsql STRICT; | |
787 | - | |
788 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_table_stats(relid regclass) | |
789 | - RETURNS SETOF regclass AS | |
790 | -$$ | |
791 | -DELETE FROM dbms_stats._relation_stats_locked | |
792 | - WHERE relid = $1 | |
793 | - RETURNING relid::regclass | |
794 | -$$ | |
795 | -LANGUAGE sql STRICT; | |
796 | - | |
797 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_table_stats( | |
798 | - schemaname text, | |
799 | - tablename text | |
800 | -) RETURNS SETOF regclass AS | |
801 | -$$ | |
802 | -DELETE FROM dbms_stats._relation_stats_locked | |
803 | - WHERE relid = dbms_stats.relname($1, $2)::regclass | |
804 | - RETURNING relid::regclass | |
805 | -$$ | |
806 | -LANGUAGE sql STRICT; | |
807 | - | |
808 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_column_stats( | |
809 | - relid regclass, | |
810 | - attname text | |
811 | -) RETURNS SETOF regclass AS | |
812 | -$$ | |
813 | -DECLARE | |
814 | - set_attnum int2; | |
815 | -BEGIN | |
816 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
817 | - WHERE a.attrelid = $1 AND a.attname = $2; | |
818 | - IF $2 IS NOT NULL AND set_attnum IS NULL THEN | |
819 | - RAISE EXCEPTION 'column "%" not found in relation "%"', $2, $1; | |
820 | - END IF; | |
821 | - | |
822 | - /* Lock the locked table stats */ | |
823 | - PERFORM * from dbms_stats.relation_stats_locked r | |
824 | - WHERE r.relid = $1 FOR SHARE; | |
825 | - | |
826 | - DELETE FROM dbms_stats._column_stats_locked | |
827 | - WHERE starelid = $1 | |
828 | - AND staattnum = set_attnum; | |
829 | - | |
830 | - RETURN QUERY | |
831 | - SELECT $1; | |
832 | -END; | |
833 | -$$ | |
834 | -LANGUAGE plpgsql STRICT; | |
835 | - | |
836 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_column_stats( | |
837 | - schemaname text, | |
838 | - tablename text, | |
839 | - attname text | |
840 | -) RETURNS SETOF regclass AS | |
841 | -$$ | |
842 | -DECLARE | |
843 | - set_attnum int2; | |
844 | -BEGIN | |
845 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
846 | - WHERE a.attrelid = dbms_stats.relname($1, $2)::regclass | |
847 | - AND a.attname = $3; | |
848 | - IF $3 IS NOT NULL AND set_attnum IS NULL THEN | |
849 | - RAISE EXCEPTION 'column "%" not found in relation "%.%"', $3, $1, $2; | |
850 | - END IF; | |
851 | - | |
852 | - /* Lock the locked table stats */ | |
853 | - PERFORM * from dbms_stats.relation_stats_locked r | |
854 | - WHERE relid = dbms_stats.relname($1, $2)::regclass FOR SHARE; | |
855 | - | |
856 | - DELETE FROM dbms_stats._column_stats_locked | |
857 | - WHERE starelid = dbms_stats.relname($1, $2)::regclass | |
858 | - AND staattnum = set_attnum; | |
859 | - | |
860 | - RETURN QUERY | |
861 | - SELECT dbms_stats.relname($1, $2)::regclass; | |
862 | -END; | |
863 | -$$ | |
864 | -LANGUAGE plpgsql STRICT; | |
865 | - | |
866 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_schema_stats( | |
867 | - schemaname text | |
868 | -) RETURNS SETOF regclass AS | |
869 | -$$ | |
870 | -DECLARE | |
871 | - unlock_id int8; | |
872 | -BEGIN | |
873 | - IF NOT EXISTS(SELECT * FROM pg_namespace WHERE nspname = $1) THEN | |
874 | - RAISE EXCEPTION 'schema "%" not found', $1; | |
875 | - END IF; | |
876 | - IF dbms_stats.is_system_schema($1) THEN | |
877 | - RAISE EXCEPTION 'unlocking statistics is not allowed for system schemas: "%"', $1; | |
878 | - END IF; | |
879 | - | |
880 | - FOR unlock_id IN | |
881 | - SELECT r.relid | |
882 | - FROM dbms_stats._relation_stats_locked r, pg_class c, pg_namespace n | |
883 | - WHERE relid = c.oid | |
884 | - AND c.relnamespace = n.oid | |
885 | - AND n.nspname = $1 | |
886 | - ORDER BY relid | |
887 | - FOR UPDATE | |
888 | - LOOP | |
889 | - DELETE FROM dbms_stats._relation_stats_locked | |
890 | - WHERE relid = unlock_id; | |
891 | - RETURN NEXT unlock_id; | |
892 | - END LOOP; | |
893 | -END; | |
894 | -$$ | |
895 | -LANGUAGE plpgsql STRICT; | |
896 | - | |
897 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_column_stats( | |
898 | - relid regclass, | |
899 | - attname text | |
900 | -) RETURNS SETOF regclass AS | |
901 | -$$ | |
902 | -DECLARE | |
903 | - set_attnum int2; | |
904 | -BEGIN | |
905 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
906 | - WHERE a.attrelid = $1 AND a.attname = $2; | |
907 | - IF $2 IS NOT NULL AND set_attnum IS NULL THEN | |
908 | - RAISE EXCEPTION 'column "%" not found in relation "%"', $2, $1; | |
909 | - END IF; | |
910 | - | |
911 | - /* Lock the locked table stats */ | |
912 | - PERFORM * from dbms_stats.relation_stats_locked r | |
913 | - WHERE r.relid = $1 FOR SHARE; | |
914 | - | |
915 | - DELETE FROM dbms_stats._column_stats_locked | |
916 | - WHERE starelid = $1 | |
917 | - AND staattnum = set_attnum; | |
918 | - | |
919 | - RETURN QUERY | |
920 | - SELECT $1; | |
921 | -END; | |
922 | -$$ | |
923 | -LANGUAGE plpgsql STRICT; | |
924 | - | |
925 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_column_stats( | |
926 | - schemaname text, | |
927 | - tablename text, | |
928 | - attname text | |
929 | -) RETURNS SETOF regclass AS | |
930 | -$$ | |
931 | -DECLARE | |
932 | - set_attnum int2; | |
933 | -BEGIN | |
934 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
935 | - WHERE a.attrelid = dbms_stats.relname($1, $2)::regclass | |
936 | - AND a.attname = $3; | |
937 | - IF $3 IS NOT NULL AND set_attnum IS NULL THEN | |
938 | - RAISE EXCEPTION 'column "%" not found in relation "%.%"', $3, $1, $2; | |
939 | - END IF; | |
940 | - | |
941 | - /* Lock the locked table stats */ | |
942 | - PERFORM * from dbms_stats.relation_stats_locked r | |
943 | - WHERE relid = dbms_stats.relname($1, $2)::regclass FOR SHARE; | |
944 | - | |
945 | - DELETE FROM dbms_stats._column_stats_locked | |
946 | - WHERE starelid = dbms_stats.relname($1, $2)::regclass | |
947 | - AND staattnum = set_attnum; | |
948 | - | |
949 | - RETURN QUERY | |
950 | - SELECT dbms_stats.relname($1, $2)::regclass; | |
951 | -END; | |
952 | -$$ | |
953 | -LANGUAGE plpgsql STRICT; | |
954 | - | |
955 | -CREATE OR REPLACE FUNCTION dbms_stats.purge_stats( | |
956 | - backup_id int8, | |
957 | - force bool DEFAULT false | |
958 | -) RETURNS SETOF dbms_stats.backup_history AS | |
959 | -$$ | |
960 | -DECLARE | |
961 | - delete_id int8; | |
962 | - todelete dbms_stats.backup_history; | |
963 | -BEGIN | |
964 | - IF $1 IS NULL THEN | |
965 | - RAISE EXCEPTION 'backup id required'; | |
966 | - END IF; | |
967 | - IF $2 IS NULL THEN | |
968 | - RAISE EXCEPTION 'NULL is not allowed as the second parameter'; | |
969 | - END IF; | |
970 | - | |
971 | - IF NOT EXISTS(SELECT * FROM dbms_stats.backup_history | |
972 | - WHERE id = $1 FOR UPDATE) THEN | |
973 | - RAISE EXCEPTION 'backup id % not found', $1; | |
974 | - END IF; | |
975 | - IF NOT $2 AND NOT EXISTS(SELECT * | |
976 | - FROM dbms_stats.backup_history | |
977 | - WHERE unit = 'd' | |
978 | - AND id > $1) THEN | |
979 | - RAISE WARNING 'no database-wide backup will remain after purge' | |
980 | - USING HINT = 'Give true for second parameter to purge forcibly.'; | |
981 | - RETURN; | |
982 | - END IF; | |
983 | - | |
984 | - FOR todelete IN | |
985 | - SELECT * FROM dbms_stats.backup_history | |
986 | - WHERE id <= $1 | |
987 | - ORDER BY id FOR UPDATE | |
988 | - LOOP | |
989 | - DELETE FROM dbms_stats.backup_history | |
990 | - WHERE id = todelete.id; | |
991 | - RETURN NEXT todelete; | |
992 | - END LOOP; | |
993 | -END; | |
994 | -$$ | |
995 | -LANGUAGE plpgsql; | |
996 | - | |
997 | -CREATE OR REPLACE FUNCTION dbms_stats.clean_up_stats() RETURNS SETOF text AS | |
998 | -$$ | |
999 | -DECLARE | |
1000 | - clean_relid Oid; | |
1001 | - clean_attnum int2; | |
1002 | - clean_inherit bool; | |
1003 | - clean_rel_col text; | |
1004 | -BEGIN | |
1005 | - -- We don't have to check that table-level dummy statistics of the table | |
1006 | - -- exists here, because the foreign key constraints defined on column-level | |
1007 | - -- dummy static table ensures that. | |
1008 | - FOR clean_rel_col, clean_relid, clean_attnum, clean_inherit IN | |
1009 | - SELECT r.relname || ', ' || v.staattnum::text, | |
1010 | - v.starelid, v.staattnum, v.stainherit | |
1011 | - FROM dbms_stats._column_stats_locked v | |
1012 | - JOIN dbms_stats._relation_stats_locked r ON (v.starelid = r.relid) | |
1013 | - WHERE NOT EXISTS ( | |
1014 | - SELECT NULL | |
1015 | - FROM pg_attribute a | |
1016 | - WHERE a.attrelid = v.starelid | |
1017 | - AND a.attnum = v.staattnum | |
1018 | - AND a.attisdropped = false | |
1019 | - FOR UPDATE | |
1020 | - ) | |
1021 | - LOOP | |
1022 | - DELETE FROM dbms_stats._column_stats_locked | |
1023 | - WHERE starelid = clean_relid | |
1024 | - AND staattnum = clean_attnum | |
1025 | - AND stainherit = clean_inherit; | |
1026 | - RETURN NEXT clean_rel_col; | |
1027 | - END LOOP; | |
1028 | - | |
1029 | - RETURN QUERY | |
1030 | - DELETE FROM dbms_stats._relation_stats_locked r | |
1031 | - WHERE NOT EXISTS ( | |
1032 | - SELECT NULL | |
1033 | - FROM pg_class c | |
1034 | - WHERE c.oid = r.relid) | |
1035 | - RETURNING relname || ','; | |
1036 | - RETURN; | |
1037 | -END | |
1038 | -$$ | |
1039 | -LANGUAGE plpgsql; |
@@ -1,810 +0,0 @@ | ||
1 | -/* pg_dbms_stats/pg_dbms_stats--1.3.4--1.3.5.sql */ | |
2 | - | |
3 | --- complain if script is sourced in psql, rather than via CREATE EXTENSION | |
4 | -\echo Use "ALTER EXTENSION pg_dbms_stats UPDATE TO '1.3.5'" to load this file. \quit | |
5 | - | |
6 | -/* Dropping unnecessary views and rename tables */ | |
7 | -ALTER EXTENSION pg_dbms_stats DROP VIEW dbms_stats.relation_stats_locked; | |
8 | -DROP VIEW dbms_stats.relation_stats_locked; | |
9 | -ALTER EXTENSION pg_dbms_stats DROP VIEW dbms_stats.column_stats_locked; | |
10 | -DROP VIEW dbms_stats.column_stats_locked; | |
11 | - | |
12 | -ALTER TABLE dbms_stats._relation_stats_locked | |
13 | - RENAME TO relation_stats_locked; | |
14 | -ALTER TABLE dbms_stats._column_stats_locked | |
15 | - RENAME TO column_stats_locked; | |
16 | -ALTER INDEX dbms_stats._relation_stats_locked_pkey | |
17 | - RENAME TO relation_stats_locked_pkey; | |
18 | -ALTER INDEX dbms_stats._column_stats_locked_pkey | |
19 | - RENAME TO column_stats_locked_pkey; | |
20 | -ALTER TABLE dbms_stats.column_stats_locked | |
21 | - RENAME CONSTRAINT _column_stats_locked_starelid_fkey | |
22 | - TO column_stats_locked_starelid_fkey; | |
23 | - | |
24 | -/* Change function defenitions */ | |
25 | - | |
26 | -CREATE OR REPLACE FUNCTION dbms_stats.merge( | |
27 | - lhs dbms_stats.column_stats_locked, | |
28 | - rhs pg_catalog.pg_statistic | |
29 | -) RETURNS dbms_stats.column_stats_locked AS | |
30 | -'MODULE_PATHNAME', 'dbms_stats_merge' | |
31 | -LANGUAGE C STABLE; | |
32 | - | |
33 | -CREATE OR REPLACE VIEW dbms_stats.relation_stats_effective AS | |
34 | - SELECT | |
35 | - c.oid AS relid, | |
36 | - dbms_stats.relname(nspname, c.relname) AS relname, | |
37 | - COALESCE(v.relpages, c.relpages) AS relpages, | |
38 | - COALESCE(v.reltuples, c.reltuples) AS reltuples, | |
39 | - COALESCE(v.relallvisible, c.relallvisible) AS relallvisible, | |
40 | - COALESCE(v.curpages, | |
41 | - (pg_relation_size(c.oid) / current_setting('block_size')::int4)::int4) | |
42 | - AS curpages, | |
43 | - COALESCE(v.last_analyze, | |
44 | - pg_catalog.pg_stat_get_last_analyze_time(c.oid)) | |
45 | - AS last_analyze, | |
46 | - COALESCE(v.last_autoanalyze, | |
47 | - pg_catalog.pg_stat_get_last_autoanalyze_time(c.oid)) | |
48 | - AS last_autoanalyze | |
49 | - FROM pg_catalog.pg_class c | |
50 | - JOIN pg_catalog.pg_namespace n | |
51 | - ON c.relnamespace = n.oid | |
52 | - LEFT JOIN dbms_stats.relation_stats_locked v | |
53 | - ON v.relid = c.oid | |
54 | - WHERE dbms_stats.is_target_relkind(c.relkind) | |
55 | - AND NOT dbms_stats.is_system_schema(nspname); | |
56 | - | |
57 | -CREATE OR REPLACE VIEW dbms_stats.column_stats_effective AS | |
58 | - SELECT * FROM ( | |
59 | - SELECT (dbms_stats.merge(v, s)).* | |
60 | - FROM pg_catalog.pg_statistic s | |
61 | - FULL JOIN dbms_stats.column_stats_locked v | |
62 | - USING (starelid, staattnum, stainherit) | |
63 | - WHERE NOT dbms_stats.is_system_catalog(starelid) | |
64 | - AND EXISTS ( | |
65 | - SELECT NULL | |
66 | - FROM pg_attribute a | |
67 | - WHERE a.attrelid = starelid | |
68 | - AND a.attnum = staattnum | |
69 | - AND a.attisdropped = false | |
70 | - ) | |
71 | - ) m | |
72 | - WHERE starelid IS NOT NULL; | |
73 | - | |
74 | -CREATE OR REPLACE FUNCTION dbms_stats.restore( | |
75 | - backup_id int8, | |
76 | - relid regclass DEFAULT NULL, | |
77 | - attname text DEFAULT NULL | |
78 | -) RETURNS SETOF regclass AS | |
79 | -$$ | |
80 | -DECLARE | |
81 | - restore_id int8; | |
82 | - restore_relid regclass; | |
83 | - restore_attnum int2; | |
84 | - set_attnum int2; | |
85 | - restore_attname text; | |
86 | - restore_type regtype; | |
87 | - cur_type regtype; | |
88 | -BEGIN | |
89 | - IF $1 IS NULL THEN | |
90 | - RAISE EXCEPTION 'backup id required'; | |
91 | - END IF; | |
92 | - IF $2 IS NULL AND $3 IS NOT NULL THEN | |
93 | - RAISE EXCEPTION 'relation required'; | |
94 | - END IF; | |
95 | - IF NOT EXISTS(SELECT * FROM dbms_stats.backup_history | |
96 | - WHERE id <= $1 FOR SHARE) THEN | |
97 | - RAISE EXCEPTION 'backup id % not found', $1; | |
98 | - END IF; | |
99 | - IF $2 IS NOT NULL THEN | |
100 | - IF NOT EXISTS(SELECT * FROM pg_catalog.pg_class | |
101 | - WHERE oid = $2 FOR SHARE) THEN | |
102 | - RAISE EXCEPTION 'relation "%" not found', $2; | |
103 | - END IF; | |
104 | - -- Grabbing all backups for the relation which is not used in restore. | |
105 | - IF NOT EXISTS(SELECT * FROM dbms_stats.relation_stats_backup b | |
106 | - WHERE b.id <= $1 AND b.relid = $2 FOR SHARE) THEN | |
107 | - RAISE EXCEPTION 'statistics of relation "%" not found in any backups before backup id = %', $2, $1; | |
108 | - END IF; | |
109 | - IF $3 IS NOT NULL THEN | |
110 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
111 | - WHERE a.attrelid = $2 AND a.attname = $3; | |
112 | - IF set_attnum IS NULL THEN | |
113 | - RAISE EXCEPTION 'column "%" not found in relation %', $3, $2; | |
114 | - END IF; | |
115 | - IF NOT EXISTS(SELECT * FROM dbms_stats.column_stats_backup WHERE id <= $1 AND starelid = $2 AND staattnum = set_attnum) THEN | |
116 | - RAISE EXCEPTION 'statistics of column "%" of relation "%" are not found in any backups before backup id = %',$3, $2, $1; | |
117 | - END IF; | |
118 | - END IF; | |
119 | - PERFORM * FROM dbms_stats.relation_stats_locked r | |
120 | - WHERE r.relid = $2 FOR UPDATE; | |
121 | - ELSE | |
122 | - /* Lock the whole relation stats if relation is not specified.*/ | |
123 | - LOCK dbms_stats.relation_stats_locked IN EXCLUSIVE MODE; | |
124 | - END IF; | |
125 | - | |
126 | - FOR restore_id, restore_relid IN | |
127 | - SELECT max(id), coid FROM | |
128 | - (SELECT b.id as id, c.oid as coid | |
129 | - FROM pg_class c, dbms_stats.relation_stats_backup b | |
130 | - WHERE (c.oid = $2 OR $2 IS NULL) | |
131 | - AND c.oid = b.relid | |
132 | - AND dbms_stats.is_target_relkind(c.relkind) | |
133 | - AND NOT dbms_stats.is_system_catalog(c.oid) | |
134 | - AND b.id <= $1 | |
135 | - FOR SHARE) t | |
136 | - GROUP BY coid | |
137 | - ORDER BY coid::regclass::text | |
138 | - LOOP | |
139 | - UPDATE dbms_stats.relation_stats_locked r | |
140 | - SET relid = b.relid, | |
141 | - relname = b.relname, | |
142 | - relpages = b.relpages, | |
143 | - reltuples = b.reltuples, | |
144 | - relallvisible = b.relallvisible, | |
145 | - curpages = b.curpages, | |
146 | - last_analyze = b.last_analyze, | |
147 | - last_autoanalyze = b.last_autoanalyze | |
148 | - FROM dbms_stats.relation_stats_backup b | |
149 | - WHERE r.relid = restore_relid | |
150 | - AND b.id = restore_id | |
151 | - AND b.relid = restore_relid; | |
152 | - IF NOT FOUND THEN | |
153 | - INSERT INTO dbms_stats.relation_stats_locked | |
154 | - SELECT b.relid, | |
155 | - b.relname, | |
156 | - b.relpages, | |
157 | - b.reltuples, | |
158 | - b.relallvisible, | |
159 | - b.curpages, | |
160 | - b.last_analyze, | |
161 | - b.last_autoanalyze | |
162 | - FROM dbms_stats.relation_stats_backup b | |
163 | - WHERE b.id = restore_id | |
164 | - AND b.relid = restore_relid; | |
165 | - END IF; | |
166 | - RETURN NEXT restore_relid; | |
167 | - END LOOP; | |
168 | - | |
169 | - FOR restore_id, restore_relid, restore_attnum, restore_type, cur_type IN | |
170 | - SELECT t.id, t.oid, t.attnum, b.statypid, a.atttypid | |
171 | - FROM pg_attribute a, | |
172 | - dbms_stats.column_stats_backup b, | |
173 | - (SELECT max(b.id) AS id, c.oid, a.attnum | |
174 | - FROM pg_class c, pg_attribute a, dbms_stats.column_stats_backup b | |
175 | - WHERE (c.oid = $2 OR $2 IS NULL) | |
176 | - AND c.oid = a.attrelid | |
177 | - AND c.oid = b.starelid | |
178 | - AND (a.attnum = set_attnum OR set_attnum IS NULL) | |
179 | - AND a.attnum = b.staattnum | |
180 | - AND NOT a.attisdropped | |
181 | - AND dbms_stats.is_target_relkind(c.relkind) | |
182 | - AND b.id <= $1 | |
183 | - GROUP BY c.oid, a.attnum) t | |
184 | - WHERE a.attrelid = t.oid | |
185 | - AND a.attnum = t.attnum | |
186 | - AND b.id = t.id | |
187 | - AND b.starelid = t.oid | |
188 | - AND b.staattnum = t.attnum | |
189 | - LOOP | |
190 | - IF restore_type <> cur_type THEN | |
191 | - SELECT a.attname INTO restore_attname | |
192 | - FROM pg_catalog.pg_attribute a | |
193 | - WHERE a.attrelid = restore_relid | |
194 | - AND a.attnum = restore_attnum; | |
195 | - RAISE WARNING 'data type of column "%.%" is inconsistent between database(%) and backup (%). Skip.', | |
196 | - restore_relid, restore_attname, cur_type, restore_type; | |
197 | - ELSE | |
198 | - DELETE FROM dbms_stats.column_stats_locked | |
199 | - WHERE starelid = restore_relid | |
200 | - AND staattnum = restore_attnum; | |
201 | - INSERT INTO dbms_stats.column_stats_locked | |
202 | - SELECT starelid, staattnum, stainherit, | |
203 | - stanullfrac, stawidth, stadistinct, | |
204 | - stakind1, stakind2, stakind3, stakind4, stakind5, | |
205 | - staop1, staop2, staop3, staop4, staop5, | |
206 | - stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, | |
207 | - stavalues1, stavalues2, stavalues3, stavalues4, stavalues5 | |
208 | - FROM dbms_stats.column_stats_backup | |
209 | - WHERE id = restore_id | |
210 | - AND starelid = restore_relid | |
211 | - AND staattnum = restore_attnum; | |
212 | - END IF; | |
213 | - END LOOP; | |
214 | -EXCEPTION | |
215 | - WHEN unique_violation THEN | |
216 | - RAISE EXCEPTION 'This operation is canceled by simultaneous lock or restore operation on the same relation.'; | |
217 | -END; | |
218 | -$$ | |
219 | -LANGUAGE plpgsql; | |
220 | - | |
221 | -CREATE OR REPLACE FUNCTION dbms_stats.restore_stats( | |
222 | - backup_id int8 | |
223 | -) RETURNS SETOF regclass AS | |
224 | -$$ | |
225 | -DECLARE | |
226 | - restore_relid regclass; | |
227 | - restore_attnum int2; | |
228 | - restore_attname text; | |
229 | - restore_type regtype; | |
230 | - cur_type regtype; | |
231 | -BEGIN | |
232 | - IF NOT EXISTS(SELECT * FROM dbms_stats.backup_history WHERE id = $1) THEN | |
233 | - RAISE EXCEPTION 'backup id % not found', $1; | |
234 | - END IF; | |
235 | - | |
236 | - /* Lock the backup */ | |
237 | - PERFORM * from dbms_stats.relation_stats_backup b | |
238 | - WHERE id = $1 FOR SHARE; | |
239 | - | |
240 | - /* Locking only _relation_stats_locked is sufficient */ | |
241 | - LOCK dbms_stats.relation_stats_locked IN EXCLUSIVE MODE; | |
242 | - | |
243 | - FOR restore_relid IN | |
244 | - SELECT b.relid | |
245 | - FROM pg_class c | |
246 | - JOIN dbms_stats.relation_stats_backup b ON (c.oid = b.relid) | |
247 | - WHERE b.id = $1 | |
248 | - ORDER BY c.oid::regclass::text | |
249 | - LOOP | |
250 | - UPDATE dbms_stats.relation_stats_locked r | |
251 | - SET relid = b.relid, | |
252 | - relname = b.relname, | |
253 | - relpages = b.relpages, | |
254 | - reltuples = b.reltuples, | |
255 | - relallvisible = b.relallvisible, | |
256 | - curpages = b.curpages, | |
257 | - last_analyze = b.last_analyze, | |
258 | - last_autoanalyze = b.last_autoanalyze | |
259 | - FROM dbms_stats.relation_stats_backup b | |
260 | - WHERE r.relid = restore_relid | |
261 | - AND b.id = $1 | |
262 | - AND b.relid = restore_relid; | |
263 | - IF NOT FOUND THEN | |
264 | - INSERT INTO dbms_stats.relation_stats_locked | |
265 | - SELECT b.relid, | |
266 | - b.relname, | |
267 | - b.relpages, | |
268 | - b.reltuples, | |
269 | - b.relallvisible, | |
270 | - b.curpages, | |
271 | - b.last_analyze, | |
272 | - b.last_autoanalyze | |
273 | - FROM dbms_stats.relation_stats_backup b | |
274 | - WHERE b.id = $1 | |
275 | - AND b.relid = restore_relid; | |
276 | - END IF; | |
277 | - RETURN NEXT restore_relid; | |
278 | - END LOOP; | |
279 | - | |
280 | - FOR restore_relid, restore_attnum, restore_type, cur_type IN | |
281 | - SELECT c.oid, a.attnum, b.statypid, a.atttypid | |
282 | - FROM pg_class c | |
283 | - JOIN dbms_stats.column_stats_backup b ON (c.oid = b.starelid) | |
284 | - JOIN pg_attribute a ON (b.starelid = attrelid | |
285 | - AND b.staattnum = a.attnum) | |
286 | - WHERE b.id = $1 | |
287 | - LOOP | |
288 | - IF restore_type <> cur_type THEN | |
289 | - SELECT attname INTO restore_attname | |
290 | - FROM pg_catalog.pg_attribute | |
291 | - WHERE attrelid = restore_relid | |
292 | - AND attnum = restore_attnum; | |
293 | - RAISE WARNING 'data type of column "%.%" is inconsistent between database(%) and backup (%). Skip.', | |
294 | - restore_relid, restore_attname, cur_type, restore_type; | |
295 | - ELSE | |
296 | - DELETE FROM dbms_stats.column_stats_locked | |
297 | - WHERE starelid = restore_relid | |
298 | - AND staattnum = restore_attnum; | |
299 | - INSERT INTO dbms_stats.column_stats_locked | |
300 | - SELECT starelid, staattnum, stainherit, | |
301 | - stanullfrac, stawidth, stadistinct, | |
302 | - stakind1, stakind2, stakind3, stakind4, stakind5, | |
303 | - staop1, staop2, staop3, staop4, staop5, | |
304 | - stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, | |
305 | - stavalues1, stavalues2, stavalues3, stavalues4, stavalues5 | |
306 | - FROM dbms_stats.column_stats_backup | |
307 | - WHERE id = $1 | |
308 | - AND starelid = restore_relid | |
309 | - AND staattnum = restore_attnum; | |
310 | - END IF; | |
311 | - END LOOP; | |
312 | - | |
313 | -END; | |
314 | -$$ | |
315 | -LANGUAGE plpgsql STRICT; | |
316 | - | |
317 | -CREATE OR REPLACE FUNCTION dbms_stats.lock( | |
318 | - relid regclass, | |
319 | - attname text | |
320 | -) RETURNS regclass AS | |
321 | -$$ | |
322 | -DECLARE | |
323 | - lock_relkind "char"; | |
324 | - set_attnum int2; | |
325 | - r record; | |
326 | -BEGIN | |
327 | - IF $1 IS NULL THEN | |
328 | - RAISE EXCEPTION 'relation required'; | |
329 | - END IF; | |
330 | - IF $2 IS NULL THEN | |
331 | - RETURN dbms_stats.lock($1); | |
332 | - END IF; | |
333 | - SELECT relkind INTO lock_relkind FROM pg_catalog.pg_class WHERE oid = $1; | |
334 | - IF NOT FOUND THEN | |
335 | - RAISE EXCEPTION 'relation "%" not found', $1; | |
336 | - END IF; | |
337 | - IF NOT dbms_stats.is_target_relkind(lock_relkind) THEN | |
338 | - RAISE EXCEPTION '"%" must be a table or an index', $1; | |
339 | - END IF; | |
340 | - IF EXISTS(SELECT * FROM pg_catalog.pg_index WHERE lock_relkind = 'i' AND indexrelid = $1 AND indexprs IS NULL) THEN | |
341 | - RAISE EXCEPTION '"%" must be an expression index', $1; | |
342 | - END IF; | |
343 | - IF dbms_stats.is_system_catalog($1) THEN | |
344 | - RAISE EXCEPTION 'locking statistics is inhibited for system catalogs: "%"', $1; | |
345 | - END IF; | |
346 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
347 | - WHERE a.attrelid = $1 AND a.attname = $2; | |
348 | - IF set_attnum IS NULL THEN | |
349 | - RAISE EXCEPTION 'column "%" not found in relation "%"', $2, $1; | |
350 | - END IF; | |
351 | - | |
352 | - /* | |
353 | - * If we don't have per-table statistics, create new one which has NULL for | |
354 | - * every statistic value for column_stats_effective. | |
355 | - */ | |
356 | - IF NOT EXISTS(SELECT * FROM dbms_stats.relation_stats_locked ru | |
357 | - WHERE ru.relid = $1 FOR SHARE) THEN | |
358 | - INSERT INTO dbms_stats.relation_stats_locked | |
359 | - SELECT $1, dbms_stats.relname(nspname, relname), | |
360 | - NULL, NULL, NULL, NULL, NULL | |
361 | - FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n | |
362 | - WHERE c.relnamespace = n.oid | |
363 | - AND c.oid = $1; | |
364 | - END IF; | |
365 | - | |
366 | - /* | |
367 | - * Process for per-column statistics | |
368 | - */ | |
369 | - FOR r IN | |
370 | - SELECT stainherit, stanullfrac, stawidth, stadistinct, | |
371 | - stakind1, stakind2, stakind3, stakind4, stakind5, | |
372 | - staop1, staop2, staop3, staop4, staop5, | |
373 | - stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, | |
374 | - stavalues1, stavalues2, stavalues3, stavalues4, stavalues5 | |
375 | - FROM dbms_stats.column_stats_effective | |
376 | - WHERE starelid = $1 | |
377 | - AND staattnum = set_attnum | |
378 | - LOOP | |
379 | - UPDATE dbms_stats.column_stats_locked c | |
380 | - SET stanullfrac = r.stanullfrac, | |
381 | - stawidth = r.stawidth, | |
382 | - stadistinct = r.stadistinct, | |
383 | - stakind1 = r.stakind1, | |
384 | - stakind2 = r.stakind2, | |
385 | - stakind3 = r.stakind3, | |
386 | - stakind4 = r.stakind4, | |
387 | - stakind5 = r.stakind5, | |
388 | - staop1 = r.staop1, | |
389 | - staop2 = r.staop2, | |
390 | - staop3 = r.staop3, | |
391 | - staop4 = r.staop4, | |
392 | - staop5 = r.staop5, | |
393 | - stanumbers1 = r.stanumbers1, | |
394 | - stanumbers2 = r.stanumbers2, | |
395 | - stanumbers3 = r.stanumbers3, | |
396 | - stanumbers4 = r.stanumbers4, | |
397 | - stanumbers5 = r.stanumbers5, | |
398 | - stavalues1 = r.stavalues1, | |
399 | - stavalues2 = r.stavalues2, | |
400 | - stavalues3 = r.stavalues3, | |
401 | - stavalues4 = r.stavalues4, | |
402 | - stavalues5 = r.stavalues5 | |
403 | - WHERE c.starelid = $1 | |
404 | - AND c.staattnum = set_attnum | |
405 | - AND c.stainherit = r.stainherit; | |
406 | - | |
407 | - IF NOT FOUND THEN | |
408 | - INSERT INTO dbms_stats.column_stats_locked | |
409 | - VALUES ($1, | |
410 | - set_attnum, | |
411 | - r.stainherit, | |
412 | - r.stanullfrac, | |
413 | - r.stawidth, | |
414 | - r.stadistinct, | |
415 | - r.stakind1, | |
416 | - r.stakind2, | |
417 | - r.stakind3, | |
418 | - r.stakind4, | |
419 | - r.stakind5, | |
420 | - r.staop1, | |
421 | - r.staop2, | |
422 | - r.staop3, | |
423 | - r.staop4, | |
424 | - r.staop5, | |
425 | - r.stanumbers1, | |
426 | - r.stanumbers2, | |
427 | - r.stanumbers3, | |
428 | - r.stanumbers4, | |
429 | - r.stanumbers5, | |
430 | - r.stavalues1, | |
431 | - r.stavalues2, | |
432 | - r.stavalues3, | |
433 | - r.stavalues4, | |
434 | - r.stavalues5); | |
435 | - END IF; | |
436 | - END LOOP; | |
437 | - | |
438 | - /* If we don't have statistics at all, raise error. */ | |
439 | - IF NOT FOUND THEN | |
440 | - RAISE EXCEPTION 'no statistics available for column "%" of relation "%"', $2, $1::regclass; | |
441 | - END IF; | |
442 | - | |
443 | - RETURN $1; | |
444 | -EXCEPTION | |
445 | - WHEN unique_violation THEN | |
446 | - RAISE EXCEPTION 'This operation is canceled by simultaneous lock or restore operation on the same relation.'; | |
447 | -END; | |
448 | -$$ | |
449 | -LANGUAGE plpgsql; | |
450 | - | |
451 | -CREATE OR REPLACE FUNCTION dbms_stats.lock(relid regclass) | |
452 | - RETURNS regclass AS | |
453 | -$$ | |
454 | -DECLARE | |
455 | - lock_relkind "char"; | |
456 | - i record; | |
457 | -BEGIN | |
458 | - IF $1 IS NULL THEN | |
459 | - RAISE EXCEPTION 'relation required'; | |
460 | - END IF; | |
461 | - SELECT relkind INTO lock_relkind FROM pg_catalog.pg_class WHERE oid = $1; | |
462 | - IF NOT FOUND THEN | |
463 | - RAISE EXCEPTION 'relation "%" not found', $1; | |
464 | - END IF; | |
465 | - IF NOT dbms_stats.is_target_relkind(lock_relkind) THEN | |
466 | - RAISE EXCEPTION 'locking statistics is not allowed for relations with relkind "%": "%"', lock_relkind, $1 | |
467 | - USING HINT = 'Only tables(r, m, f) and indexes(i) are lockable.'; | |
468 | - END IF; | |
469 | - IF dbms_stats.is_system_catalog($1) THEN | |
470 | - RAISE EXCEPTION 'locking statistics is not allowed for system catalogs: "%"', $1; | |
471 | - END IF; | |
472 | - | |
473 | - UPDATE dbms_stats.relation_stats_locked r | |
474 | - SET relname = dbms_stats.relname(nspname, c.relname), | |
475 | - relpages = v.relpages, | |
476 | - reltuples = v.reltuples, | |
477 | - relallvisible = v.relallvisible, | |
478 | - curpages = v.curpages, | |
479 | - last_analyze = v.last_analyze, | |
480 | - last_autoanalyze = v.last_autoanalyze | |
481 | - FROM pg_catalog.pg_class c, | |
482 | - pg_catalog.pg_namespace n, | |
483 | - dbms_stats.relation_stats_effective v | |
484 | - WHERE r.relid = $1 | |
485 | - AND c.oid = $1 | |
486 | - AND c.relnamespace = n.oid | |
487 | - AND v.relid = $1; | |
488 | - IF NOT FOUND THEN | |
489 | - INSERT INTO dbms_stats.relation_stats_locked | |
490 | - SELECT $1, dbms_stats.relname(nspname, c.relname), | |
491 | - v.relpages, v.reltuples, v.relallvisible, v.curpages, | |
492 | - v.last_analyze, v.last_autoanalyze | |
493 | - FROM pg_catalog.pg_class c, | |
494 | - pg_catalog.pg_namespace n, | |
495 | - dbms_stats.relation_stats_effective v | |
496 | - WHERE c.oid = $1 | |
497 | - AND c.relnamespace = n.oid | |
498 | - AND v.relid = $1; | |
499 | - END IF; | |
500 | - | |
501 | - IF EXISTS(SELECT * | |
502 | - FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index ind | |
503 | - ON c.oid = ind.indexrelid | |
504 | - WHERE c.oid = $1 | |
505 | - AND c.relkind = 'i' | |
506 | - AND ind.indexprs IS NULL) THEN | |
507 | - RETURN $1; | |
508 | - END IF; | |
509 | - | |
510 | - FOR i IN | |
511 | - SELECT staattnum, stainherit, stanullfrac, | |
512 | - stawidth, stadistinct, | |
513 | - stakind1, stakind2, stakind3, stakind4, stakind5, | |
514 | - staop1, staop2, staop3, staop4, staop5, | |
515 | - stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, | |
516 | - stavalues1, stavalues2, stavalues3, stavalues4, stavalues5 | |
517 | - FROM dbms_stats.column_stats_effective | |
518 | - WHERE starelid = $1 | |
519 | - LOOP | |
520 | - UPDATE dbms_stats.column_stats_locked c | |
521 | - SET stanullfrac = i.stanullfrac, | |
522 | - stawidth = i.stawidth, | |
523 | - stadistinct = i.stadistinct, | |
524 | - stakind1 = i.stakind1, | |
525 | - stakind2 = i.stakind2, | |
526 | - stakind3 = i.stakind3, | |
527 | - stakind4 = i.stakind4, | |
528 | - stakind5 = i.stakind5, | |
529 | - staop1 = i.staop1, | |
530 | - staop2 = i.staop2, | |
531 | - staop3 = i.staop3, | |
532 | - staop4 = i.staop4, | |
533 | - staop5 = i.staop5, | |
534 | - stanumbers1 = i.stanumbers1, | |
535 | - stanumbers2 = i.stanumbers2, | |
536 | - stanumbers3 = i.stanumbers3, | |
537 | - stanumbers4 = i.stanumbers4, | |
538 | - stanumbers5 = i.stanumbers5, | |
539 | - stavalues1 = i.stavalues1, | |
540 | - stavalues2 = i.stavalues2, | |
541 | - stavalues3 = i.stavalues3, | |
542 | - stavalues4 = i.stavalues4, | |
543 | - stavalues5 = i.stavalues5 | |
544 | - WHERE c.starelid = $1 | |
545 | - AND c.staattnum = i.staattnum | |
546 | - AND c.stainherit = i.stainherit; | |
547 | - | |
548 | - IF NOT FOUND THEN | |
549 | - INSERT INTO dbms_stats.column_stats_locked | |
550 | - VALUES ($1, | |
551 | - i.staattnum, | |
552 | - i.stainherit, | |
553 | - i.stanullfrac, | |
554 | - i.stawidth, | |
555 | - i.stadistinct, | |
556 | - i.stakind1, | |
557 | - i.stakind2, | |
558 | - i.stakind3, | |
559 | - i.stakind4, | |
560 | - i.stakind5, | |
561 | - i.staop1, | |
562 | - i.staop2, | |
563 | - i.staop3, | |
564 | - i.staop4, | |
565 | - i.staop5, | |
566 | - i.stanumbers1, | |
567 | - i.stanumbers2, | |
568 | - i.stanumbers3, | |
569 | - i.stanumbers4, | |
570 | - i.stanumbers5, | |
571 | - i.stavalues1, | |
572 | - i.stavalues2, | |
573 | - i.stavalues3, | |
574 | - i.stavalues4, | |
575 | - i.stavalues5); | |
576 | - END IF; | |
577 | - END LOOP; | |
578 | - | |
579 | - RETURN $1; | |
580 | -EXCEPTION | |
581 | - WHEN unique_violation THEN | |
582 | - RAISE EXCEPTION 'This operation is canceled by simultaneous lock operation on the same relation.'; | |
583 | -END; | |
584 | -$$ | |
585 | -LANGUAGE plpgsql; | |
586 | - | |
587 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock( | |
588 | - relid regclass DEFAULT NULL, | |
589 | - attname text DEFAULT NULL | |
590 | -) RETURNS SETOF regclass AS | |
591 | -$$ | |
592 | -DECLARE | |
593 | - set_attnum int2; | |
594 | - unlock_id int8; | |
595 | -BEGIN | |
596 | - IF $1 IS NULL AND $2 IS NOT NULL THEN | |
597 | - RAISE EXCEPTION 'relation required'; | |
598 | - END IF; | |
599 | - | |
600 | - /* | |
601 | - * Lock the target relation to prevent conflicting with stats lock/restore | |
602 | - */ | |
603 | - PERFORM * FROM dbms_stats.relation_stats_locked ru | |
604 | - WHERE (ru.relid = $1 OR $1 IS NULL) FOR UPDATE; | |
605 | - | |
606 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
607 | - WHERE a.attrelid = $1 AND a.attname = $2; | |
608 | - IF $2 IS NOT NULL AND set_attnum IS NULL THEN | |
609 | - RAISE EXCEPTION 'column "%" not found in relation "%"', $2, $1; | |
610 | - END IF; | |
611 | - | |
612 | - DELETE FROM dbms_stats.column_stats_locked | |
613 | - WHERE (starelid = $1 OR $1 IS NULL) | |
614 | - AND (staattnum = set_attnum OR $2 IS NULL); | |
615 | - | |
616 | - IF $1 IS NOT NULL AND $2 IS NOT NULL THEN | |
617 | - RETURN QUERY | |
618 | - SELECT $1; | |
619 | - END IF; | |
620 | - FOR unlock_id IN | |
621 | - SELECT ru.relid | |
622 | - FROM dbms_stats.relation_stats_locked ru | |
623 | - WHERE (ru.relid = $1 OR $1 IS NULL) AND ($2 IS NULL) | |
624 | - ORDER BY ru.relid | |
625 | - LOOP | |
626 | - DELETE FROM dbms_stats.relation_stats_locked ru | |
627 | - WHERE ru.relid = unlock_id; | |
628 | - RETURN NEXT unlock_id; | |
629 | - END LOOP; | |
630 | -END; | |
631 | -$$ | |
632 | -LANGUAGE plpgsql; | |
633 | - | |
634 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_database_stats() | |
635 | - RETURNS SETOF regclass AS | |
636 | -$$ | |
637 | -DECLARE | |
638 | - unlock_id int8; | |
639 | -BEGIN | |
640 | - LOCK dbms_stats.relation_stats_locked IN EXCLUSIVE MODE; | |
641 | - | |
642 | - FOR unlock_id IN | |
643 | - SELECT relid | |
644 | - FROM dbms_stats.relation_stats_locked | |
645 | - ORDER BY relid | |
646 | - LOOP | |
647 | - DELETE FROM dbms_stats.relation_stats_locked | |
648 | - WHERE relid = unlock_id; | |
649 | - RETURN NEXT unlock_id; | |
650 | - END LOOP; | |
651 | -END; | |
652 | -$$ | |
653 | -LANGUAGE plpgsql STRICT; | |
654 | - | |
655 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_schema_stats( | |
656 | - schemaname text | |
657 | -) RETURNS SETOF regclass AS | |
658 | -$$ | |
659 | -DECLARE | |
660 | - unlock_id int8; | |
661 | -BEGIN | |
662 | - IF NOT EXISTS(SELECT * FROM pg_namespace WHERE nspname = $1) THEN | |
663 | - RAISE EXCEPTION 'schema "%" not found', $1; | |
664 | - END IF; | |
665 | - IF dbms_stats.is_system_schema($1) THEN | |
666 | - RAISE EXCEPTION 'unlocking statistics is not allowed for system schemas: "%"', $1; | |
667 | - END IF; | |
668 | - | |
669 | - FOR unlock_id IN | |
670 | - SELECT r.relid | |
671 | - FROM dbms_stats.relation_stats_locked r, pg_class c, pg_namespace n | |
672 | - WHERE relid = c.oid | |
673 | - AND c.relnamespace = n.oid | |
674 | - AND n.nspname = $1 | |
675 | - ORDER BY relid | |
676 | - FOR UPDATE | |
677 | - LOOP | |
678 | - DELETE FROM dbms_stats.relation_stats_locked | |
679 | - WHERE relid = unlock_id; | |
680 | - RETURN NEXT unlock_id; | |
681 | - END LOOP; | |
682 | -END; | |
683 | -$$ | |
684 | -LANGUAGE plpgsql STRICT; | |
685 | - | |
686 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_table_stats(relid regclass) | |
687 | - RETURNS SETOF regclass AS | |
688 | -$$ | |
689 | -DELETE FROM dbms_stats.relation_stats_locked | |
690 | - WHERE relid = $1 | |
691 | - RETURNING relid::regclass | |
692 | -$$ | |
693 | -LANGUAGE sql STRICT; | |
694 | - | |
695 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_table_stats( | |
696 | - schemaname text, | |
697 | - tablename text | |
698 | -) RETURNS SETOF regclass AS | |
699 | -$$ | |
700 | -DELETE FROM dbms_stats.relation_stats_locked | |
701 | - WHERE relid = dbms_stats.relname($1, $2)::regclass | |
702 | - RETURNING relid::regclass | |
703 | -$$ | |
704 | -LANGUAGE sql STRICT; | |
705 | - | |
706 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_column_stats( | |
707 | - relid regclass, | |
708 | - attname text | |
709 | -) RETURNS SETOF regclass AS | |
710 | -$$ | |
711 | -DECLARE | |
712 | - set_attnum int2; | |
713 | -BEGIN | |
714 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
715 | - WHERE a.attrelid = $1 AND a.attname = $2; | |
716 | - IF $2 IS NOT NULL AND set_attnum IS NULL THEN | |
717 | - RAISE EXCEPTION 'column "%" not found in relation "%"', $2, $1; | |
718 | - END IF; | |
719 | - | |
720 | - /* Lock the locked table stats */ | |
721 | - PERFORM * from dbms_stats.relation_stats_locked r | |
722 | - WHERE r.relid = $1 FOR SHARE; | |
723 | - | |
724 | - DELETE FROM dbms_stats.column_stats_locked | |
725 | - WHERE starelid = $1 | |
726 | - AND staattnum = set_attnum; | |
727 | - | |
728 | - RETURN QUERY | |
729 | - SELECT $1; | |
730 | -END; | |
731 | -$$ | |
732 | -LANGUAGE plpgsql STRICT; | |
733 | - | |
734 | -CREATE OR REPLACE FUNCTION dbms_stats.unlock_column_stats( | |
735 | - schemaname text, | |
736 | - tablename text, | |
737 | - attname text | |
738 | -) RETURNS SETOF regclass AS | |
739 | -$$ | |
740 | -DECLARE | |
741 | - set_attnum int2; | |
742 | -BEGIN | |
743 | - SELECT a.attnum INTO set_attnum FROM pg_catalog.pg_attribute a | |
744 | - WHERE a.attrelid = dbms_stats.relname($1, $2)::regclass | |
745 | - AND a.attname = $3; | |
746 | - IF $3 IS NOT NULL AND set_attnum IS NULL THEN | |
747 | - RAISE EXCEPTION 'column "%" not found in relation "%.%"', $3, $1, $2; | |
748 | - END IF; | |
749 | - | |
750 | - /* Lock the locked table stats */ | |
751 | - PERFORM * from dbms_stats.relation_stats_locked r | |
752 | - WHERE relid = dbms_stats.relname($1, $2)::regclass FOR SHARE; | |
753 | - | |
754 | - DELETE FROM dbms_stats.column_stats_locked | |
755 | - WHERE starelid = dbms_stats.relname($1, $2)::regclass | |
756 | - AND staattnum = set_attnum; | |
757 | - | |
758 | - RETURN QUERY | |
759 | - SELECT dbms_stats.relname($1, $2)::regclass; | |
760 | -END; | |
761 | -$$ | |
762 | -LANGUAGE plpgsql STRICT; | |
763 | - | |
764 | -CREATE OR REPLACE FUNCTION dbms_stats.clean_up_stats() RETURNS SETOF text AS | |
765 | -$$ | |
766 | -DECLARE | |
767 | - clean_relid Oid; | |
768 | - clean_attnum int2; | |
769 | - clean_inherit bool; | |
770 | - clean_rel_col text; | |
771 | -BEGIN | |
772 | - -- We don't have to check that table-level dummy statistics of the table | |
773 | - -- exists here, because the foreign key constraints defined on column-level | |
774 | - -- dummy static table ensures that. | |
775 | - FOR clean_rel_col, clean_relid, clean_attnum, clean_inherit IN | |
776 | - SELECT r.relname || ', ' || v.staattnum::text, | |
777 | - v.starelid, v.staattnum, v.stainherit | |
778 | - FROM dbms_stats.column_stats_locked v | |
779 | - JOIN dbms_stats.relation_stats_locked r ON (v.starelid = r.relid) | |
780 | - WHERE NOT EXISTS ( | |
781 | - SELECT NULL | |
782 | - FROM pg_attribute a | |
783 | - WHERE a.attrelid = v.starelid | |
784 | - AND a.attnum = v.staattnum | |
785 | - AND a.attisdropped = false | |
786 | - FOR UPDATE | |
787 | - ) | |
788 | - LOOP | |
789 | - DELETE FROM dbms_stats.column_stats_locked | |
790 | - WHERE starelid = clean_relid | |
791 | - AND staattnum = clean_attnum | |
792 | - AND stainherit = clean_inherit; | |
793 | - RETURN NEXT clean_rel_col; | |
794 | - END LOOP; | |
795 | - | |
796 | - RETURN QUERY | |
797 | - DELETE FROM dbms_stats.relation_stats_locked r | |
798 | - WHERE NOT EXISTS ( | |
799 | - SELECT NULL | |
800 | - FROM pg_class c | |
801 | - WHERE c.oid = r.relid) | |
802 | - RETURNING relname || ','; | |
803 | - RETURN; | |
804 | -END | |
805 | -$$ | |
806 | -LANGUAGE plpgsql; | |
807 | - | |
808 | - | |
809 | -REVOKE SELECT ON dbms_stats.stats FROM PUBLIC; | |
810 | -REVOKE USAGE ON schema dbms_stats FROM PUBLIC; |
@@ -1,4 +0,0 @@ | ||
1 | -/* pg_dbms_stats/pg_dbms_stats--1.3.5--1.3.6.sql */ | |
2 | - | |
3 | --- complain if script is sourced in psql, rather than via CREATE EXTENSION | |
4 | -\echo Use "ALTER EXTENSION pg_dbms_stats UPDATE TO '1.3.6'" to load this file. \quit |