Skip to content

Commit a160423

Browse files
committed
Refactor ATExecAddColumn() to use BuildDescForRelation()
BuildDescForRelation() has all the knowledge for converting a ColumnDef into pg_attribute/tuple descriptor. ATExecAddColumn() can make use of that, instead of duplicating all that logic. We just pass a one-element list of ColumnDef and we get back exactly the data structure we need. Note that we don't even need to touch BuildDescForRelation() to make this work. Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://www.postgresql.org/message-id/flat/52a125e4-ff9a-95f5-9f61-b87cf447e4da@eisentraut.org
1 parent 882887e commit a160423

File tree

1 file changed

+22
-67
lines changed

1 file changed

+22
-67
lines changed

src/backend/commands/tablecmds.c

Lines changed: 22 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -6984,22 +6984,15 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
69846984
Relation pgclass,
69856985
attrdesc;
69866986
HeapTuple reltup;
6987-
FormData_pg_attribute attribute;
6987+
Form_pg_attribute attribute;
69886988
int newattnum;
69896989
char relkind;
6990-
HeapTuple typeTuple;
6991-
Oid typeOid;
6992-
int32 typmod;
6993-
Oid collOid;
6994-
Form_pg_type tform;
69956990
Expr *defval;
69966991
List *children;
69976992
ListCell *child;
69986993
AlterTableCmd *childcmd;
6999-
AclResult aclresult;
70006994
ObjectAddress address;
70016995
TupleDesc tupdesc;
7002-
FormData_pg_attribute *aattr[] = {&attribute};
70036996

70046997
/* At top level, permission check was done in ATPrepCmd, else do it */
70056998
if (recursing)
@@ -7121,59 +7114,21 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
71217114
errmsg("tables can have at most %d columns",
71227115
MaxHeapAttributeNumber)));
71237116

7124-
typeTuple = typenameType(NULL, colDef->typeName, &typmod);
7125-
tform = (Form_pg_type) GETSTRUCT(typeTuple);
7126-
typeOid = tform->oid;
7117+
/*
7118+
* Construct new attribute's pg_attribute entry.
7119+
*/
7120+
tupdesc = BuildDescForRelation(list_make1(colDef));
71277121

7128-
aclresult = object_aclcheck(TypeRelationId, typeOid, GetUserId(), ACL_USAGE);
7129-
if (aclresult != ACLCHECK_OK)
7130-
aclcheck_error_type(aclresult, typeOid);
7122+
attribute = TupleDescAttr(tupdesc, 0);
71317123

7132-
collOid = GetColumnDefCollation(NULL, colDef, typeOid);
7124+
/* Fix up attribute number */
7125+
attribute->attnum = newattnum;
71337126

71347127
/* make sure datatype is legal for a column */
7135-
CheckAttributeType(colDef->colname, typeOid, collOid,
7128+
CheckAttributeType(NameStr(attribute->attname), attribute->atttypid, attribute->attcollation,
71367129
list_make1_oid(rel->rd_rel->reltype),
71377130
0);
71387131

7139-
/*
7140-
* Construct new attribute's pg_attribute entry. (Variable-length fields
7141-
* are handled by InsertPgAttributeTuples().)
7142-
*/
7143-
attribute.attrelid = myrelid;
7144-
namestrcpy(&(attribute.attname), colDef->colname);
7145-
attribute.atttypid = typeOid;
7146-
attribute.attstattarget = -1;
7147-
attribute.attlen = tform->typlen;
7148-
attribute.attnum = newattnum;
7149-
if (list_length(colDef->typeName->arrayBounds) > PG_INT16_MAX)
7150-
ereport(ERROR,
7151-
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
7152-
errmsg("too many array dimensions"));
7153-
attribute.attndims = list_length(colDef->typeName->arrayBounds);
7154-
attribute.atttypmod = typmod;
7155-
attribute.attbyval = tform->typbyval;
7156-
attribute.attalign = tform->typalign;
7157-
if (colDef->storage_name)
7158-
attribute.attstorage = GetAttributeStorage(typeOid, colDef->storage_name);
7159-
else
7160-
attribute.attstorage = tform->typstorage;
7161-
attribute.attcompression = GetAttributeCompression(typeOid,
7162-
colDef->compression);
7163-
attribute.attnotnull = colDef->is_not_null;
7164-
attribute.atthasdef = false;
7165-
attribute.atthasmissing = false;
7166-
attribute.attidentity = colDef->identity;
7167-
attribute.attgenerated = colDef->generated;
7168-
attribute.attisdropped = false;
7169-
attribute.attislocal = colDef->is_local;
7170-
attribute.attinhcount = colDef->inhcount;
7171-
attribute.attcollation = collOid;
7172-
7173-
ReleaseSysCache(typeTuple);
7174-
7175-
tupdesc = CreateTupleDesc(lengthof(aattr), (FormData_pg_attribute **) &aattr);
7176-
71777132
InsertPgAttributeTuples(attrdesc, tupdesc, myrelid, NULL, NULL);
71787133

71797134
table_close(attrdesc, RowExclusiveLock);
@@ -7203,7 +7158,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
72037158
RawColumnDefault *rawEnt;
72047159

72057160
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
7206-
rawEnt->attnum = attribute.attnum;
7161+
rawEnt->attnum = attribute->attnum;
72077162
rawEnt->raw_default = copyObject(colDef->raw_default);
72087163

72097164
/*
@@ -7277,31 +7232,31 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
72777232
NextValueExpr *nve = makeNode(NextValueExpr);
72787233

72797234
nve->seqid = RangeVarGetRelid(colDef->identitySequence, NoLock, false);
7280-
nve->typeId = typeOid;
7235+
nve->typeId = attribute->atttypid;
72817236

72827237
defval = (Expr *) nve;
72837238

72847239
/* must do a rewrite for identity columns */
72857240
tab->rewrite |= AT_REWRITE_DEFAULT_VAL;
72867241
}
72877242
else
7288-
defval = (Expr *) build_column_default(rel, attribute.attnum);
7243+
defval = (Expr *) build_column_default(rel, attribute->attnum);
72897244

