* ALTER TABLE ALTER COLUMN ADD IDENTITY * * Return the address of the affected column. */
| 9489 | * Return the address of the affected column. |
| 9490 | */ |
| 9491 | static ObjectAddress |
| 9492 | ATExecAddIdentity(Relation rel, const char *colName, |
| 9493 | Node *def, LOCKMODE lockmode) |
| 9494 | { |
| 9495 | Relation attrelation; |
| 9496 | HeapTuple tuple; |
| 9497 | Form_pg_attribute attTup; |
| 9498 | AttrNumber attnum; |
| 9499 | ObjectAddress address; |
| 9500 | ColumnDef *cdef = castNode(ColumnDef, def); |
| 9501 | |
| 9502 | attrelation = table_open(AttributeRelationId, RowExclusiveLock); |
| 9503 | |
| 9504 | tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName); |
| 9505 | if (!HeapTupleIsValid(tuple)) |
| 9506 | ereport(ERROR, |
| 9507 | (errcode(ERRCODE_UNDEFINED_COLUMN), |
| 9508 | errmsg("column \"%s\" of relation \"%s\" does not exist", |
| 9509 | colName, RelationGetRelationName(rel)))); |
| 9510 | attTup = (Form_pg_attribute) GETSTRUCT(tuple); |
| 9511 | attnum = attTup->attnum; |
| 9512 | |
| 9513 | /* Can't alter a system attribute */ |
| 9514 | if (attnum <= 0) |
| 9515 | ereport(ERROR, |
| 9516 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 9517 | errmsg("cannot alter system column \"%s\"", |
| 9518 | colName))); |
| 9519 | |
| 9520 | /* |
| 9521 | * Creating a column as identity implies NOT NULL, so adding the identity |
| 9522 | * to an existing column that is not NOT NULL would create a state that |
| 9523 | * cannot be reproduced without contortions. |
| 9524 | */ |
| 9525 | if (!attTup->attnotnull) |
| 9526 | ereport(ERROR, |
| 9527 | (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
| 9528 | errmsg("column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added", |
| 9529 | colName, RelationGetRelationName(rel)))); |
| 9530 | |
| 9531 | if (attTup->attidentity) |
| 9532 | ereport(ERROR, |
| 9533 | (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
| 9534 | errmsg("column \"%s\" of relation \"%s\" is already an identity column", |
| 9535 | colName, RelationGetRelationName(rel)))); |
| 9536 | |
| 9537 | if (attTup->atthasdef) |
| 9538 | ereport(ERROR, |
| 9539 | (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
| 9540 | errmsg("column \"%s\" of relation \"%s\" already has a default value", |
| 9541 | colName, RelationGetRelationName(rel)))); |
| 9542 | |
| 9543 | attTup->attidentity = cdef->identity; |
| 9544 | CatalogTupleUpdate(attrelation, &tuple->t_self, tuple); |
| 9545 | |
| 9546 | InvokeObjectPostAlterHook(RelationRelationId, |
| 9547 | RelationGetRelid(rel), |
| 9548 | attTup->attnum); |
no test coverage detected