2008-12-08 04:32:10 +00:00
/*
2012-11-10 22:33:57 +00:00
* pg_repack : lib / pg_repack . sql . in
2008-12-08 04:32:10 +00:00
*
2011-04-29 05:06:48 +00:00
* Portions Copyright ( c ) 2008 - 2011 , NIPPON TELEGRAPH AND TELEPHONE CORPORATION
* Portions Copyright ( c ) 2011 , Itagaki Takahiro
2012-11-11 03:00:00 +00:00
* Portions Copyright ( c ) 2012 , The Reorg Development Team
2008-12-08 04:32:10 +00:00
* /
2012-11-13 14:02:45 +00:00
CREATE SCHEMA repack ;
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . version ( ) RETURNS text AS
' MODULE_PATHNAME ' , ' repack_version '
2012-05-01 06:11:49 +00:00
LANGUAGE C IMMUTABLE STRICT ;
2009-05-25 07:06:38 +00:00
2012-11-15 23:37:09 +00:00
CREATE FUNCTION repack . version_sql ( ) RETURNS text AS
$ $ SELECT ' pg_repack REPACK_VERSION ' : : text $ $
LANGUAGE SQL IMMUTABLE STRICT ;
2012-11-10 22:33:57 +00:00
CREATE AGGREGATE repack . array_accum (
2008-12-08 04:32:10 +00:00
sfunc = array_append ,
basetype = anyelement ,
stype = anyarray ,
initcond = ' {} '
) ;
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . oid2text ( oid ) RETURNS text AS
2009-01-27 01:35:53 +00:00
$ $
SELECT textin ( regclassout ( $ 1 ) ) ;
$ $
LANGUAGE sql STABLE STRICT ;
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . get_index_columns ( oid , text ) RETURNS text AS
2008-12-08 04:32:10 +00:00
$ $
2012-11-10 22:33:57 +00:00
SELECT array_to_string ( repack . array_accum ( quote_ident ( attname ) ) , $ 2 )
2008-12-08 04:32:10 +00:00
FROM pg_attribute ,
( SELECT indrelid ,
indkey ,
generate_series ( 0 , indnatts - 1 ) AS i
FROM pg_index
WHERE indexrelid = $ 1
) AS keys
WHERE attrelid = indrelid
AND attnum = indkey [ i ] ;
$ $
LANGUAGE sql STABLE STRICT ;
2012-12-09 11:35:52 +00:00
CREATE FUNCTION repack . get_order_by ( oid , oid ) RETURNS text AS
' MODULE_PATHNAME ' , ' repack_get_order_by '
2012-05-01 06:11:49 +00:00
LANGUAGE C STABLE STRICT ;
2008-12-08 04:32:10 +00:00
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . get_create_index_type ( oid , name ) RETURNS text AS
2008-12-08 04:32:10 +00:00
$ $
SELECT ' CREATE TYPE ' | | $ 2 | | ' AS ( ' | |
2012-11-10 22:33:57 +00:00
array_to_string ( repack . array_accum ( quote_ident ( attname ) | | ' ' | |
2008-12-08 04:32:10 +00:00
pg_catalog . format_type ( atttypid , atttypmod ) ) , ' , ' ) | | ' ) '
FROM pg_attribute ,
( SELECT indrelid ,
indkey ,
generate_series ( 0 , indnatts - 1 ) AS i
FROM pg_index
WHERE indexrelid = $ 1
) AS keys
WHERE attrelid = indrelid
AND attnum = indkey [ i ] ;
$ $
LANGUAGE sql STABLE STRICT ;
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . get_create_trigger ( relid oid , pkid oid )
2008-12-08 04:32:10 +00:00
RETURNS text AS
$ $
2012-11-10 22:33:57 +00:00
SELECT ' CREATE TRIGGER z_repack_trigger ' | |
' BEFORE INSERT OR DELETE OR UPDATE ON ' | | repack . oid2text ( $ 1 ) | |
' FOR EACH ROW EXECUTE PROCEDURE repack.repack_trigger( ' | |
' '' INSERT INTO repack.log_ ' | | $ 1 | | ' (pk, row) VALUES( ' | |
2008-12-08 04:32:10 +00:00
' CASE WHEN $1 IS NULL THEN NULL ELSE (ROW($1. ' | |
2012-11-10 22:33:57 +00:00
repack . get_index_columns ( $ 2 , ' , $1. ' ) | | ' )::repack.pk_ ' | |
2008-12-08 04:32:10 +00:00
$ 1 | | ' ) END, $2) '' ) ' ;
$ $
LANGUAGE sql STABLE STRICT ;
2012-11-12 11:51:20 +00:00
CREATE FUNCTION repack . get_enable_trigger ( relid oid )
2012-10-14 10:50:05 -07:00
RETURNS text AS
$ $
2012-11-10 22:33:57 +00:00
SELECT ' ALTER TABLE ' | | repack . oid2text ( $ 1 ) | |
2012-11-12 11:51:20 +00:00
' ENABLE ALWAYS TRIGGER z_repack_trigger ' ;
2012-10-14 10:50:05 -07:00
$ $
LANGUAGE sql STABLE STRICT ;
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . get_assign ( oid , text ) RETURNS text AS
2008-12-08 04:32:10 +00:00
$ $
2012-11-10 22:33:57 +00:00
SELECT ' ( ' | | array_to_string ( repack . array_accum ( quote_ident ( attname ) ) , ' , ' ) | |
2008-12-08 04:32:10 +00:00
' ) = ( ' | | $ 2 | | ' . ' | |
2012-11-10 22:33:57 +00:00
array_to_string ( repack . array_accum ( quote_ident ( attname ) ) , ' , ' | | $ 2 | | ' . ' ) | | ' ) '
2008-12-08 04:32:10 +00:00
FROM ( SELECT attname FROM pg_attribute
2009-07-02 09:50:58 +00:00
WHERE attrelid = $ 1 AND attnum > 0 AND NOT attisdropped
2008-12-08 04:32:10 +00:00
ORDER BY attnum ) tmp ;
$ $
LANGUAGE sql STABLE STRICT ;
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . get_compare_pkey ( oid , text )
2008-12-08 04:32:10 +00:00
RETURNS text AS
$ $
2012-11-10 22:33:57 +00:00
SELECT ' ( ' | | array_to_string ( repack . array_accum ( quote_ident ( attname ) ) , ' , ' ) | |
2008-12-08 04:32:10 +00:00
' ) = ( ' | | $ 2 | | ' . ' | |
2012-11-10 22:33:57 +00:00
array_to_string ( repack . array_accum ( quote_ident ( attname ) ) , ' , ' | | $ 2 | | ' . ' ) | | ' ) '
2008-12-08 04:32:10 +00:00
FROM pg_attribute ,
( SELECT indrelid ,
indkey ,
generate_series ( 0 , indnatts - 1 ) AS i
FROM pg_index
WHERE indexrelid = $ 1
) AS keys
WHERE attrelid = indrelid
AND attnum = indkey [ i ] ;
$ $
LANGUAGE sql STABLE STRICT ;
2011-04-29 05:06:48 +00:00
-- Get a column list for SELECT all columns including dropped ones.
-- We use NULLs of integer types for dropped columns (types are not important).
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . get_columns_for_create_as ( oid )
2011-04-29 05:06:48 +00:00
RETURNS text AS
$ $
2012-11-10 22:33:57 +00:00
SELECT array_to_string ( repack . array_accum ( c ) , ' , ' ) FROM ( SELECT
2011-04-29 05:06:48 +00:00
CASE WHEN attisdropped
THEN ' NULL::integer AS ' | | quote_ident ( attname )
ELSE quote_ident ( attname )
END AS c
FROM pg_attribute
WHERE attrelid = $ 1 AND attnum > 0 ORDER BY attnum
) AS COL
$ $
LANGUAGE sql STABLE STRICT ;
-- Get a SQL text to DROP dropped columns for the table,
-- or NULL if it has no dropped columns.
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . get_drop_columns ( oid , text )
2011-04-29 05:06:48 +00:00
RETURNS text AS
$ $
SELECT
' ALTER TABLE ' | | $ 2 | | ' ' | | array_to_string ( dropped_columns , ' , ' )
FROM (
SELECT
2012-11-10 22:33:57 +00:00
repack . array_accum ( ' DROP COLUMN ' | | quote_ident ( attname ) ) AS dropped_columns
2011-04-29 05:06:48 +00:00
FROM (
SELECT * FROM pg_attribute
WHERE attrelid = $ 1 AND attnum > 0 AND attisdropped
ORDER BY attnum
) T
) T
WHERE
array_upper ( dropped_columns , 1 ) > 0
$ $
LANGUAGE sql STABLE STRICT ;
2011-01-06 09:35:15 +00:00
-- includes not only PRIMARY KEYS but also UNIQUE NOT NULL keys
2012-11-10 22:33:57 +00:00
CREATE VIEW repack . primary_keys AS
SELECT indrelid , ( repack . array_accum ( indexrelid ) ) [ 1 ] AS indexrelid
2011-01-25 06:41:12 +00:00
FROM ( SELECT indrelid , indexrelid FROM pg_index
WHERE indisunique
2012-10-17 00:01:00 +01:00
AND indisvalid
2012-11-15 00:16:38 +00:00
AND indpred IS NULL
2011-01-25 06:41:12 +00:00
AND 0 < > ALL ( indkey )
AND NOT EXISTS (
SELECT 1 FROM pg_attribute
WHERE attrelid = indrelid
AND attnum = ANY ( indkey )
AND NOT attnotnull )
ORDER BY indrelid , indisprimary DESC , indnatts , indkey ) tmp
GROUP BY indrelid ;
2011-01-06 09:35:15 +00:00
2012-11-10 22:33:57 +00:00
CREATE VIEW repack . tables AS
2008-12-08 04:32:10 +00:00
SELECT R . oid : : regclass AS relname ,
R . oid AS relid ,
R . reltoastrelid AS reltoastrelid ,
CASE WHEN R . reltoastrelid = 0 THEN 0 ELSE ( SELECT reltoastidxid FROM pg_class WHERE oid = R . reltoastrelid ) END AS reltoastidxid ,
PK . indexrelid AS pkid ,
CK . indexrelid AS ckid ,
2012-11-10 22:33:57 +00:00
repack . get_create_index_type ( PK . indexrelid , ' repack.pk_ ' | | R . oid ) AS create_pktype ,
' CREATE TABLE repack.log_ ' | | R . oid | | ' (id bigserial PRIMARY KEY, pk repack.pk_ ' | | R . oid | | ' , row ' | | repack . oid2text ( R . oid ) | | ' ) ' AS create_log ,
repack . get_create_trigger ( R . oid , PK . indexrelid ) AS create_trigger ,
2012-11-12 11:51:20 +00:00
repack . get_enable_trigger ( R . oid ) as enable_trigger ,
2012-11-10 22:33:57 +00:00
' CREATE TABLE repack.table_ ' | | R . oid | | ' WITH ( ' | | array_to_string ( array_append ( R . reloptions , ' oids= ' | | CASE WHEN R . relhasoids THEN ' true ' ELSE ' false ' END ) , ' , ' ) | | ' ) TABLESPACE ' | | coalesce ( quote_ident ( S . spcname ) , ' pg_default ' ) | | ' AS SELECT ' | | repack . get_columns_for_create_as ( R . oid ) | | ' FROM ONLY ' | | repack . oid2text ( R . oid ) AS create_table ,
2012-11-12 11:51:20 +00:00
repack . get_drop_columns ( R . oid , ' repack.table_ ' | | R . oid ) AS drop_columns ,
2012-11-10 22:33:57 +00:00
' DELETE FROM repack.log_ ' | | R . oid AS delete_log ,
' LOCK TABLE ' | | repack . oid2text ( R . oid ) | | ' IN ACCESS EXCLUSIVE MODE ' AS lock_table ,
2012-12-09 11:35:52 +00:00
repack . get_order_by ( CK . indexrelid , R . oid ) AS ckey ,
2012-11-10 22:33:57 +00:00
' SELECT * FROM repack.log_ ' | | R . oid | | ' ORDER BY id LIMIT $1 ' AS sql_peek ,
' INSERT INTO repack.table_ ' | | R . oid | | ' VALUES ($1.*) ' AS sql_insert ,
' DELETE FROM repack.table_ ' | | R . oid | | ' WHERE ' | | repack . get_compare_pkey ( PK . indexrelid , ' $1 ' ) AS sql_delete ,
' UPDATE repack.table_ ' | | R . oid | | ' SET ' | | repack . get_assign ( R . oid , ' $2 ' ) | | ' WHERE ' | | repack . get_compare_pkey ( PK . indexrelid , ' $1 ' ) AS sql_update ,
' DELETE FROM repack.log_ ' | | R . oid | | ' WHERE id <= $1 ' AS sql_pop
2008-12-08 04:32:10 +00:00
FROM pg_class R
LEFT JOIN pg_class T ON R . reltoastrelid = T . oid
2012-11-10 22:33:57 +00:00
LEFT JOIN repack . primary_keys PK
2008-12-08 04:32:10 +00:00
ON R . oid = PK . indrelid
LEFT JOIN ( SELECT CKI . * FROM pg_index CKI , pg_class CKT
2011-01-06 09:35:15 +00:00
WHERE CKI . indisvalid
AND CKI . indexrelid = CKT . oid
AND CKI . indisclustered
AND CKT . relam = 403 ) CK
2008-12-08 04:32:10 +00:00
ON R . oid = CK . indrelid
LEFT JOIN pg_namespace N ON N . oid = R . relnamespace
LEFT JOIN pg_tablespace S ON S . oid = R . reltablespace
WHERE R . relkind = ' r '
AND N . nspname NOT IN ( ' pg_catalog ' , ' information_schema ' )
AND N . nspname NOT LIKE E ' pg\\_temp\\_% ' ;
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . repack_indexdef ( oid , oid ) RETURNS text AS
' MODULE_PATHNAME ' , ' repack_indexdef '
2012-05-01 06:11:49 +00:00
LANGUAGE C STABLE STRICT ;
2008-12-08 04:32:10 +00:00
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . repack_trigger ( ) RETURNS trigger AS
' MODULE_PATHNAME ' , ' repack_trigger '
2012-05-01 06:11:49 +00:00
LANGUAGE C VOLATILE STRICT SECURITY DEFINER ;
2008-12-08 04:32:10 +00:00
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . conflicted_triggers ( oid ) RETURNS SETOF name AS
2009-05-25 07:06:38 +00:00
$ $
SELECT tgname FROM pg_trigger
2012-11-10 22:33:57 +00:00
WHERE tgrelid = $ 1 AND tgname > = ' z_repack_trigger '
2009-05-25 07:06:38 +00:00
$ $
LANGUAGE sql STABLE STRICT ;
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . disable_autovacuum ( regclass ) RETURNS void AS
' MODULE_PATHNAME ' , ' repack_disable_autovacuum '
2012-05-01 06:11:49 +00:00
LANGUAGE C VOLATILE STRICT ;
2009-05-25 07:06:38 +00:00
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . repack_apply (
2008-12-08 04:32:10 +00:00
sql_peek cstring ,
sql_insert cstring ,
sql_delete cstring ,
sql_update cstring ,
sql_pop cstring ,
count integer )
RETURNS integer AS
2012-11-10 22:33:57 +00:00
' MODULE_PATHNAME ' , ' repack_apply '
2012-05-01 06:11:49 +00:00
LANGUAGE C VOLATILE ;
2008-12-08 04:32:10 +00:00
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . repack_swap ( oid ) RETURNS void AS
' MODULE_PATHNAME ' , ' repack_swap '
2012-05-01 06:11:49 +00:00
LANGUAGE C VOLATILE STRICT ;
2008-12-08 04:32:10 +00:00
2012-11-10 22:33:57 +00:00
CREATE FUNCTION repack . repack_drop ( oid ) RETURNS void AS
' MODULE_PATHNAME ' , ' repack_drop '
2012-05-01 06:11:49 +00:00
LANGUAGE C VOLATILE STRICT ;