blob: b919179b8dbb0b9e8453ff39025562349a628737 [file] [log] [blame]
/*-------------------------------------------------------------------------
*
* altertablenodes.h
* definitions for ALTER TABLE subcommands
*
* In PostgreSQL, these are in tablecmds.c, but in GPDB, they need to be
* exposed to out/readfunc.c, because we need support for serializing
* these. Also, the structs are Nodes in GPDB for the same reason.
*
* NOTE: If new fields are added to these structs, remember to update
* outfuncs.c/readfuncs.c
*
* Portions Copyright (c) 2006-2009, Greenplum inc
* Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates.
* Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/nodes/altertablenodes.h
*
*-------------------------------------------------------------------------
*/
#ifndef ALTERTABLENODES_H
#define ALTERTABLENODES_H
/*
* GPDB: Moved here from tablecmds.c
*
* State information for ALTER TABLE
*
* The pending-work queue for an ALTER TABLE is a List of AlteredTableInfo
* structs, one for each table modified by the operation (the named table
* plus any child tables that are affected). We save lists of subcommands
* to apply to this table (possibly modified by parse transformation steps);
* these lists will be executed in Phase 2. If a Phase 3 step is needed,
* necessary information is stored in the constraints and newvals lists.
*
* Phase 2 is divided into multiple passes; subcommands are executed in
* 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 other column attributes */
#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 struct AlteredTableInfo
{
NodeTag type;
/* Information saved before any work commences: */
Oid relid; /* Relation to work on */
char relkind; /* Its relkind */
TupleDesc oldDesc; /* Pre-modification tuple descriptor */
/*
* Transiently set during Phase 2, normally set to NULL.
*
* ATRewriteCatalogs sets this when it starts, and closes when ATExecCmd
* returns control. This can be exploited by ATExecCmd subroutines to
* close/reopen across transaction boundaries.
*/
Relation rel;
/* Information saved by Phase 1 for Phase 2: */
List *subcmds[AT_NUM_PASSES]; /* Lists of AlterTableCmd */
/* Information saved by Phases 1/2 for Phase 3: */
List *constraints; /* List of NewConstraint */
List *newvals; /* List of NewColumnValue */
List *afterStmts; /* List of utility command parsetrees */
bool verify_new_notnull; /* T if we should recheck NOT NULL */
int rewrite; /* Reason for forced rewrite, if any */
Oid newAccessMethod; /* new access method; 0 means no change */
bool dist_opfamily_changed; /* T if changing datatype of distribution key column and new opclass is in different opfamily than old one */
Oid new_opclass; /* new opclass, if changing a distribution key column */
Oid newTableSpace; /* new tablespace; 0 means no change */
bool chgPersistence; /* T if SET LOGGED/UNLOGGED is used */
char newrelpersistence; /* if above is true */
Expr *partition_constraint; /* for attach partition validation */
/* true, if validating default due to some other attach/detach */
bool validate_default;
/* Objects to rebuild after completing ALTER TYPE operations */
List *changedConstraintOids; /* OIDs of constraints to rebuild */
List *changedConstraintDefs; /* string definitions of same */
List *changedIndexOids; /* OIDs of indexes to rebuild */
List *changedIndexDefs; /* string definitions of same */
char *replicaIdentityIndex; /* index to reset as REPLICA IDENTITY */
char *clusterOnIndex; /* index to use for CLUSTER */
List *changedStatisticsOids; /* OIDs of statistics to rebuild */
List *changedStatisticsDefs; /* string definitions of same */
/*
* Saved before/constraint list(list of list) in transformAlterTableStmt.
* `transformAlterTableStmt()` will not execute on QEs, so QD must
* dispatch these results to the QEs. The 2 fields are lists of list,
* whenever `transformAlterTableStmt()` is called, the QD saves the lists
* to the current `AlteredTableInfo` and the QE consumes the list item
* from `AlteredTableInfo` dispatched from QD.
*
* beforeStmtLists: transformAlterTableStmt() generates some utility
* commands to run before the current action. See the usage of
* ProcessUtilityForAlterTable. These utility commands should be
* generated in QD, because it needs to choose some names, like
* relation/index/sequence name. The QEs are not allowed to
* choose a name that is different to that in QD side. The
* BEFORE commands don't run all at one point like `afterStmts`,
* so we must exactly pick up the list of commands that was
* generated by QD at the same running sequence.
* constraintLists: transformAlterTableStmt() normally sets `atstmt.cmds`
* to the same cmd-list that passes in, but it will generate some
* new cmd-list driven by the constraint.
*/
List *beforeStmtLists;
List *constraintLists;
} AlteredTableInfo;
typedef struct ExprState ExprState;
/* Struct describing one new constraint to check in Phase 3 scan */
/* Note: new NOT NULL constraints are handled elsewhere */
typedef struct NewConstraint
{
NodeTag type;
char *name; /* Constraint name, or NULL if none */
ConstrType contype; /* CHECK or FOREIGN */
Oid refrelid; /* PK rel, if FOREIGN */
Oid refindid; /* OID of PK's index, if FOREIGN */
Oid conid; /* OID of pg_constraint entry, if FOREIGN */
Node *qual; /* Check expr or CONSTR_FOREIGN Constraint */
ExprState *qualstate; /* Execution state for CHECK expr */
} NewConstraint;
/*
* Struct describing one new column value that needs to be computed during
* Phase 3 copy (this could be either a new column with a non-null default, or
* a column that we're changing the type of). Columns without such an entry
* are just copied from the old table during ATRewriteTable. Note that the
* expr is an expression over *old* table values, except when is_generated
* is true; then it is an expression over columns of the *new* tuple.
*/
typedef struct NewColumnValue
{
NodeTag type;
AttrNumber attnum; /* which column */
Expr *expr; /* expression to compute */
ExprState *exprstate; /* execution state */
bool is_generated; /* is it a GENERATED expression? */
} NewColumnValue;
#endif /* ALTERTABLENODES_H */