* RelationGetExclusionInfo -- get info about index's exclusion constraint * * This should be called only for an index that is known to have an * associated exclusion constraint. It returns arrays (palloc'd in caller's * context) of the exclusion operator OIDs, their underlying functions' * OIDs, and their strategy numbers in the index's opclasses. We cache * all this information since it r
| 5688 | * all this information since it requires a fair amount of work to get. |
| 5689 | */ |
| 5690 | void |
| 5691 | RelationGetExclusionInfo(Relation indexRelation, |
| 5692 | Oid **operators, |
| 5693 | Oid **procs, |
| 5694 | uint16 **strategies) |
| 5695 | { |
| 5696 | int indnkeyatts; |
| 5697 | Oid *ops; |
| 5698 | Oid *funcs; |
| 5699 | uint16 *strats; |
| 5700 | Relation conrel; |
| 5701 | SysScanDesc conscan; |
| 5702 | ScanKeyData skey[1]; |
| 5703 | HeapTuple htup; |
| 5704 | bool found; |
| 5705 | MemoryContext oldcxt; |
| 5706 | int i; |
| 5707 | |
| 5708 | indnkeyatts = IndexRelationGetNumberOfKeyAttributes(indexRelation); |
| 5709 | |
| 5710 | /* Allocate result space in caller context */ |
| 5711 | *operators = ops = (Oid *) palloc(sizeof(Oid) * indnkeyatts); |
| 5712 | *procs = funcs = (Oid *) palloc(sizeof(Oid) * indnkeyatts); |
| 5713 | *strategies = strats = (uint16 *) palloc(sizeof(uint16) * indnkeyatts); |
| 5714 | |
| 5715 | /* Quick exit if we have the data cached already */ |
| 5716 | if (indexRelation->rd_exclstrats != NULL) |
| 5717 | { |
| 5718 | memcpy(ops, indexRelation->rd_exclops, sizeof(Oid) * indnkeyatts); |
| 5719 | memcpy(funcs, indexRelation->rd_exclprocs, sizeof(Oid) * indnkeyatts); |
| 5720 | memcpy(strats, indexRelation->rd_exclstrats, sizeof(uint16) * indnkeyatts); |
| 5721 | return; |
| 5722 | } |
| 5723 | |
| 5724 | /* |
| 5725 | * Search pg_constraint for the constraint associated with the index. To |
| 5726 | * make this not too painfully slow, we use the index on conrelid; that |
| 5727 | * will hold the parent relation's OID not the index's own OID. |
| 5728 | * |
| 5729 | * Note: if we wanted to rely on the constraint name matching the index's |
| 5730 | * name, we could just do a direct lookup using pg_constraint's unique |
| 5731 | * index. For the moment it doesn't seem worth requiring that. |
| 5732 | */ |
| 5733 | ScanKeyInit(&skey[0], |
| 5734 | Anum_pg_constraint_conrelid, |
| 5735 | BTEqualStrategyNumber, F_OIDEQ, |
| 5736 | ObjectIdGetDatum(indexRelation->rd_index->indrelid)); |
| 5737 | |
| 5738 | conrel = table_open(ConstraintRelationId, AccessShareLock); |
| 5739 | conscan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, true, |
| 5740 | NULL, 1, skey); |
| 5741 | found = false; |
| 5742 | |
| 5743 | while (HeapTupleIsValid(htup = systable_getnext(conscan))) |
| 5744 | { |
| 5745 | Form_pg_constraint conform = (Form_pg_constraint) GETSTRUCT(htup); |
| 5746 | Datum val; |
| 5747 | bool isnull; |
no test coverage detected