Commit cd03c6e9 authored by Alvaro Herrera's avatar Alvaro Herrera

Let ALTER TABLE Phase 2 routines manage the relation pointer

Struct AlteredRelationInfo gains a new Relation member, to be used only
by Phase 2 (ATRewriteCatalogs); this allows ATExecCmd() subroutines open
and close the relation internally.

A future commit will use this facility to implement an ALTER TABLE
subcommand that closes and reopens the relation across transaction
boundaries.

(It is possible to keep the relation open past phase 2 to be used by
phase 3 instead of having to reopen it that point, but there are some
minor complications with that; it's not clear that there is much to be
won from doing that, though.)

Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Discussion: https://postgr.es/m/20200803234854.GA24158@alvherre.pgsql
parent 4669cacb
...@@ -157,6 +157,8 @@ typedef struct AlteredTableInfo ...@@ -157,6 +157,8 @@ typedef struct AlteredTableInfo
Oid relid; /* Relation to work on */ Oid relid; /* Relation to work on */
char relkind; /* Its relkind */ char relkind; /* Its relkind */
TupleDesc oldDesc; /* Pre-modification tuple descriptor */ TupleDesc oldDesc; /* Pre-modification tuple descriptor */
/* Transiently set during Phase 2, normally set to NULL */
Relation rel;
/* Information saved by Phase 1 for Phase 2: */ /* Information saved by Phase 1 for Phase 2: */
List *subcmds[AT_NUM_PASSES]; /* Lists of AlterTableCmd */ List *subcmds[AT_NUM_PASSES]; /* Lists of AlterTableCmd */
/* Information saved by Phases 1/2 for Phase 3: */ /* Information saved by Phases 1/2 for Phase 3: */
...@@ -354,7 +356,7 @@ static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, ...@@ -354,7 +356,7 @@ static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
AlterTableUtilityContext *context); AlterTableUtilityContext *context);
static void ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, static void ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode,
AlterTableUtilityContext *context); AlterTableUtilityContext *context);
static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, static void ATExecCmd(List **wqueue, AlteredTableInfo *tab,
AlterTableCmd *cmd, LOCKMODE lockmode, int cur_pass, AlterTableCmd *cmd, LOCKMODE lockmode, int cur_pass,
AlterTableUtilityContext *context); AlterTableUtilityContext *context);
static AlterTableCmd *ATParseTransformCmd(List **wqueue, AlteredTableInfo *tab, static AlterTableCmd *ATParseTransformCmd(List **wqueue, AlteredTableInfo *tab,
...@@ -4569,7 +4571,6 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, ...@@ -4569,7 +4571,6 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode,
{ {
AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab); AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
List *subcmds = tab->subcmds[pass]; List *subcmds = tab->subcmds[pass];
Relation rel;
ListCell *lcmd; ListCell *lcmd;
if (subcmds == NIL) if (subcmds == NIL)
...@@ -4578,10 +4579,10 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, ...@@ -4578,10 +4579,10 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode,
/* /*
* Appropriate lock was obtained by phase 1, needn't get it again * Appropriate lock was obtained by phase 1, needn't get it again
*/ */
rel = relation_open(tab->relid, NoLock); tab->rel = relation_open(tab->relid, NoLock);
foreach(lcmd, subcmds) foreach(lcmd, subcmds)
ATExecCmd(wqueue, tab, rel, ATExecCmd(wqueue, tab,
castNode(AlterTableCmd, lfirst(lcmd)), castNode(AlterTableCmd, lfirst(lcmd)),
lockmode, pass, context); lockmode, pass, context);
...@@ -4593,7 +4594,11 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, ...@@ -4593,7 +4594,11 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode,
if (pass == AT_PASS_ALTER_TYPE) if (pass == AT_PASS_ALTER_TYPE)
ATPostAlterTypeCleanup(wqueue, tab, lockmode); ATPostAlterTypeCleanup(wqueue, tab, lockmode);
relation_close(rel, NoLock); if (tab->rel)
{
relation_close(tab->rel, NoLock);
tab->rel = NULL;
}
} }
} }
...@@ -4619,11 +4624,12 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, ...@@ -4619,11 +4624,12 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode,
* ATExecCmd: dispatch a subcommand to appropriate execution routine * ATExecCmd: dispatch a subcommand to appropriate execution routine
*/ */
static void static void
ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, ATExecCmd(List **wqueue, AlteredTableInfo *tab,
AlterTableCmd *cmd, LOCKMODE lockmode, int cur_pass, AlterTableCmd *cmd, LOCKMODE lockmode, int cur_pass,
AlterTableUtilityContext *context) AlterTableUtilityContext *context)
{ {
ObjectAddress address = InvalidObjectAddress; ObjectAddress address = InvalidObjectAddress;
Relation rel = tab->rel;
switch (cmd->subtype) switch (cmd->subtype)
{ {
...@@ -5730,6 +5736,7 @@ ATGetQueueEntry(List **wqueue, Relation rel) ...@@ -5730,6 +5736,7 @@ ATGetQueueEntry(List **wqueue, Relation rel)
*/ */
tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo)); tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo));
tab->relid = relid; tab->relid = relid;
tab->rel = NULL; /* set later */
tab->relkind = rel->rd_rel->relkind; tab->relkind = rel->rd_rel->relkind;
tab->oldDesc = CreateTupleDescCopyConstr(RelationGetDescr(rel)); tab->oldDesc = CreateTupleDescCopyConstr(RelationGetDescr(rel));
tab->newrelpersistence = RELPERSISTENCE_PERMANENT; tab->newrelpersistence = RELPERSISTENCE_PERMANENT;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment