at1.3w-tablecmds-enum.patch
text/plain
Filename: at1.3w-tablecmds-enum.patch
Type: text/plain
Part: 3
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/commands/tablecmds.c | 0 | 0 |
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 78262d8..63e2538 100644
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 129,134 **** static List *on_commits = NIL;
--- 129,137 ----
#define AT_PASS_MISC 8 /* other stuff */
#define AT_NUM_PASSES 9
+ /* Level of effort required in Phase 3 (ATRewriteTables). */
+ typedef enum { WORK_NONE = 0, WORK_SCAN = 1, WORK_REWRITE = 2 } WorkLevel;
+
typedef struct AlteredTableInfo
{
/* Information saved before any work commences: */
***************
*** 141,147 **** typedef struct AlteredTableInfo
List *constraints; /* List of NewConstraint */
List *newvals; /* List of NewColumnValue */
bool new_notnull; /* T if we added new NOT NULL constraints */
! bool new_changeoids; /* T if we added/dropped the OID column */
Oid newTableSpace; /* new tablespace; 0 means no change */
/* Objects to rebuild after completing ALTER TYPE operations */
List *changedConstraintOids; /* OIDs of constraints to rebuild */
--- 144,150 ----
List *constraints; /* List of NewConstraint */
List *newvals; /* List of NewColumnValue */
bool new_notnull; /* T if we added new NOT NULL constraints */
! WorkLevel worklevel; /* How much work shall we do on the heap? */
Oid newTableSpace; /* new tablespace; 0 means no change */
/* Objects to rebuild after completing ALTER TYPE operations */
List *changedConstraintOids; /* OIDs of constraints to rebuild */
***************
*** 3180,3190 **** ATRewriteTables(List **wqueue, LOCKMODE lockmode)
if (tab->relkind == RELKIND_FOREIGN_TABLE)
continue;
! /*
! * We only need to rewrite the table if at least one column needs to
! * be recomputed, or we are adding/removing the OID column.
! */
! if (tab->newvals != NIL || tab->new_changeoids)
{
/* Build a temporary relation and copy data */
Relation OldHeap;
--- 3183,3195 ----
if (tab->relkind == RELKIND_FOREIGN_TABLE)
continue;
! /* New NOT NULL constraints always require a scan. */
! if (tab->new_notnull)
! tab->worklevel = Max(tab->worklevel, WORK_SCAN);
!
! switch (tab->worklevel)
! {
! case WORK_REWRITE:
{
/* Build a temporary relation and copy data */
Relation OldHeap;
***************
*** 3194,3202 **** ATRewriteTables(List **wqueue, LOCKMODE lockmode)
OldHeap = heap_open(tab->relid, NoLock);
/*
! * We don't support rewriting of system catalogs; there are too
! * many corner cases and too little benefit. In particular this
! * is certainly not going to work for mapped catalogs.
*/
if (IsSystemRelation(OldHeap))
ereport(ERROR,
--- 3199,3207 ----
OldHeap = heap_open(tab->relid, NoLock);
/*
! * We don't support rewriting of system catalogs; there are
! * too many corner cases and too little benefit. In
! * particular, it would fail for mapped catalogs.
*/
if (IsSystemRelation(OldHeap))
ereport(ERROR,
***************
*** 3205,3212 **** ATRewriteTables(List **wqueue, LOCKMODE lockmode)
RelationGetRelationName(OldHeap))));
/*
! * Don't allow rewrite on temp tables of other backends ... their
! * local buffer manager is not going to cope.
*/
if (RELATION_IS_OTHER_TEMP(OldHeap))
ereport(ERROR,
--- 3210,3217 ----
RelationGetRelationName(OldHeap))));
/*
! * Don't allow rewrite on temp tables of other backends
! * ... their local buffer manager is not going to cope.
*/
if (RELATION_IS_OTHER_TEMP(OldHeap))
ereport(ERROR,
***************
*** 3214,3221 **** ATRewriteTables(List **wqueue, LOCKMODE lockmode)
errmsg("cannot rewrite temporary tables of other sessions")));
/*
! * Select destination tablespace (same as original unless user
! * requested a change)
*/
if (tab->newTableSpace)
NewTableSpace = tab->newTableSpace;
--- 3219,3226 ----
errmsg("cannot rewrite temporary tables of other sessions")));
/*
! * Select destination tablespace (same as original unless
! * user requested a change)
*/
if (tab->newTableSpace)
NewTableSpace = tab->newTableSpace;
***************
*** 3224,3265 **** ATRewriteTables(List **wqueue, LOCKMODE lockmode)
heap_close(OldHeap, NoLock);
! /* Create transient table that will receive the modified data */
OIDNewHeap = make_new_heap(tab->relid, NewTableSpace);
/*
* Copy the heap data into the new table with the desired
* modifications, and test the current data within the table
! * against new constraints generated by ALTER TABLE commands.
*/
ATRewriteTable(tab, OIDNewHeap, lockmode);
/*
! * Swap the physical files of the old and new heaps, then rebuild
! * indexes and discard the old heap. We can use RecentXmin for
! * the table's new relfrozenxid because we rewrote all the tuples
! * in ATRewriteTable, so no older Xid remains in the table. Also,
! * we never try to swap toast tables by content, since we have no
! * interest in letting this code work on system catalogs.
*/
finish_heap_swap(tab->relid, OIDNewHeap,
false, false, true, RecentXmin);
}
! else
! {
! /*
! * Test the current data within the table against new constraints
! * generated by ALTER TABLE commands, but don't rebuild data.
! */
! if (tab->constraints != NIL || tab->new_notnull)
ATRewriteTable(tab, InvalidOid, lockmode);
/*
* If we had SET TABLESPACE but no reason to reconstruct tuples,
* just do a block-by-block copy.
*/
if (tab->newTableSpace)
ATExecSetTableSpace(tab->relid, tab->newTableSpace, lockmode);
}
}
--- 3229,3271 ----
heap_close(OldHeap, NoLock);
! /* Create transient table for the modified data */
OIDNewHeap = make_new_heap(tab->relid, NewTableSpace);
/*
* Copy the heap data into the new table with the desired
* modifications, and test the current data within the table
! * against new constraints.
*/
ATRewriteTable(tab, OIDNewHeap, lockmode);
/*
! * Swap the physical files of the old and new heaps, then
! * rebuild indexes and discard the old heap. We can use
! * RecentXmin for the table's new relfrozenxid because we
! * rewrote all the tuples in ATRewriteTable, so no older Xid
! * remains in the table. Also, we never try to swap toast
! * tables by content, since we have no interest in letting
! * this code work on system catalogs.
*/
finish_heap_swap(tab->relid, OIDNewHeap,
false, false, true, RecentXmin);
}
! break;
!
! case WORK_SCAN:
! /* Test the current table data. */
ATRewriteTable(tab, InvalidOid, lockmode);
+ break;
+ case WORK_NONE:
/*
* If we had SET TABLESPACE but no reason to reconstruct tuples,
* just do a block-by-block copy.
*/
if (tab->newTableSpace)
ATExecSetTableSpace(tab->relid, tab->newTableSpace, lockmode);
+ break;
}
}
***************
*** 3320,3326 **** ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
Relation newrel;
TupleDesc oldTupDesc;
TupleDesc newTupDesc;
- bool needscan = false;
List *notnull_attrs;
int i;
ListCell *l;
--- 3326,3331 ----
***************
*** 3328,3333 **** ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
--- 3333,3348 ----
CommandId mycid;
BulkInsertState bistate;
int hi_options;
+ ExprContext *econtext;
+ Datum *values;
+ bool *isnull;
+ TupleTableSlot *oldslot;
+ TupleTableSlot *newslot;
+ HeapScanDesc scan;
+ HeapTuple tuple;
+ MemoryContext oldCxt;
+ List *dropped_attrs = NIL;
+ ListCell *lc;
/*
* Open the relation(s). We have surely already locked the existing
***************
*** 3379,3385 **** ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
switch (con->contype)
{
case CONSTR_CHECK:
- needscan = true;
con->qualstate = (List *)
ExecPrepareExpr((Expr *) con->qual, estate);
break;
--- 3394,3399 ----
***************
*** 3414,3436 **** ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
!newTupDesc->attrs[i]->attisdropped)
notnull_attrs = lappend_int(notnull_attrs, i);
}
- if (notnull_attrs)
- needscan = true;
}
- if (newrel || needscan)
- {
- ExprContext *econtext;
- Datum *values;
- bool *isnull;
- TupleTableSlot *oldslot;
- TupleTableSlot *newslot;
- HeapScanDesc scan;
- HeapTuple tuple;
- MemoryContext oldCxt;
- List *dropped_attrs = NIL;
- ListCell *lc;
-
if (newrel)
ereport(DEBUG1,
(errmsg("Rewriting table \"%s\"",
--- 3428,3435 ----
***************
*** 3574,3580 **** ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
ExecDropSingleTupleTableSlot(oldslot);
ExecDropSingleTupleTableSlot(newslot);
- }
FreeExecutorState(estate);
--- 3573,3578 ----
***************
*** 4271,4276 **** ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
--- 4269,4275 ----
newval->expr = defval;
tab->newvals = lappend(tab->newvals, newval);
+ tab->worklevel = WORK_REWRITE;
}
/*
***************
*** 4288,4294 **** ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
*/
if (isOid)
{
! tab->new_changeoids = true;
/* See comments in ATExecDropColumn. */
find_composite_type_dependencies(rel->rd_rel->reltype,
--- 4287,4293 ----
*/
if (isOid)
{
! tab->worklevel = WORK_REWRITE;
/* See comments in ATExecDropColumn. */
find_composite_type_dependencies(rel->rd_rel->reltype,
***************
*** 4967,4973 **** ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
tab = ATGetQueueEntry(wqueue, rel);
/* Tell Phase 3 to physically remove the OID column */
! tab->new_changeoids = true;
/*
* We would also need to rewrite all tables using this table's rowtype
--- 4966,4972 ----
tab = ATGetQueueEntry(wqueue, rel);
/* Tell Phase 3 to physically remove the OID column */
! tab->worklevel = WORK_REWRITE;
/*
* We would also need to rewrite all tables using this table's rowtype
***************
*** 5000,5006 **** ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
/* suppress schema rights check when rebuilding existing index */
check_rights = !is_rebuild;
/* skip index build if phase 3 will have to rewrite table anyway */
! skip_build = (tab->newvals != NIL);
/* suppress notices when rebuilding existing index */
quiet = is_rebuild;
--- 4999,5005 ----
/* suppress schema rights check when rebuilding existing index */
check_rights = !is_rebuild;
/* skip index build if phase 3 will have to rewrite table anyway */
! skip_build = (tab->worklevel == WORK_REWRITE);
/* suppress notices when rebuilding existing index */
quiet = is_rebuild;
***************
*** 5139,5144 **** ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
--- 5138,5144 ----
newcon->qual = (Node *) make_ands_implicit((Expr *) ccon->expr);
tab->constraints = lappend(tab->constraints, newcon);
+ tab->worklevel = Max(tab->worklevel, WORK_SCAN);
/* Save the actually assigned name if it was defaulted */
if (constr->conname == NULL)
***************
*** 5485,5490 **** ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
--- 5485,5494 ----
newcon->qual = (Node *) fkconstraint;
tab->constraints = lappend(tab->constraints, newcon);
+ /*
+ * No need to set tab->worklevel; foreign key validation is a distinct
+ * aspect of Phase 3.
+ */
}
/*
***************
*** 6369,6374 **** ATPrepAlterColumnType(List **wqueue,
--- 6373,6379 ----
newval->expr = (Expr *) transform;
tab->newvals = lappend(tab->newvals, newval);
+ tab->worklevel = WORK_REWRITE;
/*
* If we need to rewrite or scan this table, tables using its rowtype as