@ -58,6 +58,17 @@ typedef struct BrinBuildState
BrinMemTuple * bs_dtuple ;
} BrinBuildState ;
/*
* We use a BrinInsertState to capture running state spanning multiple
* brininsert invocations , within the same command .
*/
typedef struct BrinInsertState
{
BrinRevmap * bis_rmAccess ;
BrinDesc * bis_desc ;
BlockNumber bis_pages_per_range ;
} BrinInsertState ;
/*
* Struct used as " opaque " during index scans
*/
@ -72,6 +83,7 @@ typedef struct BrinOpaque
static BrinBuildState * initialize_brin_buildstate ( Relation idxRel ,
BrinRevmap * revmap , BlockNumber pagesPerRange ) ;
static BrinInsertState * initialize_brin_insertstate ( Relation idxRel , IndexInfo * indexInfo ) ;
static void terminate_brin_buildstate ( BrinBuildState * state ) ;
static void brinsummarize ( Relation index , Relation heapRel , BlockNumber pageRange ,
bool include_partial , double * numSummarized , double * numExisting ) ;
@ -117,6 +129,7 @@ brinhandler(PG_FUNCTION_ARGS)
amroutine - > ambuild = brinbuild ;
amroutine - > ambuildempty = brinbuildempty ;
amroutine - > aminsert = brininsert ;
amroutine - > aminsertcleanup = brininsertcleanup ;
amroutine - > ambulkdelete = brinbulkdelete ;
amroutine - > amvacuumcleanup = brinvacuumcleanup ;
amroutine - > amcanreturn = NULL ;
@ -140,6 +153,27 @@ brinhandler(PG_FUNCTION_ARGS)
PG_RETURN_POINTER ( amroutine ) ;
}
/*
* Initialize a BrinInsertState to maintain state to be used across multiple
* tuple inserts , within the same command .
*/
static BrinInsertState *
initialize_brin_insertstate ( Relation idxRel , IndexInfo * indexInfo )
{
BrinInsertState * bistate ;
MemoryContext oldcxt ;
oldcxt = MemoryContextSwitchTo ( indexInfo - > ii_Context ) ;
bistate = palloc0 ( sizeof ( BrinInsertState ) ) ;
bistate - > bis_desc = brin_build_desc ( idxRel ) ;
bistate - > bis_rmAccess = brinRevmapInitialize ( idxRel ,
& bistate - > bis_pages_per_range ) ;
indexInfo - > ii_AmCache = bistate ;
MemoryContextSwitchTo ( oldcxt ) ;
return bistate ;
}
/*
* A tuple in the heap is being inserted . To keep a brin index up to date ,
* we need to obtain the relevant index tuple and compare its stored values
@ -162,14 +196,24 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
BlockNumber pagesPerRange ;
BlockNumber origHeapBlk ;
BlockNumber heapBlk ;
BrinDesc * bdesc = ( BrinDesc * ) indexInfo - > ii_AmCache ;
BrinInsertState * bistate = ( BrinInsertState * ) indexInfo - > ii_AmCache ;
BrinRevmap * revmap ;
BrinDesc * bdesc ;
Buffer buf = InvalidBuffer ;
MemoryContext tupcxt = NULL ;
MemoryContext oldcxt = CurrentMemoryContext ;
bool autosummarize = BrinGetAutoSummarize ( idxRel ) ;
revmap = brinRevmapInitialize ( idxRel , & pagesPerRange ) ;
/*
* If firt time through in this statement , initialize the insert state
* that we keep for all the inserts in the command .
*/
if ( ! bistate )
bistate = initialize_brin_insertstate ( idxRel , indexInfo ) ;
revmap = bistate - > bis_rmAccess ;
bdesc = bistate - > bis_desc ;
pagesPerRange = bistate - > bis_pages_per_range ;
/*
* origHeapBlk is the block number where the insertion occurred . heapBlk
@ -228,14 +272,6 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
if ( ! brtup )
break ;
/* First time through in this statement? */
if ( bdesc = = NULL )
{
MemoryContextSwitchTo ( indexInfo - > ii_Context ) ;
bdesc = brin_build_desc ( idxRel ) ;
indexInfo - > ii_AmCache = ( void * ) bdesc ;
MemoryContextSwitchTo ( oldcxt ) ;
}
/* First time through in this brininsert call? */
if ( tupcxt = = NULL )
{
@ -306,7 +342,6 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
break ;
}
brinRevmapTerminate ( revmap ) ;
if ( BufferIsValid ( buf ) )
ReleaseBuffer ( buf ) ;
MemoryContextSwitchTo ( oldcxt ) ;
@ -316,6 +351,24 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
return false ;
}
/*
* Callback to clean up the BrinInsertState once all tuple inserts are done .
*/
void
brininsertcleanup ( IndexInfo * indexInfo )
{
BrinInsertState * bistate = ( BrinInsertState * ) indexInfo - > ii_AmCache ;
Assert ( bistate ) ;
/*
* Clean up the revmap . Note that the brinDesc has already been cleaned up
* as part of its own memory context .
*/
brinRevmapTerminate ( bistate - > bis_rmAccess ) ;
bistate - > bis_rmAccess = NULL ;
bistate - > bis_desc = NULL ;
}
/*
* Initialize state for a BRIN index scan .
*