On 23.11.23 15:13, Amul Sul wrote:
The exact sequencing of this seems to be tricky. It's clear that we
need to do it earlier than at the end. I also think it should be
strictly after AT_PASS_ALTER_TYPE so that the new expression can refer
to the new type of a column. It should also be after AT_PASS_ADD_COL,
so that the new expression can refer to any newly added column. But
then it's after AT_PASS_OLD_INDEX and AT_PASS_OLD_CONSTR, is that a
problem?
AT_PASS_ALTER_TYPE and AT_PASS_ADD_COL cannot be together, the ALTER TYPE
cannot see that column, I think we can adopt the samebehaviour.
With your v5 patch, I see the following behavior:
create table t1 (a int, b int generated always as (a + 1) stored);
alter table t1 add column c int, alter column b set expression as (a + c);
ERROR: 42703: column "c" does not exist
I think intuitively, this ought to work. Maybe just moving the new pass
after AT_PASS_ADD_COL would do it.
While looking at this, I figured that converting the AT_PASS_* macros to
an enum would make this code simpler and easier to follow. For patches
like yours you wouldn't have to renumber the whole list. We could put
this patch before yours if people agree with it.
I tried to reuse the code by borrowing code from ALTER TYPE, see if that
looks good to you.
But I have concerns, with that code reuse where we drop and re-add the
indexes
and constraints which seems unnecessary for SET EXPRESSION where column
attributes will stay the same. I don't know why ATLER TYPE does that for
index
since finish_heap_swap() anyway does reindexing. We could skip re-adding
index for SET EXPRESSION which would be fine but we could not skip the
re-addition of constraints, since rebuilding constraints for checking might
need a good amount of code copy especially for foreign key constraints.
Please have a look at the attached version, 0001 patch does the code
refactoring, and 0002 is the implementation, using the newly refactored
code to
re-add indexes and constraints for the validation. Added tests for the same.
This looks reasonable after a first reading. (I have found that using
git diff --patience makes the 0001 patch look more readable. Maybe
that's helpful.)From eac97b6f2a081f327d0649d35a346db0b4bb9d99 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 28 Nov 2023 12:04:03 +0100
Subject: [PATCH] Turn AT_PASS_* macros into an enum
---
src/backend/commands/tablecmds.c | 55 +++++++++++++++++---------------
src/tools/pgindent/typedefs.list | 1 +
2 files changed, 30 insertions(+), 26 deletions(-)
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 323d9bf870..7c675b834c 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -142,20 +142,24 @@ static List *on_commits = NIL;
* a pass determined by subcommand type.
*/
-#define AT_PASS_UNSET -1 /* UNSET will cause ERROR */
-#define AT_PASS_DROP 0 /* DROP (all flavors) */
-#define AT_PASS_ALTER_TYPE 1 /* ALTER COLUMN TYPE */
-#define AT_PASS_OLD_INDEX 2 /* re-add existing indexes */
-#define AT_PASS_OLD_CONSTR 3 /* re-add existing constraints
*/
-/* We could support a RENAME COLUMN pass here, but not currently used */
-#define AT_PASS_ADD_COL 4 /* ADD COLUMN */
-#define AT_PASS_ADD_CONSTR 5 /* ADD constraints (initial
examination) */
-#define AT_PASS_COL_ATTRS 6 /* set column attributes, eg
NOT NULL */
-#define AT_PASS_ADD_INDEXCONSTR 7 /* ADD index-based constraints
*/
-#define AT_PASS_ADD_INDEX 8 /* ADD indexes */
-#define AT_PASS_ADD_OTHERCONSTR 9 /* ADD other constraints,
defaults */
-#define AT_PASS_MISC 10 /* other stuff */
-#define AT_NUM_PASSES 11
+typedef enum AlterTablePass
+{
+ AT_PASS_UNSET = -1, /* UNSET will cause ERROR */
+ AT_PASS_DROP, /* DROP (all flavors) */
+ AT_PASS_ALTER_TYPE, /* ALTER COLUMN TYPE */
+ AT_PASS_OLD_INDEX, /* re-add existing indexes */
+ AT_PASS_OLD_CONSTR, /* re-add existing constraints
*/
+ /* We could support a RENAME COLUMN pass here, but not currently used */
+ AT_PASS_ADD_COL, /* ADD COLUMN */
+ AT_PASS_ADD_CONSTR, /* ADD constraints (initial
examination) */
+ AT_PASS_COL_ATTRS, /* set column attributes, eg
NOT NULL */
+ AT_PASS_ADD_INDEXCONSTR, /* ADD index-based constraints */
+ AT_PASS_ADD_INDEX, /* ADD indexes */
+ AT_PASS_ADD_OTHERCONSTR, /* ADD other constraints, defaults */
+ AT_PASS_MISC, /* other stuff */
+} AlterTablePass;
+
+#define AT_NUM_PASSES (AT_PASS_MISC + 1)
typedef struct AlteredTableInfo
{
@@ -399,12 +403,12 @@ static void ATPrepCmd(List **wqueue, Relation rel,
AlterTableCmd *cmd,
static void ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode,
AlterTableUtilityContext *context);
static void ATExecCmd(List **wqueue, AlteredTableInfo *tab,
- AlterTableCmd *cmd, LOCKMODE
lockmode, int cur_pass,
+ AlterTableCmd *cmd, LOCKMODE
lockmode, AlterTablePass cur_pass,
AlterTableUtilityContext *context);
static AlterTableCmd *ATParseTransformCmd(List **wqueue, AlteredTableInfo *tab,
Relation rel, AlterTableCmd *cmd,
bool recurse, LOCKMODE lockmode,
-
int cur_pass,
+
AlterTablePass cur_pass,
AlterTableUtilityContext *context);
static void ATRewriteTables(AlterTableStmt *parsetree,
List **wqueue, LOCKMODE
lockmode,
@@ -427,7 +431,7 @@ static void ATPrepAddColumn(List **wqueue, Relation rel,
bool recurse, bool recu
static ObjectAddress ATExecAddColumn(List **wqueue, AlteredTableInfo *tab,
Relation rel, AlterTableCmd **cmd,
bool
recurse, bool recursing,
-
LOCKMODE lockmode, int cur_pass,
+
LOCKMODE lockmode, AlterTablePass cur_pass,
AlterTableUtilityContext *context);
static bool check_for_column_name_collision(Relation rel, const char *colname,
bool if_not_exists);
@@ -565,7 +569,7 @@ static void ATPostAlterTypeCleanup(List **wqueue,
AlteredTableInfo *tab,
static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId,
char *cmd,
List **wqueue, LOCKMODE lockmode,
bool rewrite);
-static void RebuildConstraintComment(AlteredTableInfo *tab, int pass,
+static void RebuildConstraintComment(AlteredTableInfo *tab, AlterTablePass
pass,
Oid
objid, Relation rel, List *domname,
const
char *conname);
static void TryReuseIndex(Oid oldId, IndexStmt *stmt);
@@ -4742,7 +4746,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
AlterTableUtilityContext *context)
{
AlteredTableInfo *tab;
- int pass = AT_PASS_UNSET;
+ AlterTablePass pass;
/* Find or create work queue entry for this table */
tab = ATGetQueueEntry(wqueue, rel);
@@ -5116,7 +5120,6 @@ static void
ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode,
AlterTableUtilityContext *context)
{
- int pass;
ListCell *ltab;
/*
@@ -5126,7 +5129,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode,
* re-adding of the foreign key constraint to the other table). Work
can
* only be propagated into later passes, however.
*/
- for (pass = 0; pass < AT_NUM_PASSES; pass++)
+ for (AlterTablePass pass = 0; pass <= AT_NUM_PASSES; pass++)
{
/* Go through each table that needs to be processed */
foreach(ltab, *wqueue)
@@ -5189,7 +5192,7 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode,
*/
static void
ATExecCmd(List **wqueue, AlteredTableInfo *tab,
- AlterTableCmd *cmd, LOCKMODE lockmode, int cur_pass,
+ AlterTableCmd *cmd, LOCKMODE lockmode, AlterTablePass
cur_pass,
AlterTableUtilityContext *context)
{
ObjectAddress address = InvalidObjectAddress;
@@ -5516,7 +5519,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab,
static AlterTableCmd *
ATParseTransformCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
AlterTableCmd *cmd, bool recurse,
LOCKMODE lockmode,
- int cur_pass, AlterTableUtilityContext
*context)
+ AlterTablePass cur_pass,
AlterTableUtilityContext *context)
{
AlterTableCmd *newcmd = NULL;
AlterTableStmt *atstmt = makeNode(AlterTableStmt);
@@ -5554,7 +5557,7 @@ ATParseTransformCmd(List **wqueue, AlteredTableInfo *tab,
Relation rel,
foreach(lc, atstmt->cmds)
{
AlterTableCmd *cmd2 = lfirst_node(AlterTableCmd, lc);
- int pass;
+ AlterTablePass pass;
/*
* This switch need only cover the subcommand types that can be
added
@@ -6959,7 +6962,7 @@ ATPrepAddColumn(List **wqueue, Relation rel, bool
recurse, bool recursing,
static ObjectAddress
ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
AlterTableCmd **cmd, bool recurse, bool
recursing,
- LOCKMODE lockmode, int cur_pass,
+ LOCKMODE lockmode, AlterTablePass cur_pass,
AlterTableUtilityContext *context)
{
Oid myrelid = RelationGetRelid(rel);
@@ -14235,7 +14238,7 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid
refRelId, char *cmd,
* entry; but callers already have them so might as well pass them.)
*/
static void
-RebuildConstraintComment(AlteredTableInfo *tab, int pass, Oid objid,
+RebuildConstraintComment(AlteredTableInfo *tab, AlterTablePass pass, Oid objid,
Relation rel, List *domname,
const char *conname)
{
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index dba3498a13..404a800fe4 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -97,6 +97,7 @@ AlterTSConfigurationStmt
AlterTSDictionaryStmt
AlterTableCmd
AlterTableMoveAllStmt
+AlterTablePass
AlterTableSpaceOptionsStmt
AlterTableStmt
AlterTableType
--
2.43.0