* Return the address of the modified column. If the column was already NOT * NULL, InvalidObjectAddress is returned. */
| 9211 | * NULL, InvalidObjectAddress is returned. |
| 9212 | */ |
| 9213 | static ObjectAddress |
| 9214 | ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, |
| 9215 | const char *colName, LOCKMODE lockmode) |
| 9216 | { |
| 9217 | HeapTuple tuple; |
| 9218 | AttrNumber attnum; |
| 9219 | Relation attr_rel; |
| 9220 | ObjectAddress address; |
| 9221 | |
| 9222 | /* |
| 9223 | * lookup the attribute |
| 9224 | */ |
| 9225 | attr_rel = table_open(AttributeRelationId, RowExclusiveLock); |
| 9226 | |
| 9227 | tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName); |
| 9228 | |
| 9229 | if (!HeapTupleIsValid(tuple)) |
| 9230 | ereport(ERROR, |
| 9231 | (errcode(ERRCODE_UNDEFINED_COLUMN), |
| 9232 | errmsg("column \"%s\" of relation \"%s\" does not exist", |
| 9233 | colName, RelationGetRelationName(rel)))); |
| 9234 | |
| 9235 | attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; |
| 9236 | |
| 9237 | /* Prevent them from altering a system attribute */ |
| 9238 | if (attnum <= 0) |
| 9239 | ereport(ERROR, |
| 9240 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 9241 | errmsg("cannot alter system column \"%s\"", |
| 9242 | colName))); |
| 9243 | |
| 9244 | /* |
| 9245 | * Okay, actually perform the catalog change ... if needed |
| 9246 | */ |
| 9247 | if (!((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull) |
| 9248 | { |
| 9249 | ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = true; |
| 9250 | |
| 9251 | CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple); |
| 9252 | |
| 9253 | /* |
| 9254 | * Ordinarily phase 3 must ensure that no NULLs exist in columns that |
| 9255 | * are set NOT NULL; however, if we can find a constraint which proves |
| 9256 | * this then we can skip that. We needn't bother looking if we've |
| 9257 | * already found that we must verify some other NOT NULL constraint. |
| 9258 | */ |
| 9259 | if (!tab->verify_new_notnull && |
| 9260 | !NotNullImpliedByRelConstraints(rel, (Form_pg_attribute) GETSTRUCT(tuple))) |
| 9261 | { |
| 9262 | /* Tell Phase 3 it needs to test the constraint */ |
| 9263 | tab->verify_new_notnull = true; |
| 9264 | } |
| 9265 | |
| 9266 | ObjectAddressSubSet(address, RelationRelationId, |
| 9267 | RelationGetRelid(rel), attnum); |
| 9268 | } |
| 9269 | else |
| 9270 | address = InvalidObjectAddress; |
no test coverage detected