7290-
if (!defval && DomainHasConstraints(typeOid))
7245+
if (!defval && DomainHasConstraints(attribute->atttypid))
72917246
{
72927247
Oid baseTypeId;
72937248
int32 baseTypeMod;
72947249
Oid baseTypeColl;
72957250

7296-
baseTypeMod = typmod;
7297-
baseTypeId = getBaseTypeAndTypmod(typeOid, &baseTypeMod);
7251+
baseTypeMod = attribute->atttypmod;
7252+
baseTypeId = getBaseTypeAndTypmod(attribute->atttypid, &baseTypeMod);
72987253
baseTypeColl = get_typcollation(baseTypeId);
72997254
defval = (Expr *) makeNullConst(baseTypeId, baseTypeMod, baseTypeColl);
73007255
defval = (Expr *) coerce_to_target_type(NULL,
73017256
(Node *) defval,
73027257
baseTypeId,
7303-
typeOid,
7304-
typmod,
7258+
attribute->atttypid,
7259+
attribute->atttypmod,
73057260
COERCION_ASSIGNMENT,
73067261
COERCE_IMPLICIT_CAST,
73077262
-1);
@@ -7314,17 +7269,17 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
73147269
NewColumnValue *newval;
73157270

73167271
newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
7317-
newval->attnum = attribute.attnum;
7272+
newval->attnum = attribute->attnum;
73187273
newval->expr = expression_planner(defval);
73197274
newval->is_generated = (colDef->generated != '\0');
73207275

73217276
tab->newvals = lappend(tab->newvals, newval);
73227277
}
73237278

7324-
if (DomainHasConstraints(typeOid))
7279+
if (DomainHasConstraints(attribute->atttypid))
73257280
tab->rewrite |= AT_REWRITE_DEFAULT_VAL;
73267281

7327-
if (!TupleDescAttr(rel->rd_att, attribute.attnum - 1)->atthasmissing)
7282+
if (!TupleDescAttr(rel->rd_att, attribute->attnum - 1)->atthasmissing)
73287283
{
73297284
/*
73307285
* If the new column is NOT NULL, and there is no missing value,
@@ -7337,8 +7292,8 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
73377292
/*
73387293
* Add needed dependency entries for the new column.
73397294
*/
7340-
add_column_datatype_dependency(myrelid, newattnum, attribute.atttypid);
7341-
add_column_collation_dependency(myrelid, newattnum, attribute.attcollation);
7295+
add_column_datatype_dependency(myrelid, newattnum, attribute->atttypid);
7296+
add_column_collation_dependency(myrelid, newattnum, attribute->attcollation);
73427297

73437298
/*
73447299
* Propagate to children as appropriate. Unlike most other ALTER

0 commit comments

Comments
 (0)