From 1ea75d187f602bed86a9bce88f2c50c1faeba49c Mon Sep 17 00:00:00 2001 From: Matthias van de Meent Date: Thu, 7 Apr 2022 12:30:00 +0200 Subject: [PATCH v6 2/8] Use specialized attribute iterators in backend/*/nbt*_spec.h Split out for making it clear what substantial changes were made to the pre-existing functions. Even though not all nbt*_spec functions have been updated; most call sites now can directly call the specialized functions instead of having to determine the right specialization based on the (potentially locally unavailable) index relation, making the specialization of those functions worth the effort. --- src/backend/access/nbtree/nbtsearch_spec.h | 16 +++--- src/backend/access/nbtree/nbtsort_spec.h | 24 +++++---- src/backend/access/nbtree/nbtutils_spec.h | 63 +++++++++++++--------- 3 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/backend/access/nbtree/nbtsearch_spec.h b/src/backend/access/nbtree/nbtsearch_spec.h index 73d5370496..a5c5f2b94f 100644 --- a/src/backend/access/nbtree/nbtsearch_spec.h +++ b/src/backend/access/nbtree/nbtsearch_spec.h @@ -823,6 +823,7 @@ NBTS_FUNCTION(_bt_compare)(Relation rel, int ncmpkey; int ntupatts; int32 result; + nbts_attiterdeclare(itup); Assert(_bt_check_natts(rel, key->heapkeyspace, page, offnum)); Assert(key->keysz <= IndexRelationGetNumberOfKeyAttributes(rel)); @@ -854,23 +855,26 @@ NBTS_FUNCTION(_bt_compare)(Relation rel, Assert(key->heapkeyspace || ncmpkey == key->keysz); Assert(!BTreeTupleIsPosting(itup) || key->allequalimage); scankey = key->scankeys; - for (int i = 1; i <= ncmpkey; i++) + nbts_attiterinit(itup, 1, itupdesc); + + nbts_foreachattr(1, ncmpkey) { Datum datum; - bool isNull; - datum = index_getattr(itup, scankey->sk_attno, itupdesc, &isNull); + datum = nbts_attiter_nextattdatum(itup, itupdesc); - if (scankey->sk_flags & SK_ISNULL) /* key is NULL */ + /* key is NULL */ + if (scankey->sk_flags & SK_ISNULL) { - if (isNull) + if (nbts_attiter_curattisnull(itup)) result = 0; /* NULL "=" NULL */ else if (scankey->sk_flags & SK_BT_NULLS_FIRST) result = -1; /* NULL "<" NOT_NULL */ else result = 1; /* NULL ">" NOT_NULL */ } - else if (isNull) /* key is NOT_NULL and item is NULL */ + /* key is NOT_NULL and item is NULL */ + else if (nbts_attiter_curattisnull(itup)) { if (scankey->sk_flags & SK_BT_NULLS_FIRST) result = 1; /* NOT_NULL ">" NULL */ diff --git a/src/backend/access/nbtree/nbtsort_spec.h b/src/backend/access/nbtree/nbtsort_spec.h index 8f4a3602ca..d3f2db2dc4 100644 --- a/src/backend/access/nbtree/nbtsort_spec.h +++ b/src/backend/access/nbtree/nbtsort_spec.h @@ -27,8 +27,7 @@ NBTS_FUNCTION(_bt_load)(BTWriteState *wstate, BTSpool *btspool, itup2 = NULL; bool load1; TupleDesc tupdes = RelationGetDescr(wstate->index); - int i, - keysz = IndexRelationGetNumberOfKeyAttributes(wstate->index); + int keysz = IndexRelationGetNumberOfKeyAttributes(wstate->index); SortSupport sortKeys; int64 tuples_done = 0; bool deduplicate; @@ -50,7 +49,7 @@ NBTS_FUNCTION(_bt_load)(BTWriteState *wstate, BTSpool *btspool, /* Prepare SortSupport data for each column */ sortKeys = (SortSupport) palloc0(keysz * sizeof(SortSupportData)); - for (i = 0; i < keysz; i++) + for (int i = 0; i < keysz; i++) { SortSupport sortKey = sortKeys + i; ScanKey scanKey = wstate->inskey->scankeys + i; @@ -82,22 +81,25 @@ NBTS_FUNCTION(_bt_load)(BTWriteState *wstate, BTSpool *btspool, } else if (itup != NULL) { + nbts_attiterdeclare(itup); + nbts_attiterdeclare(itup2); int32 compare = 0; - for (i = 1; i <= keysz; i++) + nbts_attiterinit(itup, 1, tupdes); + nbts_attiterinit(itup2, 1, tupdes); + + nbts_foreachattr(1, keysz) { SortSupport entry; Datum attrDatum1, attrDatum2; - bool isNull1, - isNull2; - entry = sortKeys + i - 1; - attrDatum1 = index_getattr(itup, i, tupdes, &isNull1); - attrDatum2 = index_getattr(itup2, i, tupdes, &isNull2); + entry = sortKeys + nbts_attiter_attnum - 1; + attrDatum1 = nbts_attiter_nextattdatum(itup, tupdes); + attrDatum2 = nbts_attiter_nextattdatum(itup2, tupdes); - compare = ApplySortComparator(attrDatum1, isNull1, - attrDatum2, isNull2, + compare = ApplySortComparator(attrDatum1, nbts_attiter_curattisnull(itup), + attrDatum2, nbts_attiter_curattisnull(itup2), entry); if (compare > 0) { diff --git a/src/backend/access/nbtree/nbtutils_spec.h b/src/backend/access/nbtree/nbtutils_spec.h index a4b934ae7a..638eff18f6 100644 --- a/src/backend/access/nbtree/nbtutils_spec.h +++ b/src/backend/access/nbtree/nbtutils_spec.h @@ -211,6 +211,8 @@ NBTS_FUNCTION(_bt_keep_natts)(Relation rel, IndexTuple lastleft, TupleDesc itupdesc = RelationGetDescr(rel); int keepnatts; ScanKey scankey; + nbts_attiterdeclare(lastleft); + nbts_attiterdeclare(firstright); /* * _bt_compare() treats truncated key attributes as having the value minus @@ -222,20 +224,22 @@ NBTS_FUNCTION(_bt_keep_natts)(Relation rel, IndexTuple lastleft, scankey = itup_key->scankeys; keepnatts = 1; - for (int attnum = 1; attnum <= nkeyatts; attnum++, scankey++) + + nbts_attiterinit(lastleft, 1, itupdesc); + nbts_attiterinit(firstright, 1, itupdesc); + + nbts_foreachattr(1, nkeyatts) { Datum datum1, datum2; - bool isNull1, - isNull2; - datum1 = index_getattr(lastleft, attnum, itupdesc, &isNull1); - datum2 = index_getattr(firstright, attnum, itupdesc, &isNull2); + datum1 = nbts_attiter_nextattdatum(lastleft, itupdesc); + datum2 = nbts_attiter_nextattdatum(firstright, itupdesc); - if (isNull1 != isNull2) + if (nbts_attiter_curattisnull(lastleft) != nbts_attiter_curattisnull(firstright)) break; - if (!isNull1 && + if (!nbts_attiter_curattisnull(lastleft) && DatumGetInt32(FunctionCall2Coll(&scankey->sk_func, scankey->sk_collation, datum1, @@ -243,6 +247,7 @@ NBTS_FUNCTION(_bt_keep_natts)(Relation rel, IndexTuple lastleft, break; keepnatts++; + scankey++; } /* @@ -295,7 +300,7 @@ NBTS_FUNCTION(_bt_mkscankey)(Relation rel, IndexTuple itup) int indnkeyatts; int16 *indoption; int tupnatts; - int i; + nbts_attiterdeclare(itup); itupdesc = RelationGetDescr(rel); indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); @@ -326,7 +331,10 @@ NBTS_FUNCTION(_bt_mkscankey)(Relation rel, IndexTuple itup) key->scantid = key->heapkeyspace && itup ? BTreeTupleGetHeapTID(itup) : NULL; skey = key->scankeys; - for (i = 0; i < indnkeyatts; i++) + + nbts_attiterinit(itup, 1, itupdesc); + + nbts_foreachattr(1, indnkeyatts) { FmgrInfo *procinfo; Datum arg; @@ -337,27 +345,30 @@ NBTS_FUNCTION(_bt_mkscankey)(Relation rel, IndexTuple itup) * We can use the cached (default) support procs since no cross-type * comparison can be needed. */ - procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC); + procinfo = index_getprocinfo(rel, nbts_attiter_attnum, BTORDER_PROC); /* * Key arguments built from truncated attributes (or when caller * provides no tuple) are defensively represented as NULL values. They * should never be used. */ - if (i < tupnatts) - arg = index_getattr(itup, i + 1, itupdesc, &null); + if (nbts_attiter_attnum <= tupnatts) + { + arg = nbts_attiter_nextattdatum(itup, itupdesc); + null = nbts_attiter_curattisnull(itup); + } else { arg = (Datum) 0; null = true; } - flags = (null ? SK_ISNULL : 0) | (indoption[i] << SK_BT_INDOPTION_SHIFT); - ScanKeyEntryInitializeWithInfo(&skey[i], + flags = (null ? SK_ISNULL : 0) | (indoption[nbts_attiter_attnum - 1] << SK_BT_INDOPTION_SHIFT); + ScanKeyEntryInitializeWithInfo(&skey[nbts_attiter_attnum - 1], flags, - (AttrNumber) (i + 1), + (AttrNumber) nbts_attiter_attnum, InvalidStrategy, InvalidOid, - rel->rd_indcollation[i], + rel->rd_indcollation[nbts_attiter_attnum - 1], procinfo, arg); /* Record if any key attribute is NULL (or truncated) */ @@ -744,24 +755,28 @@ NBTS_FUNCTION(_bt_keep_natts_fast)(Relation rel, TupleDesc itupdesc = RelationGetDescr(rel); int keysz = IndexRelationGetNumberOfKeyAttributes(rel); int keepnatts; + nbts_attiterdeclare(lastleft); + nbts_attiterdeclare(firstright); keepnatts = 1; - for (int attnum = 1; attnum <= keysz; attnum++) + nbts_attiterinit(lastleft, 1, itupdesc); + nbts_attiterinit(firstright, 1, itupdesc); + + nbts_foreachattr(1, keysz) { Datum datum1, datum2; - bool isNull1, - isNull2; Form_pg_attribute att; - datum1 = index_getattr(lastleft, attnum, itupdesc, &isNull1); - datum2 = index_getattr(firstright, attnum, itupdesc, &isNull2); - att = TupleDescAttr(itupdesc, attnum - 1); + datum1 = nbts_attiter_nextattdatum(lastleft,itupdesc); + datum2 = nbts_attiter_nextattdatum(firstright, itupdesc); + att = TupleDescAttr(itupdesc, nbts_attiter_attnum - 1); - if (isNull1 != isNull2) + if (nbts_attiter_curattisnull(lastleft) != + nbts_attiter_curattisnull(firstright)) break; - if (!isNull1 && + if (!nbts_attiter_curattisnull(lastleft) && !datum_image_eq(datum1, datum2, att->attbyval, att->attlen)) break; -- 2.30.2