diff --git a/lib/.gitignore b/lib/.gitignore index b0856a5..0903fca 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -1,2 +1,3 @@ /.deps/ /pg_reorg.sql +/pg_reorg--1.0.sql diff --git a/lib/Makefile b/lib/Makefile index 9bc57f4..307562c 100755 --- a/lib/Makefile +++ b/lib/Makefile @@ -10,9 +10,8 @@ OBJS = reorg.o pgut/pgut-be.o pgut/pgut-spi.o EXTENSION = pg_reorg #supports both EXTENSION (for >=9.1) and without_EXTENSION (for $@; \ + echo "CREATE SCHEMA reorg;\n" >> $@; \ + sed 's,MODULE_PATHNAME,$$libdir/$(MODULE_big),g' $< >> $@; \ + echo "\nCOMMIT;" >> $@; + +pg_reorg--1.0.sql: pg_reorg.sql.in + echo '\echo Use "CREATE EXTENSION pg_reorg" to load this file. \quit' > $@; \ + cat $< >> $@; diff --git a/lib/pg_reorg--1.0.sql b/lib/pg_reorg--1.0.sql deleted file mode 100644 index dbc43f8..0000000 --- a/lib/pg_reorg--1.0.sql +++ /dev/null @@ -1,224 +0,0 @@ -/* pg_reorg/pg_reorg--1.0.sql */ - --- complain if script is sourced in psql, rather than via CREATE EXTENSION -\echo Use "CREATE EXTENSION pg_reorg" to load this file. \quit - -CREATE FUNCTION reorg.version() RETURNS text AS -'MODULE_PATHNAME', 'reorg_version' -LANGUAGE C IMMUTABLE STRICT; - -CREATE AGGREGATE reorg.array_accum ( - sfunc = array_append, - basetype = anyelement, - stype = anyarray, - initcond = '{}' -); - -CREATE FUNCTION reorg.oid2text(oid) RETURNS text AS -$$ - SELECT textin(regclassout($1)); -$$ -LANGUAGE sql STABLE STRICT; - -CREATE FUNCTION reorg.get_index_columns(oid, text) RETURNS text AS -$$ - SELECT array_to_string(reorg.array_accum(quote_ident(attname)), $2) - 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; - -CREATE FUNCTION reorg.get_index_keys(oid, oid) RETURNS text AS -'MODULE_PATHNAME', 'reorg_get_index_keys' -LANGUAGE C STABLE STRICT; - -CREATE FUNCTION reorg.get_create_index_type(oid, name) RETURNS text AS -$$ - SELECT 'CREATE TYPE ' || $2 || ' AS (' || - array_to_string(reorg.array_accum(quote_ident(attname) || ' ' || - 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; - -CREATE FUNCTION reorg.get_create_trigger(relid oid, pkid oid) - RETURNS text AS -$$ - SELECT 'CREATE TRIGGER z_reorg_trigger' || - ' BEFORE INSERT OR DELETE OR UPDATE ON ' || reorg.oid2text($1) || - ' FOR EACH ROW EXECUTE PROCEDURE reorg.reorg_trigger(' || - '''INSERT INTO reorg.log_' || $1 || '(pk, row) VALUES(' || - ' CASE WHEN $1 IS NULL THEN NULL ELSE (ROW($1.' || - reorg.get_index_columns($2, ', $1.') || ')::reorg.pk_' || - $1 || ') END, $2)'')'; -$$ -LANGUAGE sql STABLE STRICT; - -CREATE FUNCTION reorg.get_assign(oid, text) RETURNS text AS -$$ - SELECT '(' || array_to_string(reorg.array_accum(attname), ', ') || - ') = (' || $2 || '.' || - array_to_string(reorg.array_accum(quote_ident(attname)), ', ' || $2 || '.') || ')' - FROM (SELECT attname FROM pg_attribute - WHERE attrelid = $1 AND attnum > 0 AND NOT attisdropped - ORDER BY attnum) tmp; -$$ -LANGUAGE sql STABLE STRICT; - -CREATE FUNCTION reorg.get_compare_pkey(oid, text) - RETURNS text AS -$$ - SELECT '(' || array_to_string(reorg.array_accum(quote_ident(attname)), ', ') || - ') = (' || $2 || '.' || - array_to_string(reorg.array_accum(quote_ident(attname)), ', ' || $2 || '.') || ')' - 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; - --- Get a column list for SELECT all columns including dropped ones. --- We use NULLs of integer types for dropped columns (types are not important). -CREATE FUNCTION reorg.get_columns_for_create_as(oid) - RETURNS text AS -$$ -SELECT array_to_string(reorg.array_accum(c), ',') FROM (SELECT - 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. -CREATE FUNCTION reorg.get_drop_columns(oid, text) - RETURNS text AS -$$ -SELECT - 'ALTER TABLE ' || $2 || ' ' || array_to_string(dropped_columns, ', ') -FROM ( - SELECT - reorg.array_accum('DROP COLUMN ' || quote_ident(attname)) AS dropped_columns - 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; - --- includes not only PRIMARY KEYS but also UNIQUE NOT NULL keys -CREATE VIEW reorg.primary_keys AS - SELECT indrelid, (reorg.array_accum(indexrelid))[1] AS indexrelid - FROM (SELECT indrelid, indexrelid FROM pg_index - WHERE indisunique - 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; - -CREATE VIEW reorg.tables AS - 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, - reorg.get_create_index_type(PK.indexrelid, 'reorg.pk_' || R.oid) AS create_pktype, - 'CREATE TABLE reorg.log_' || R.oid || ' (id bigserial PRIMARY KEY, pk reorg.pk_' || R.oid || ', row ' || reorg.oid2text(R.oid) || ')' AS create_log, - reorg.get_create_trigger(R.oid, PK.indexrelid) AS create_trigger, - 'CREATE TABLE reorg.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 ' || reorg.get_columns_for_create_as(R.oid) || ' FROM ONLY ' || reorg.oid2text(R.oid) AS create_table, - reorg.get_drop_columns(R.oid, 'reorg.table_' || R.oid) AS drop_columns, - 'DELETE FROM reorg.log_' || R.oid AS delete_log, - 'LOCK TABLE ' || reorg.oid2text(R.oid) || ' IN ACCESS EXCLUSIVE MODE' AS lock_table, - reorg.get_index_keys(CK.indexrelid, R.oid) AS ckey, - 'SELECT * FROM reorg.log_' || R.oid || ' ORDER BY id LIMIT $1' AS sql_peek, - 'INSERT INTO reorg.table_' || R.oid || ' VALUES ($1.*)' AS sql_insert, - 'DELETE FROM reorg.table_' || R.oid || ' WHERE ' || reorg.get_compare_pkey(PK.indexrelid, '$1') AS sql_delete, - 'UPDATE reorg.table_' || R.oid || ' SET ' || reorg.get_assign(R.oid, '$2') || ' WHERE ' || reorg.get_compare_pkey(PK.indexrelid, '$1') AS sql_update, - 'DELETE FROM reorg.log_' || R.oid || ' WHERE id <= $1' AS sql_pop - FROM pg_class R - LEFT JOIN pg_class T ON R.reltoastrelid = T.oid - LEFT JOIN reorg.primary_keys PK - ON R.oid = PK.indrelid - LEFT JOIN (SELECT CKI.* FROM pg_index CKI, pg_class CKT - WHERE CKI.indisvalid - AND CKI.indexrelid = CKT.oid - AND CKI.indisclustered - AND CKT.relam = 403) CK - 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\\_%'; - -CREATE FUNCTION reorg.reorg_indexdef(oid, oid) RETURNS text AS -'MODULE_PATHNAME', 'reorg_indexdef' -LANGUAGE C STABLE STRICT; - -CREATE FUNCTION reorg.reorg_trigger() RETURNS trigger AS -'MODULE_PATHNAME', 'reorg_trigger' -LANGUAGE C VOLATILE STRICT SECURITY DEFINER; - -CREATE FUNCTION reorg.conflicted_triggers(oid) RETURNS SETOF name AS -$$ -SELECT tgname FROM pg_trigger - WHERE tgrelid = $1 AND tgname >= 'z_reorg_trigger' -$$ -LANGUAGE sql STABLE STRICT; - -CREATE FUNCTION reorg.disable_autovacuum(regclass) RETURNS void AS -'MODULE_PATHNAME', 'reorg_disable_autovacuum' -LANGUAGE C VOLATILE STRICT; - -CREATE FUNCTION reorg.reorg_apply( - sql_peek cstring, - sql_insert cstring, - sql_delete cstring, - sql_update cstring, - sql_pop cstring, - count integer) -RETURNS integer AS -'MODULE_PATHNAME', 'reorg_apply' -LANGUAGE C VOLATILE; - -CREATE FUNCTION reorg.reorg_swap(oid) RETURNS void AS -'MODULE_PATHNAME', 'reorg_swap' -LANGUAGE C VOLATILE STRICT; - -CREATE FUNCTION reorg.reorg_drop(oid) RETURNS void AS -'MODULE_PATHNAME', 'reorg_drop' -LANGUAGE C VOLATILE STRICT; diff --git a/lib/pg_reorg.sql.in b/lib/pg_reorg.sql.in index 4be4d44..ed4bc72 100755 --- a/lib/pg_reorg.sql.in +++ b/lib/pg_reorg.sql.in @@ -5,13 +5,6 @@ * Portions Copyright (c) 2011, Itagaki Takahiro */ --- Adjust this setting to control where the objects get created. -SET search_path = public; - -BEGIN; - -CREATE SCHEMA reorg; - CREATE FUNCTION reorg.version() RETURNS text AS 'MODULE_PATHNAME', 'reorg_version' LANGUAGE C IMMUTABLE STRICT; @@ -241,5 +234,3 @@ LANGUAGE C VOLATILE STRICT; CREATE FUNCTION reorg.reorg_drop(oid) RETURNS void AS 'MODULE_PATHNAME', 'reorg_drop' LANGUAGE C VOLATILE STRICT; - -COMMIT;