* Add a column to a table. The return value is the address of the * new column in the parent relation. * * cmd is pass-by-ref so that we can replace it with the parse-transformed * copy (but that happens only after we check for IF NOT EXISTS). */
| 8301 | * copy (but that happens only after we check for IF NOT EXISTS). |
| 8302 | */ |
| 8303 | static ObjectAddress |
| 8304 | ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, |
| 8305 | AlterTableCmd **cmd, |
| 8306 | bool recurse, bool recursing, |
| 8307 | LOCKMODE lockmode, int cur_pass, |
| 8308 | AlterTableUtilityContext *context) |
| 8309 | { |
| 8310 | Oid myrelid = RelationGetRelid(rel); |
| 8311 | ColumnDef *colDef = castNode(ColumnDef, (*cmd)->def); |
| 8312 | bool if_not_exists = (*cmd)->missing_ok; |
| 8313 | Relation pgclass, |
| 8314 | attrdesc; |
| 8315 | HeapTuple reltup; |
| 8316 | FormData_pg_attribute attribute; |
| 8317 | int newattnum; |
| 8318 | char relkind; |
| 8319 | HeapTuple typeTuple; |
| 8320 | Oid typeOid; |
| 8321 | int32 typmod; |
| 8322 | Oid collOid; |
| 8323 | Form_pg_type tform; |
| 8324 | Expr *defval; |
| 8325 | List *children; |
| 8326 | ListCell *child; |
| 8327 | AlterTableCmd *childcmd; |
| 8328 | AclResult aclresult; |
| 8329 | ObjectAddress address; |
| 8330 | TupleDesc tupdesc; |
| 8331 | FormData_pg_attribute *aattr[] = {&attribute}; |
| 8332 | |
| 8333 | /* At top level, permission check was done in ATPrepCmd, else do it */ |
| 8334 | if (recursing) |
| 8335 | ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); |
| 8336 | |
| 8337 | if (rel->rd_rel->relispartition && !recursing) |
| 8338 | ereport(ERROR, |
| 8339 | (errcode(ERRCODE_WRONG_OBJECT_TYPE), |
| 8340 | errmsg("cannot add column to a partition"))); |
| 8341 | |
| 8342 | attrdesc = table_open(AttributeRelationId, RowExclusiveLock); |
| 8343 | |
| 8344 | /* |
| 8345 | * Are we adding the column to a recursion child? If so, check whether to |
| 8346 | * merge with an existing definition for the column. If we do merge, we |
| 8347 | * must not recurse. Children will already have the column, and recursing |
| 8348 | * into them would mess up attinhcount. |
| 8349 | */ |
| 8350 | if (colDef->inhcount > 0) |
| 8351 | { |
| 8352 | HeapTuple tuple; |
| 8353 | |
| 8354 | /* Does child already have a column by this name? */ |
| 8355 | tuple = SearchSysCacheCopyAttName(myrelid, colDef->colname); |
| 8356 | if (HeapTupleIsValid(tuple)) |
| 8357 | { |
| 8358 | Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple); |
| 8359 | Oid ctypeId; |
| 8360 | int32 ctypmod; |
no test coverage detected