diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 99337b0..2e92dd0 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -131,7 +131,7 @@ brininsert(PG_FUNCTION_ARGS) oldcxt = MemoryContextSwitchTo(tupcxt); } - dtup = brin_deform_tuple(bdesc, brtup); + dtup = brin_deform_tuple(bdesc, brtup, NULL, NULL, NULL); /* * Compare the key values of the new tuple to the stored index values; @@ -284,7 +284,12 @@ bringetbitmap(PG_FUNCTION_ARGS) FmgrInfo *consistentFn; MemoryContext oldcxt; MemoryContext perRangeCxt; - + BrinTuple *btup; + uint32 tupInitSize; + Datum *values; + bool *allnulls; + bool *hasnulls; + opaque = (BrinOpaque *) scan->opaque; bdesc = opaque->bo_bdesc; pgstat_count_index_scan(idxRel); @@ -304,7 +309,16 @@ bringetbitmap(PG_FUNCTION_ARGS) * key reference each of them. We rely on zeroing fn_oid to InvalidOid. */ consistentFn = palloc0(sizeof(FmgrInfo) * bdesc->bd_tupdesc->natts); - + + /* + * Estimate the approximate size and allocate memory for tup. + */ + tupInitSize = bdesc->bd_tupdesc->natts * 16; + btup = palloc(tupInitSize); + values = palloc(sizeof(Datum) * bdesc->bd_totalstored); + allnulls = palloc(sizeof(bool) * bdesc->bd_tupdesc->natts); + hasnulls = palloc(sizeof(bool) * bdesc->bd_tupdesc->natts); + /* * Setup and use a per-range memory context, which is reset every time we * loop below. This avoids having to free the tuples within the loop. @@ -327,7 +341,6 @@ bringetbitmap(PG_FUNCTION_ARGS) BrinTuple *tup; OffsetNumber off; Size size; - CHECK_FOR_INTERRUPTS(); MemoryContextResetAndDeleteChildren(perRangeCxt); @@ -336,7 +349,10 @@ bringetbitmap(PG_FUNCTION_ARGS) &off, &size, BUFFER_LOCK_SHARE); if (tup) { - tup = brin_copy_tuple(tup, size); + if(size <= tupInitSize) + memcpy(btup, tup, size); + else + btup = brin_copy_tuple(tup, size); LockBuffer(buf, BUFFER_LOCK_UNLOCK); } @@ -344,7 +360,7 @@ bringetbitmap(PG_FUNCTION_ARGS) * For page ranges with no indexed tuple, we must return the whole * range; otherwise, compare it to the scan keys. */ - if (tup == NULL) + if (btup == NULL) { addrange = true; } @@ -352,7 +368,7 @@ bringetbitmap(PG_FUNCTION_ARGS) { BrinMemTuple *dtup; - dtup = brin_deform_tuple(bdesc, tup); + dtup = brin_deform_tuple(bdesc, btup, values, allnulls, hasnulls); if (dtup->bt_placeholder) { /* @@ -1136,7 +1152,7 @@ union_tuples(BrinDesc *bdesc, BrinMemTuple *a, BrinTuple *b) ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); oldcxt = MemoryContextSwitchTo(cxt); - db = brin_deform_tuple(bdesc, b); + db = brin_deform_tuple(bdesc, b, NULL, NULL, NULL); MemoryContextSwitchTo(oldcxt); for (keyno = 0; keyno < bdesc->bd_tupdesc->natts; keyno++) diff --git a/src/backend/access/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c index 5a7462b..2f416f1 100644 --- a/src/backend/access/brin/brin_tuple.c +++ b/src/backend/access/brin/brin_tuple.c @@ -397,7 +397,8 @@ brin_memtuple_initialize(BrinMemTuple *dtuple, BrinDesc *brdesc) * deconstruct the tuple from the on-disk format. */ BrinMemTuple * -brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple) +brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple, + Datum *valuesArg, bool *allnullsArg, bool *hasnullsArg) { BrinMemTuple *dtup; Datum *values; @@ -415,9 +416,20 @@ brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple) dtup->bt_placeholder = true; dtup->bt_blkno = tuple->bt_blkno; - values = palloc(sizeof(Datum) * brdesc->bd_totalstored); - allnulls = palloc(sizeof(bool) * brdesc->bd_tupdesc->natts); - hasnulls = palloc(sizeof(bool) * brdesc->bd_tupdesc->natts); + if(!valuesArg) + { + Assert(!allnullsArg && !hasnullsArg); + values = palloc(sizeof(Datum) * brdesc->bd_totalstored); + allnulls = palloc(sizeof(bool) * brdesc->bd_tupdesc->natts); + hasnulls = palloc(sizeof(bool) * brdesc->bd_tupdesc->natts); + } + else + { + Assert(allnullsArg && hasnullsArg); + values = valuesArg; + allnulls = allnullsArg; + hasnulls = hasnullsArg; + } tp = (char *) tuple + BrinTupleDataOffset(tuple); @@ -460,9 +472,12 @@ brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple) MemoryContextSwitchTo(oldcxt); - pfree(values); - pfree(allnulls); - pfree(hasnulls); + if(!valuesArg) + { + pfree(values); + pfree(allnulls); + pfree(hasnulls); + } return dtup; } diff --git a/src/include/access/brin_tuple.h b/src/include/access/brin_tuple.h index ce63b30..b63ea15 100644 --- a/src/include/access/brin_tuple.h +++ b/src/include/access/brin_tuple.h @@ -91,6 +91,9 @@ extern BrinMemTuple *brin_new_memtuple(BrinDesc *brdesc); extern void brin_memtuple_initialize(BrinMemTuple *dtuple, BrinDesc *brdesc); extern BrinMemTuple *brin_deform_tuple(BrinDesc *brdesc, - BrinTuple *tuple); + BrinTuple *tuple, + Datum *valuesArg, + bool *allnullsArg, + bool *hasnullsArg); #endif /* BRIN_TUPLE_H */