Use one of not-null unique keys to identify rows when the target table doesn't
have a primary key. Some of users want to use not-null unique keys rather than primary keys because postgres doesn't support REINDEX PRIMARY KEY CONCURRENTLY. - Support 9.1dev. - Improve Makefile to use PGXS automatically.
This commit is contained in:
parent
d8d39cc948
commit
232c9bb6c9
14
Makefile
14
Makefile
@ -3,14 +3,22 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
# Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||||
#
|
#
|
||||||
|
ifndef USE_PGXS
|
||||||
|
top_builddir = ../..
|
||||||
|
makefile_global = $(top_builddir)/src/Makefile.global
|
||||||
|
ifeq "$(wildcard $(makefile_global))" ""
|
||||||
|
USE_PGXS = 1 # use pgxs if not in contrib directory
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef USE_PGXS
|
ifdef USE_PGXS
|
||||||
PG_CONFIG = pg_config
|
PG_CONFIG = pg_config
|
||||||
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||||
include $(PGXS)
|
include $(PGXS)
|
||||||
else
|
else
|
||||||
subdir = pg_statsinfo
|
subdir = pg_reorg
|
||||||
top_builddir = ../..
|
include $(makefile_global)
|
||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_srcdir)/contrib/contrib-global.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SUBDIRS = bin lib
|
SUBDIRS = bin lib
|
||||||
|
16
bin/Makefile
16
bin/Makefile
@ -15,13 +15,21 @@ PG_CPPFLAGS = -I$(libpq_srcdir)
|
|||||||
endif
|
endif
|
||||||
PG_LIBS = $(libpq)
|
PG_LIBS = $(libpq)
|
||||||
|
|
||||||
|
ifndef USE_PGXS
|
||||||
|
top_builddir = ../../..
|
||||||
|
makefile_global = $(top_builddir)/src/Makefile.global
|
||||||
|
ifeq "$(wildcard $(makefile_global))" ""
|
||||||
|
USE_PGXS = 1 # use pgxs if not in contrib directory
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef USE_PGXS
|
ifdef USE_PGXS
|
||||||
PGXS := $(shell pg_config --pgxs)
|
PG_CONFIG = pg_config
|
||||||
|
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||||
include $(PGXS)
|
include $(PGXS)
|
||||||
else
|
else
|
||||||
subdir = contrib/pg_reorg
|
subdir = contrib/$(MODULE_big)
|
||||||
top_builddir = ../../..
|
include $(makefile_global)
|
||||||
include $(top_builddir)/src/Makefile.global
|
|
||||||
include $(top_srcdir)/contrib/contrib-global.mk
|
include $(top_srcdir)/contrib/contrib-global.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -222,3 +222,20 @@ SELECT oid, relname
|
|||||||
-----+---------
|
-----+---------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
|
--
|
||||||
|
-- NOT NULL UNIQUE
|
||||||
|
--
|
||||||
|
CREATE TABLE tbl_nn (col1 int NOT NULL, col2 int NOT NULL);
|
||||||
|
CREATE TABLE tbl_uk (col1 int NOT NULL, col2 int , UNIQUE(col1, col2));
|
||||||
|
CREATE TABLE tbl_nn_uk (col1 int NOT NULL, col2 int NOT NULL, UNIQUE(col1, col2));
|
||||||
|
CREATE TABLE tbl_pk_uk (col1 int NOT NULL, col2 int NOT NULL, PRIMARY KEY(col1, col2), UNIQUE(col2, col1));
|
||||||
|
\! pg_reorg --dbname=contrib_regression --no-order --table=tbl_nn
|
||||||
|
ERROR: relation "tbl_nn" must have a primary key or not-null unique keys
|
||||||
|
-- => ERROR
|
||||||
|
\! pg_reorg --dbname=contrib_regression --no-order --table=tbl_uk
|
||||||
|
ERROR: relation "tbl_uk" must have a primary key or not-null unique keys
|
||||||
|
-- => ERROR
|
||||||
|
\! pg_reorg --dbname=contrib_regression --no-order --table=tbl_nn_uk
|
||||||
|
-- => OK
|
||||||
|
\! pg_reorg --dbname=contrib_regression --no-order --table=tbl_pk_uk
|
||||||
|
-- => OK
|
||||||
|
@ -293,7 +293,7 @@ reorg_one_database(const char *orderby, const char *table)
|
|||||||
if (table.pkid == 0)
|
if (table.pkid == 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(E_PG_COMMAND),
|
(errcode(E_PG_COMMAND),
|
||||||
errmsg("relation \"%s\" has no primary key", table.target_name)));
|
errmsg("relation \"%s\" must have a primary key or not-null unique keys", table.target_name)));
|
||||||
|
|
||||||
table.create_pktype = getstr(res, i, c++);
|
table.create_pktype = getstr(res, i, c++);
|
||||||
table.create_log = getstr(res, i, c++);
|
table.create_log = getstr(res, i, c++);
|
||||||
|
@ -130,3 +130,19 @@ SELECT oid, relname
|
|||||||
WHERE relkind = 'r'
|
WHERE relkind = 'r'
|
||||||
AND reltoastrelid <> 0
|
AND reltoastrelid <> 0
|
||||||
AND reltoastrelid NOT IN (SELECT oid FROM pg_class WHERE relkind = 't');
|
AND reltoastrelid NOT IN (SELECT oid FROM pg_class WHERE relkind = 't');
|
||||||
|
|
||||||
|
--
|
||||||
|
-- NOT NULL UNIQUE
|
||||||
|
--
|
||||||
|
CREATE TABLE tbl_nn (col1 int NOT NULL, col2 int NOT NULL);
|
||||||
|
CREATE TABLE tbl_uk (col1 int NOT NULL, col2 int , UNIQUE(col1, col2));
|
||||||
|
CREATE TABLE tbl_nn_uk (col1 int NOT NULL, col2 int NOT NULL, UNIQUE(col1, col2));
|
||||||
|
CREATE TABLE tbl_pk_uk (col1 int NOT NULL, col2 int NOT NULL, PRIMARY KEY(col1, col2), UNIQUE(col2, col1));
|
||||||
|
\! pg_reorg --dbname=contrib_regression --no-order --table=tbl_nn
|
||||||
|
-- => ERROR
|
||||||
|
\! pg_reorg --dbname=contrib_regression --no-order --table=tbl_uk
|
||||||
|
-- => ERROR
|
||||||
|
\! pg_reorg --dbname=contrib_regression --no-order --table=tbl_nn_uk
|
||||||
|
-- => OK
|
||||||
|
\! pg_reorg --dbname=contrib_regression --no-order --table=tbl_pk_uk
|
||||||
|
-- => OK
|
||||||
|
16
lib/Makefile
16
lib/Makefile
@ -9,13 +9,21 @@ MODULE_big = pg_reorg
|
|||||||
DATA_built = pg_reorg.sql
|
DATA_built = pg_reorg.sql
|
||||||
DATA = uninstall_pg_reorg.sql
|
DATA = uninstall_pg_reorg.sql
|
||||||
|
|
||||||
|
ifndef USE_PGXS
|
||||||
|
top_builddir = ../../..
|
||||||
|
makefile_global = $(top_builddir)/src/Makefile.global
|
||||||
|
ifeq "$(wildcard $(makefile_global))" ""
|
||||||
|
USE_PGXS = 1 # use pgxs if not in contrib directory
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef USE_PGXS
|
ifdef USE_PGXS
|
||||||
PGXS := $(shell pg_config --pgxs)
|
PG_CONFIG = pg_config
|
||||||
|
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||||
include $(PGXS)
|
include $(PGXS)
|
||||||
else
|
else
|
||||||
subdir = contrib/pg_reorg
|
subdir = contrib/$(MODULE_big)
|
||||||
top_builddir = ../../..
|
include $(makefile_global)
|
||||||
include $(top_builddir)/src/Makefile.global
|
|
||||||
include $(top_srcdir)/contrib/contrib-global.mk
|
include $(top_srcdir)/contrib/contrib-global.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -106,6 +106,20 @@ $$
|
|||||||
$$
|
$$
|
||||||
LANGUAGE sql STABLE STRICT;
|
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
|
CREATE VIEW reorg.tables AS
|
||||||
SELECT R.oid::regclass AS relname,
|
SELECT R.oid::regclass AS relname,
|
||||||
R.oid AS relid,
|
R.oid AS relid,
|
||||||
@ -127,10 +141,13 @@ CREATE VIEW reorg.tables AS
|
|||||||
'DELETE FROM reorg.log_' || R.oid || ' WHERE id <= $1' AS sql_pop
|
'DELETE FROM reorg.log_' || R.oid || ' WHERE id <= $1' AS sql_pop
|
||||||
FROM pg_class R
|
FROM pg_class R
|
||||||
LEFT JOIN pg_class T ON R.reltoastrelid = T.oid
|
LEFT JOIN pg_class T ON R.reltoastrelid = T.oid
|
||||||
LEFT JOIN (SELECT * FROM pg_index WHERE indisprimary) PK
|
LEFT JOIN reorg.primary_keys PK
|
||||||
ON R.oid = PK.indrelid
|
ON R.oid = PK.indrelid
|
||||||
LEFT JOIN (SELECT CKI.* FROM pg_index CKI, pg_class CKT
|
LEFT JOIN (SELECT CKI.* FROM pg_index CKI, pg_class CKT
|
||||||
WHERE CKI.indexrelid = CKT.oid AND CKI.indisclustered AND CKT.relam = 403) CK
|
WHERE CKI.indisvalid
|
||||||
|
AND CKI.indexrelid = CKT.oid
|
||||||
|
AND CKI.indisclustered
|
||||||
|
AND CKT.relam = 403) CK
|
||||||
ON R.oid = CK.indrelid
|
ON R.oid = CK.indrelid
|
||||||
LEFT JOIN pg_namespace N ON N.oid = R.relnamespace
|
LEFT JOIN pg_namespace N ON N.oid = R.relnamespace
|
||||||
LEFT JOIN pg_tablespace S ON S.oid = R.reltablespace
|
LEFT JOIN pg_tablespace S ON S.oid = R.reltablespace
|
||||||
|
@ -151,6 +151,12 @@ extern void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM < 90100
|
||||||
|
|
||||||
|
#define ATExecChangeOwner(relationOid, newOwnerId, recursing, lockmode) \
|
||||||
|
ATExecChangeOwner((relationOid), (newOwnerId), (recursing))
|
||||||
|
#endif
|
||||||
|
|
||||||
#if PG_VERSION_NUM < 80300
|
#if PG_VERSION_NUM < 80300
|
||||||
#define RelationSetNewRelfilenode(rel, xid) \
|
#define RelationSetNewRelfilenode(rel, xid) \
|
||||||
setNewRelfilenode((rel))
|
setNewRelfilenode((rel))
|
||||||
|
@ -766,7 +766,7 @@ reorg_swap(PG_FUNCTION_ARGS)
|
|||||||
/* change owner of new relation to original owner */
|
/* change owner of new relation to original owner */
|
||||||
if (owner1 != owner2)
|
if (owner1 != owner2)
|
||||||
{
|
{
|
||||||
ATExecChangeOwner(oid2, owner1, true);
|
ATExecChangeOwner(oid2, owner1, true, AccessExclusiveLock);
|
||||||
CommandCounterIncrement();
|
CommandCounterIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user