• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisionc45371c527de71c2c19bf1c808e8819b15b86ac0 (tree)
Time2016-01-15 16:50:08
AuthorKyotaro Horiguchi <horiguchi.kyotaro@lab....>
CommiterKyotaro Horiguchi

Log Message

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.

Change Summary

  • modified: Makefile (diff)
  • delete: ext_scripts/pg_dbms_stats--1.0--1.3.2-9.4.sql
  • delete: ext_scripts/pg_dbms_stats--1.3.2--1.3.3-9.4.sql
  • delete: ext_scripts/pg_dbms_stats--1.3.3--1.3.4-9.4.sql
  • delete: ext_scripts/pg_dbms_stats--1.3.4--1.3.5-9.4.sql
  • delete: ext_scripts/pg_dbms_stats--1.3.5--1.3.6-9.4.sql

Incremental Difference

--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,11 @@
11 # pg_dbms_stats/Makefile
22
3+DBMSSTATSVER = 1.3.6
4+PGVERS = 91 92 93 94
5+IS_PRE_95 = $(filter 0,$(shell test "$(MAJORVERSION)" \< "9.5"; echo $$?))
6+
37 MODULE_big = pg_dbms_stats
48 OBJS = pg_dbms_stats.o dump.o import.o
5-DBMSSTATSVER = 1.3.6
69 DOCDIR = doc
710 EXTDIR = ext_scripts
811
@@ -12,7 +15,6 @@ endif
1215
1316 LAST_LIBPATH=$(shell echo $(LD_LIBRARY_PATH) | sed -e "s/^.*;//")
1417 CHECKING=$(shell echo $(LAST_LIBPATH)| grep './tmp_check/install/' | wc -l)
15-
1618 EXTENSION = pg_dbms_stats
1719
1820 REGRESS = init-common ut_fdw_init init-$(REGTESTVER) ut-common \
@@ -20,19 +22,20 @@ REGRESS = init-common ut_fdw_init init-$(REGTESTVER) ut-common \
2022 EXTRA_INSTALL = contrib/file_fdw
2123
2224 # 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))
2426
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))))
2629
2730 DOCS = $(DOCDIR)/export_effective_stats-$(MAJORVERSION).sql.sample \
2831 $(DOCDIR)/export_plain_stats-$(MAJORVERSION).sql.sample
2932
33+# Source tarballs required for rpmbuild
3034 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))
3639
3740 EXTRA_CLEAN = sql/ut_anyarray-*.sql expected/ut_anyarray-*.out \
3841 sql/ut_imp_exp-*.sql expected/ut_imp_exp-*.out \
@@ -57,8 +60,8 @@ include $(top_builddir)/src/Makefile.global
5760 include $(top_srcdir)/contrib/contrib-global.mk
5861 endif
5962
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)
6265
6366 TARSOURCES = Makefile *.c *.h \
6467 $(EXTDIR)/pg_dbms_stats--*-9.*.sql \
@@ -70,13 +73,16 @@ TARSOURCES = Makefile *.c *.h \
7073
7174 all: $(DATA) $(DOCS)
7275
73-rpms: rpm94 rpm93 rpm92 rpm91
76+rpms: $(RPMS)
7477
7578 sourcetar: $(STARBALL)
7679
77-$(DATA): %.sql: $(EXTDIR)/%-$(REGTESTVER).sql
80+$(DATA): %.sql: $(EXTDIR)/%-$(MAJORVERSION).sql
7881 cp $< $@
7982
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.
8086 $(STARBALLS): $(TARSOURCES)
8187 if [ -h $(subst .tar.gz,,$@) ]; then rm $(subst .tar.gz,,$@); fi
8288 if [ -e $(subst .tar.gz,,$@) ]; then \
@@ -87,14 +93,6 @@ $(STARBALLS): $(TARSOURCES)
8793 tar -chzf $@ $(addprefix $(subst .tar.gz,,$@)/, $^)
8894 rm $(subst .tar.gz,,$@)
8995
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 $<
9898
99-rpm91: $(STARBALL91)
100- MAKE_ROOT=`pwd` rpmbuild -bb SPECS/pg_dbms_stats91.spec
--- a/ext_scripts/pg_dbms_stats--1.0--1.3.2-9.4.sql
+++ /dev/null
@@ -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
--- a/ext_scripts/pg_dbms_stats--1.3.2--1.3.3-9.4.sql
+++ /dev/null
@@ -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;
--- a/ext_scripts/pg_dbms_stats--1.3.4--1.3.5-9.4.sql
+++ /dev/null
@@ -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;
--- a/ext_scripts/pg_dbms_stats--1.3.5--1.3.6-9.4.sql
+++ /dev/null
@@ -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