aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c66
1 files changed, 50 insertions, 16 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 8473c9e7f44..4953def029b 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -366,7 +366,9 @@ static void ATExecDropCluster(Relation rel, LOCKMODE lockmode);
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
char *tablespacename, LOCKMODE lockmode);
static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode);
-static void ATExecSetRelOptions(Relation rel, List *defList, bool isReset, LOCKMODE lockmode);
+static void ATExecSetRelOptions(Relation rel, List *defList,
+ AlterTableType operation,
+ LOCKMODE lockmode);
static void ATExecEnableDisableTrigger(Relation rel, char *trigname,
char fires_when, bool skip_system, LOCKMODE lockmode);
static void ATExecEnableDisableRule(Relation rel, char *rulename,
@@ -2866,6 +2868,7 @@ AlterTableGetLockLevel(List *cmds)
case AT_DropCluster:
case AT_SetRelOptions:
case AT_ResetRelOptions:
+ case AT_ReplaceRelOptions:
case AT_SetOptions:
case AT_ResetOptions:
case AT_SetStorage:
@@ -3094,8 +3097,9 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
pass = AT_PASS_MISC; /* doesn't actually matter */
break;
case AT_SetRelOptions: /* SET (...) */
- case AT_ResetRelOptions: /* RESET (...) */
- ATSimplePermissions(rel, ATT_TABLE | ATT_INDEX);
+ case AT_ResetRelOptions: /* RESET (...) */
+ case AT_ReplaceRelOptions: /* reset them all, then set just these */
+ ATSimplePermissions(rel, ATT_TABLE | ATT_INDEX | ATT_VIEW);
/* This command never recurses */
/* No command-specific prep needed */
pass = AT_PASS_MISC;
@@ -3338,12 +3342,10 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
*/
break;
case AT_SetRelOptions: /* SET (...) */
- ATExecSetRelOptions(rel, (List *) cmd->def, false, lockmode);
- break;
case AT_ResetRelOptions: /* RESET (...) */
- ATExecSetRelOptions(rel, (List *) cmd->def, true, lockmode);
+ case AT_ReplaceRelOptions: /* replace entire option list */
+ ATExecSetRelOptions(rel, (List *) cmd->def, cmd->subtype, lockmode);
break;
-
case AT_EnableTrig: /* ENABLE TRIGGER name */
ATExecEnableDisableTrigger(rel, cmd->name,
TRIGGER_FIRES_ON_ORIGIN, false, lockmode);
@@ -8271,10 +8273,11 @@ ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename, L
}
/*
- * ALTER TABLE/INDEX SET (...) or RESET (...)
+ * Set, reset, or replace reloptions.
*/
static void
-ATExecSetRelOptions(Relation rel, List *defList, bool isReset, LOCKMODE lockmode)
+ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
+ LOCKMODE lockmode)
{
Oid relid;
Relation pgclass;
@@ -8288,28 +8291,44 @@ ATExecSetRelOptions(Relation rel, List *defList, bool isReset, LOCKMODE lockmode
bool repl_repl[Natts_pg_class];
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
- if (defList == NIL)
+ if (defList == NIL && operation != AT_ReplaceRelOptions)
return; /* nothing to do */
pgclass = heap_open(RelationRelationId, RowExclusiveLock);
- /* Get the old reloptions */
+ /* Fetch heap tuple */
relid = RelationGetRelid(rel);
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", relid);
- datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
+ if (operation == AT_ReplaceRelOptions)
+ {
+ /*
+ * If we're supposed to replace the reloptions list, we just pretend
+ * there were none before.
+ */
+ datum = (Datum) 0;
+ isnull = true;
+ }
+ else
+ {
+ /* Get the old reloptions */
+ datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,
+ &isnull);
+ }
/* Generate new proposed reloptions (text array) */
newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
- defList, NULL, validnsps, false, isReset);
+ defList, NULL, validnsps, false,
+ operation == AT_ResetRelOptions);
/* Validate */
switch (rel->rd_rel->relkind)
{
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
+ case RELKIND_VIEW:
(void) heap_reloptions(rel->rd_rel->relkind, newOptions, true);
break;
case RELKIND_INDEX:
@@ -8357,15 +8376,30 @@ ATExecSetRelOptions(Relation rel, List *defList, bool isReset, LOCKMODE lockmode
toastrel = heap_open(toastid, lockmode);
- /* Get the old reloptions */
+ /* Fetch heap tuple */
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid));
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", toastid);
- datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
+ if (operation == AT_ReplaceRelOptions)
+ {
+ /*
+ * If we're supposed to replace the reloptions list, we just
+ * pretend there were none before.
+ */
+ datum = (Datum) 0;
+ isnull = true;
+ }
+ else
+ {
+ /* Get the old reloptions */
+ datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,
+ &isnull);
+ }
newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
- defList, "toast", validnsps, false, isReset);
+ defList, "toast", validnsps, false,
+ operation == AT_ResetRelOptions);
(void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true);