* Setup a ScanKey for a search in the relation 'rel' for a tuple 'key' that * is setup to match 'rel' (*NOT* idxrel!). * * Returns whether any column contains NULLs. * * This is not generic routine, it expects the idxrel to be replication * identity of a rel and meet all limitations associated with that. */
| 47 | * identity of a rel and meet all limitations associated with that. |
| 48 | */ |
| 49 | static bool |
| 50 | build_replindex_scan_key(ScanKey skey, Relation rel, Relation idxrel, |
| 51 | TupleTableSlot *searchslot) |
| 52 | { |
| 53 | int attoff; |
| 54 | bool isnull; |
| 55 | Datum indclassDatum; |
| 56 | oidvector *opclass; |
| 57 | int2vector *indkey = &idxrel->rd_index->indkey; |
| 58 | bool hasnulls = false; |
| 59 | |
| 60 | Assert(RelationGetReplicaIndex(rel) == RelationGetRelid(idxrel) || |
| 61 | RelationGetPrimaryKeyIndex(rel) == RelationGetRelid(idxrel)); |
| 62 | |
| 63 | indclassDatum = SysCacheGetAttr(INDEXRELID, idxrel->rd_indextuple, |
| 64 | Anum_pg_index_indclass, &isnull); |
| 65 | Assert(!isnull); |
| 66 | opclass = (oidvector *) DatumGetPointer(indclassDatum); |
| 67 | |
| 68 | /* Build scankey for every attribute in the index. */ |
| 69 | for (attoff = 0; attoff < IndexRelationGetNumberOfKeyAttributes(idxrel); attoff++) |
| 70 | { |
| 71 | Oid operator; |
| 72 | Oid opfamily; |
| 73 | RegProcedure regop; |
| 74 | int pkattno = attoff + 1; |
| 75 | int mainattno = indkey->values[attoff]; |
| 76 | Oid optype = get_opclass_input_type(opclass->values[attoff]); |
| 77 | |
| 78 | /* |
| 79 | * Load the operator info. We need this to get the equality operator |
| 80 | * function for the scan key. |
| 81 | */ |
| 82 | opfamily = get_opclass_family(opclass->values[attoff]); |
| 83 | |
| 84 | operator = get_opfamily_member(opfamily, optype, |
| 85 | optype, |
| 86 | BTEqualStrategyNumber); |
| 87 | if (!OidIsValid(operator)) |
| 88 | elog(ERROR, "missing operator %d(%u,%u) in opfamily %u", |
| 89 | BTEqualStrategyNumber, optype, optype, opfamily); |
| 90 | |
| 91 | regop = get_opcode(operator); |
| 92 | |
| 93 | /* Initialize the scankey. */ |
| 94 | ScanKeyInit(&skey[attoff], |
| 95 | pkattno, |
| 96 | BTEqualStrategyNumber, |
| 97 | regop, |
| 98 | searchslot->tts_values[mainattno - 1]); |
| 99 | |
| 100 | skey[attoff].sk_collation = idxrel->rd_indcollation[attoff]; |
| 101 | |
| 102 | /* Check for null value. */ |
| 103 | if (searchslot->tts_isnull[mainattno - 1]) |
| 104 | { |
| 105 | hasnulls = true; |
| 106 | skey[attoff].sk_flags |= SK_ISNULL; |
no test coverage detected