mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 00:02:04 -04:00
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
This commit is contained in:
parent
882887e9b4
commit
a1604237a6
@ -6984,22 +6984,15 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
|
|||||||
Relation pgclass,
|
Relation pgclass,
|
||||||
attrdesc;
|
attrdesc;
|
||||||
HeapTuple reltup;
|
HeapTuple reltup;
|
||||||
FormData_pg_attribute attribute;
|
Form_pg_attribute attribute;
|
||||||
int newattnum;
|
int newattnum;
|
||||||
char relkind;
|
char relkind;
|
||||||
HeapTuple typeTuple;
|
|
||||||
Oid typeOid;
|
|
||||||
int32 typmod;
|
|
||||||
Oid collOid;
|
|
||||||
Form_pg_type tform;
|
|
||||||
Expr *defval;
|
Expr *defval;
|
||||||
List *children;
|
List *children;
|
||||||
ListCell *child;
|
ListCell *child;
|
||||||
AlterTableCmd *childcmd;
|
AlterTableCmd *childcmd;
|
||||||
AclResult aclresult;
|
|
||||||
ObjectAddress address;
|
ObjectAddress address;
|
||||||
TupleDesc tupdesc;
|
TupleDesc tupdesc;
|
||||||
FormData_pg_attribute *aattr[] = {&attribute};
|
|
||||||
|
|
||||||
/* At top level, permission check was done in ATPrepCmd, else do it */
|
/* At top level, permission check was done in ATPrepCmd, else do it */
|
||||||
if (recursing)
|
if (recursing)
|
||||||
@ -7121,59 +7114,21 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
|
|||||||
errmsg("tables can have at most %d columns",
|
errmsg("tables can have at most %d columns",
|
||||||
MaxHeapAttributeNumber)));
|
MaxHeapAttributeNumber)));
|
||||||
|
|
||||||
typeTuple = typenameType(NULL, colDef->typeName, &typmod);
|
/*
|
||||||
tform = (Form_pg_type) GETSTRUCT(typeTuple);
|
* Construct new attribute's pg_attribute entry.
|
||||||
typeOid = tform->oid;
|
*/
|
||||||
|
tupdesc = BuildDescForRelation(list_make1(colDef));
|
||||||
|
|
||||||
aclresult = object_aclcheck(TypeRelationId, typeOid, GetUserId(), ACL_USAGE);
|
attribute = TupleDescAttr(tupdesc, 0);
|
||||||
if (aclresult != ACLCHECK_OK)
|
|
||||||
aclcheck_error_type(aclresult, typeOid);
|
|
||||||
|
|
||||||
collOid = GetColumnDefCollation(NULL, colDef, typeOid);
|
/* Fix up attribute number */
|
||||||
|
attribute->attnum = newattnum;
|
||||||
|
|
||||||
/* make sure datatype is legal for a column */
|
/* make sure datatype is legal for a column */
|
||||||
CheckAttributeType(colDef->colname, typeOid, collOid,
|
CheckAttributeType(NameStr(attribute->attname), attribute->atttypid, attribute->attcollation,
|
||||||
list_make1_oid(rel->rd_rel->reltype),
|
list_make1_oid(rel->rd_rel->reltype),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
/*
|
|
||||||
* Construct new attribute's pg_attribute entry. (Variable-length fields
|
|
||||||
* are handled by InsertPgAttributeTuples().)
|
|
||||||
*/
|
|
||||||
attribute.attrelid = myrelid;
|
|
||||||
namestrcpy(&(attribute.attname), colDef->colname);
|
|
||||||
attribute.atttypid = typeOid;
|
|
||||||
attribute.attstattarget = -1;
|
|
||||||
attribute.attlen = tform->typlen;
|
|
||||||
attribute.attnum = newattnum;
|
|
||||||
if (list_length(colDef->typeName->arrayBounds) > PG_INT16_MAX)
|
|
||||||
ereport(ERROR,
|
|
||||||
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
|
||||||
errmsg("too many array dimensions"));
|
|
||||||
attribute.attndims = list_length(colDef->typeName->arrayBounds);
|
|
||||||
attribute.atttypmod = typmod;
|
|
||||||
attribute.attbyval = tform->typbyval;
|
|
||||||
attribute.attalign = tform->typalign;
|
|
||||||
if (colDef->storage_name)
|
|
||||||
attribute.attstorage = GetAttributeStorage(typeOid, colDef->storage_name);
|
|
||||||
else
|
|
||||||
attribute.attstorage = tform->typstorage;
|
|
||||||
attribute.attcompression = GetAttributeCompression(typeOid,
|
|
||||||
colDef->compression);
|
|
||||||
attribute.attnotnull = colDef->is_not_null;
|
|
||||||
attribute.atthasdef = false;
|
|
||||||
attribute.atthasmissing = false;
|
|
||||||
attribute.attidentity = colDef->identity;
|
|
||||||
attribute.attgenerated = colDef->generated;
|
|
||||||
attribute.attisdropped = false;
|
|
||||||
attribute.attislocal = colDef->is_local;
|
|
||||||
attribute.attinhcount = colDef->inhcount;
|
|
||||||
attribute.attcollation = collOid;
|
|
||||||
|
|
||||||
ReleaseSysCache(typeTuple);
|
|
||||||
|
|
||||||
tupdesc = CreateTupleDesc(lengthof(aattr), (FormData_pg_attribute **) &aattr);
|
|
||||||
|
|
||||||
InsertPgAttributeTuples(attrdesc, tupdesc, myrelid, NULL, NULL);
|
InsertPgAttributeTuples(attrdesc, tupdesc, myrelid, NULL, NULL);
|
||||||
|
|
||||||
table_close(attrdesc, RowExclusiveLock);
|
table_close(attrdesc, RowExclusiveLock);
|
||||||
@ -7203,7 +7158,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
|
|||||||
RawColumnDefault *rawEnt;
|
RawColumnDefault *rawEnt;
|
||||||
|
|
||||||
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
|
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
|
||||||
rawEnt->attnum = attribute.attnum;
|
rawEnt->attnum = attribute->attnum;
|
||||||
rawEnt->raw_default = copyObject(colDef->raw_default);
|
rawEnt->raw_default = copyObject(colDef->raw_default);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -7277,7 +7232,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
|
|||||||
NextValueExpr *nve = makeNode(NextValueExpr);
|
NextValueExpr *nve = makeNode(NextValueExpr);
|
||||||
|
|
||||||
nve->seqid = RangeVarGetRelid(colDef->identitySequence, NoLock, false);
|
nve->seqid = RangeVarGetRelid(colDef->identitySequence, NoLock, false);
|
||||||
nve->typeId = typeOid;
|
nve->typeId = attribute->atttypid;
|
||||||
|
|
||||||
defval = (Expr *) nve;
|
defval = (Expr *) nve;
|
||||||
|
|
||||||
@ -7285,23 +7240,23 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
|
|||||||
tab->rewrite |= AT_REWRITE_DEFAULT_VAL;
|
tab->rewrite |= AT_REWRITE_DEFAULT_VAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
defval = (Expr *) build_column_default(rel, attribute.attnum);
|
defval = (Expr *) build_column_default(rel, attribute->attnum);
|
||||||
|
|
||||||
if (!defval && DomainHasConstraints(typeOid))
|
if (!defval && DomainHasConstraints(attribute->atttypid))
|
||||||
{
|
{
|
||||||
Oid baseTypeId;
|
Oid baseTypeId;
|
||||||
int32 baseTypeMod;
|
int32 baseTypeMod;
|
||||||
Oid baseTypeColl;
|
Oid baseTypeColl;
|
||||||
|
|
||||||
baseTypeMod = typmod;
|
baseTypeMod = attribute->atttypmod;
|
||||||
baseTypeId = getBaseTypeAndTypmod(typeOid, &baseTypeMod);
|
baseTypeId = getBaseTypeAndTypmod(attribute->atttypid, &baseTypeMod);
|
||||||
baseTypeColl = get_typcollation(baseTypeId);
|
baseTypeColl = get_typcollation(baseTypeId);
|
||||||
defval = (Expr *) makeNullConst(baseTypeId, baseTypeMod, baseTypeColl);
|
defval = (Expr *) makeNullConst(baseTypeId, baseTypeMod, baseTypeColl);
|
||||||
defval = (Expr *) coerce_to_target_type(NULL,
|
defval = (Expr *) coerce_to_target_type(NULL,
|
||||||
(Node *) defval,
|
(Node *) defval,
|
||||||
baseTypeId,
|
baseTypeId,
|
||||||
typeOid,
|
attribute->atttypid,
|
||||||
typmod,
|
attribute->atttypmod,
|
||||||
COERCION_ASSIGNMENT,
|
COERCION_ASSIGNMENT,
|
||||||
COERCE_IMPLICIT_CAST,
|
COERCE_IMPLICIT_CAST,
|
||||||
-1);
|
-1);
|
||||||
@ -7314,17 +7269,17 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
|
|||||||
NewColumnValue *newval;
|
NewColumnValue *newval;
|
||||||
|
|
||||||
newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
|
newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
|
||||||
newval->attnum = attribute.attnum;
|
newval->attnum = attribute->attnum;
|
||||||
newval->expr = expression_planner(defval);
|
newval->expr = expression_planner(defval);
|
||||||
newval->is_generated = (colDef->generated != '\0');
|
newval->is_generated = (colDef->generated != '\0');
|
||||||
|
|
||||||
tab->newvals = lappend(tab->newvals, newval);
|
tab->newvals = lappend(tab->newvals, newval);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DomainHasConstraints(typeOid))
|
if (DomainHasConstraints(attribute->atttypid))
|
||||||
tab->rewrite |= AT_REWRITE_DEFAULT_VAL;
|
tab->rewrite |= AT_REWRITE_DEFAULT_VAL;
|
||||||
|
|
||||||
if (!TupleDescAttr(rel->rd_att, attribute.attnum - 1)->atthasmissing)
|
if (!TupleDescAttr(rel->rd_att, attribute->attnum - 1)->atthasmissing)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If the new column is NOT NULL, and there is no missing value,
|
* If the new column is NOT NULL, and there is no missing value,
|
||||||
@ -7337,8 +7292,8 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
|
|||||||
/*
|
/*
|
||||||
* Add needed dependency entries for the new column.
|
* Add needed dependency entries for the new column.
|
||||||
*/
|
*/
|
||||||
add_column_datatype_dependency(myrelid, newattnum, attribute.atttypid);
|
add_column_datatype_dependency(myrelid, newattnum, attribute->atttypid);
|
||||||
add_column_collation_dependency(myrelid, newattnum, attribute.attcollation);
|
add_column_collation_dependency(myrelid, newattnum, attribute->attcollation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Propagate to children as appropriate. Unlike most other ALTER
|
* Propagate to children as appropriate. Unlike most other ALTER
|
||||||
|
Loading…
x
Reference in New Issue
Block a user