* RelationBuildTupleDesc * * Form the relation's tuple descriptor from information in * the pg_attribute, pg_attrdef & pg_constraint system catalogs. */
| 539 | * the pg_attribute, pg_attrdef & pg_constraint system catalogs. |
| 540 | */ |
| 541 | static void |
| 542 | RelationBuildTupleDesc(Relation relation) |
| 543 | { |
| 544 | HeapTuple pg_attribute_tuple; |
| 545 | Relation pg_attribute_desc; |
| 546 | SysScanDesc pg_attribute_scan; |
| 547 | ScanKeyData skey[2]; |
| 548 | int need; |
| 549 | TupleConstr *constr; |
| 550 | AttrMissing *attrmiss = NULL; |
| 551 | int ndef = 0; |
| 552 | |
| 553 | /* fill rd_att's type ID fields (compare heap.c's AddNewRelationTuple) */ |
| 554 | relation->rd_att->tdtypeid = |
| 555 | relation->rd_rel->reltype ? relation->rd_rel->reltype : RECORDOID; |
| 556 | relation->rd_att->tdtypmod = -1; /* just to be sure */ |
| 557 | |
| 558 | constr = (TupleConstr *) MemoryContextAllocZero(CacheMemoryContext, |
| 559 | sizeof(TupleConstr)); |
| 560 | constr->has_not_null = false; |
| 561 | constr->has_generated_stored = false; |
| 562 | |
| 563 | /* |
| 564 | * Form a scan key that selects only user attributes (attnum > 0). |
| 565 | * (Eliminating system attribute rows at the index level is lots faster |
| 566 | * than fetching them.) |
| 567 | */ |
| 568 | ScanKeyInit(&skey[0], |
| 569 | Anum_pg_attribute_attrelid, |
| 570 | BTEqualStrategyNumber, F_OIDEQ, |
| 571 | ObjectIdGetDatum(RelationGetRelid(relation))); |
| 572 | ScanKeyInit(&skey[1], |
| 573 | Anum_pg_attribute_attnum, |
| 574 | BTGreaterStrategyNumber, F_INT2GT, |
| 575 | Int16GetDatum(0)); |
| 576 | |
| 577 | /* |
| 578 | * Open pg_attribute and begin a scan. Force heap scan if we haven't yet |
| 579 | * built the critical relcache entries (this includes initdb and startup |
| 580 | * without a pg_internal.init file). |
| 581 | */ |
| 582 | pg_attribute_desc = table_open(AttributeRelationId, AccessShareLock); |
| 583 | pg_attribute_scan = systable_beginscan(pg_attribute_desc, |
| 584 | AttributeRelidNumIndexId, |
| 585 | criticalRelcachesBuilt, |
| 586 | NULL, |
| 587 | 2, skey); |
| 588 | |
| 589 | /* |
| 590 | * add attribute data to relation->rd_att |
| 591 | */ |
| 592 | need = RelationGetNumberOfAttributes(relation); |
| 593 | |
| 594 | while (HeapTupleIsValid(pg_attribute_tuple = systable_getnext(pg_attribute_scan))) |
| 595 | { |
| 596 | Form_pg_attribute attp; |
| 597 | int attnum; |
| 598 |
no test coverage detected