if (wal_level < WAL_LEVEL_REPLICA)
ereport(ERROR,
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("cannot execute \"%s\" in this configuration",
+ errmsg("cannot execute %s in this configuration",
"REPACK (CONCURRENTLY)"),
errdetail("%s requires \"wal_level\" to be set to \"replica\" or higher.",
"REPACK (CONCURRENTLY)"));
if (IsCatalogRelation(rel))
ereport(ERROR,
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot repack relation \"%s\"",
- RelationGetRelationName(rel)),
+ errmsg("cannot execute %s on relation \"%s\"",
+ "REPACK (CONCURRENTLY)", RelationGetRelationName(rel)),
errhint("%s is not supported for catalog relations.",
"REPACK (CONCURRENTLY)"));
if (IsToastRelation(rel))
ereport(ERROR,
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot repack relation \"%s\"",
- RelationGetRelationName(rel)),
+ errmsg("cannot execute %s on relation \"%s\"",
+ "REPACK (CONCURRENTLY)", RelationGetRelationName(rel)),
errhint("%s is not supported for TOAST relations.",
"REPACK (CONCURRENTLY)"));
if (relpersistence != RELPERSISTENCE_PERMANENT)
ereport(ERROR,
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("cannot repack relation \"%s\"",
- RelationGetRelationName(rel)),
+ errmsg("cannot execute %s on relation \"%s\"",
+ "REPACK (CONCURRENTLY)", RelationGetRelationName(rel)),
errhint("%s is only allowed for permanent relations.",
"REPACK (CONCURRENTLY)"));
- /* With NOTHING, WAL does not contain the old tuple. */
+ /*
+ * With NOTHING, WAL does not contain the old tuple; FULL is not yet
+ * supported.
+ */
replident = rel->rd_rel->relreplident;
- if (replident == REPLICA_IDENTITY_NOTHING)
+ if (replident == REPLICA_IDENTITY_NOTHING ||
+ replident == REPLICA_IDENTITY_FULL)
ereport(ERROR,
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("cannot repack relation \"%s\"",
- RelationGetRelationName(rel)),
- errhint("Relation \"%s\" has insufficient replication identity.",
- RelationGetRelationName(rel)));
+ errmsg("cannot execute %s on relation \"%s\"",
+ "REPACK (CONCURRENTLY)", RelationGetRelationName(rel)),
+ errdetail("%s does not support tables with %s.",
+ "REPACK (CONCURRENTLY)",
+ replident == REPLICA_IDENTITY_NOTHING ?
+ "REPLICA IDENTITY NOTHING" : "REPLICA IDENTITY FULL"));
/*
* Obtain the replica identity index -- either one that has been set
*/
ident_idx = GetRelationIdentityOrPK(rel);
if (!OidIsValid(ident_idx))
+ {
+ /* This special case warrants its own error message */
+ if (OidIsValid(rel->rd_pkindex) && rel->rd_ispkdeferrable)
+ ereport(ERROR,
+ errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot execute %s on relation \"%s\"",
+ "REPACK (CONCURRENTLY)",
+ RelationGetRelationName(rel)),
+ errdetail("%s does not support deferrable primary keys.",
+ "REPACK (CONCURRENTLY)"),
+ errhint("Use ALTER TABLE ... REPLICA IDENTITY USING INDEX to designate another index as replica identity."));
+
ereport(ERROR,
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("cannot process relation \"%s\"",
- RelationGetRelationName(rel)),
+ errmsg("cannot execute %s on relation \"%s\"",
+ "REPACK (CONCURRENTLY)", RelationGetRelationName(rel)),
errhint("Relation \"%s\" has no identity index.",
RelationGetRelationName(rel)));
+ }
*ident_idx_p = ident_idx;
}
--
-- Disallowed in catalogs
REPACK (CONCURRENTLY) pg_class;
-ERROR: cannot repack relation "pg_class"
+ERROR: cannot execute REPACK (CONCURRENTLY) on relation "pg_class"
HINT: REPACK (CONCURRENTLY) is not supported for catalog relations.
-- Doesn't like partitioned tables
REPACK (CONCURRENTLY) clstrpart;
HINT: Consider running the command on individual partitions.
-- Doesn't support catalog tables
REPACK (CONCURRENTLY) pg_class;
-ERROR: cannot repack relation "pg_class"
+ERROR: cannot execute REPACK (CONCURRENTLY) on relation "pg_class"
HINT: REPACK (CONCURRENTLY) is not supported for catalog relations.
-- Only support permanent tables, temp and unlogged tables are not supported
CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
REPACK (CONCURRENTLY) repack_conc_temp;
-ERROR: cannot repack relation "repack_conc_temp"
+ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_temp"
HINT: REPACK (CONCURRENTLY) is only allowed for permanent relations.
DROP TABLE repack_conc_temp;
CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
REPACK (CONCURRENTLY) repack_conc_unlogged;
-ERROR: cannot repack relation "repack_conc_unlogged"
+ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_unlogged"
HINT: REPACK (CONCURRENTLY) is only allowed for permanent relations.
DROP TABLE repack_conc_unlogged;
-- Doesn't support TOAST tables directly
CREATE TABLE repack_conc_replident (i int PRIMARY KEY);
ALTER TABLE repack_conc_replident REPLICA IDENTITY NOTHING;
REPACK (CONCURRENTLY) repack_conc_replident;
-ERROR: cannot repack relation "repack_conc_replident"
-HINT: Relation "repack_conc_replident" has insufficient replication identity.
+ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
+DETAIL: REPACK (CONCURRENTLY) does not support tables with REPLICA IDENTITY NOTHING.
-- Doesn't support tables without a primary key or replica identity index
ALTER TABLE repack_conc_replident DROP CONSTRAINT repack_conc_replident_pkey;
ALTER TABLE repack_conc_replident REPLICA IDENTITY DEFAULT;
REPACK (CONCURRENTLY) repack_conc_replident;
-ERROR: cannot process relation "repack_conc_replident"
+ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
HINT: Relation "repack_conc_replident" has no identity index.
-- Doesn't support tables with deferrable primary keys
ALTER TABLE repack_conc_replident ADD PRIMARY KEY (i) DEFERRABLE;
REPACK (CONCURRENTLY) repack_conc_replident;
-ERROR: cannot process relation "repack_conc_replident"
-HINT: Relation "repack_conc_replident" has no identity index.
+ERROR: cannot execute REPACK (CONCURRENTLY) on relation "repack_conc_replident"
+DETAIL: REPACK (CONCURRENTLY) does not support deferrable primary keys.
+HINT: Use ALTER TABLE ... REPLICA IDENTITY USING INDEX to designate another index as replica identity.
-- clean up
DROP TABLE repack_conc_replident;
DROP TABLE clustertest;