* ALTER TABLE OF * * Attach a table to a composite type, as though it had been created with CREATE * TABLE OF. All attname, atttypid, atttypmod and attcollation must match. The * subject table must not have inheritance parents. These restrictions ensure * that you cannot create a configuration impossible with CREATE TABLE OF alone. * * The address of the type is returned. */
| 19411 | * The address of the type is returned. |
| 19412 | */ |
| 19413 | static ObjectAddress |
| 19414 | ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) |
| 19415 | { |
| 19416 | Oid relid = RelationGetRelid(rel); |
| 19417 | Type typetuple; |
| 19418 | Form_pg_type typeform; |
| 19419 | Oid typeid; |
| 19420 | Relation inheritsRelation, |
| 19421 | relationRelation; |
| 19422 | SysScanDesc scan; |
| 19423 | ScanKeyData key; |
| 19424 | AttrNumber table_attno, |
| 19425 | type_attno; |
| 19426 | TupleDesc typeTupleDesc, |
| 19427 | tableTupleDesc; |
| 19428 | ObjectAddress tableobj, |
| 19429 | typeobj; |
| 19430 | HeapTuple classtuple; |
| 19431 | |
| 19432 | /* Validate the type. */ |
| 19433 | typetuple = typenameType(NULL, ofTypename, NULL); |
| 19434 | check_of_type(typetuple); |
| 19435 | typeform = (Form_pg_type) GETSTRUCT(typetuple); |
| 19436 | typeid = typeform->oid; |
| 19437 | |
| 19438 | /* Fail if the table has any inheritance parents. */ |
| 19439 | inheritsRelation = table_open(InheritsRelationId, AccessShareLock); |
| 19440 | ScanKeyInit(&key, |
| 19441 | Anum_pg_inherits_inhrelid, |
| 19442 | BTEqualStrategyNumber, F_OIDEQ, |
| 19443 | ObjectIdGetDatum(relid)); |
| 19444 | scan = systable_beginscan(inheritsRelation, InheritsRelidSeqnoIndexId, |
| 19445 | true, NULL, 1, &key); |
| 19446 | if (HeapTupleIsValid(systable_getnext(scan))) |
| 19447 | ereport(ERROR, |
| 19448 | (errcode(ERRCODE_WRONG_OBJECT_TYPE), |
| 19449 | errmsg("typed tables cannot inherit"))); |
| 19450 | systable_endscan(scan); |
| 19451 | table_close(inheritsRelation, AccessShareLock); |
| 19452 | |
| 19453 | /* |
| 19454 | * Check the tuple descriptors for compatibility. Unlike inheritance, we |
| 19455 | * require that the order also match. However, attnotnull need not match. |
| 19456 | */ |
| 19457 | typeTupleDesc = lookup_rowtype_tupdesc(typeid, -1); |
| 19458 | tableTupleDesc = RelationGetDescr(rel); |
| 19459 | table_attno = 1; |
| 19460 | for (type_attno = 1; type_attno <= typeTupleDesc->natts; type_attno++) |
| 19461 | { |
| 19462 | Form_pg_attribute type_attr, |
| 19463 | table_attr; |
| 19464 | const char *type_attname, |
| 19465 | *table_attname; |
| 19466 | |
| 19467 | /* Get the next non-dropped type attribute. */ |
| 19468 | type_attr = TupleDescAttr(typeTupleDesc, type_attno - 1); |
| 19469 | if (type_attr->attisdropped) |
| 19470 | continue; |
no test coverage detected