@ -85,8 +85,6 @@ static FmgrInfo *inclusion_get_procinfo(BrinDesc *bdesc, uint16 attno,
uint16 procnum ) ;
static FmgrInfo * inclusion_get_strategy_procinfo ( BrinDesc * bdesc , uint16 attno ,
Oid subtype , uint16 strategynum ) ;
static bool inclusion_consistent_key ( BrinDesc * bdesc , BrinValues * column ,
ScanKey key , Oid colloid ) ;
/*
@ -243,9 +241,9 @@ brin_inclusion_add_value(PG_FUNCTION_ARGS)
/*
* BRIN inclusion consistent function
*
* We inspect the IS NULL scan keys first , which allows us to make a decision
* without looking at the contents of the page range . Only when the page range
* matches the IS NULL keys , we check the regular scan keys .
* We ' re no longer dealing with NULL keys in the consistent function , that is
* now handled by the AM code . That means we should not get any all - NULL ranges
* either , because those can ' t be consistent with regular ( not [ IS ] NULL ) keys .
*
* All of the strategies are optional .
*/
@ -254,63 +252,29 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
{
BrinDesc * bdesc = ( BrinDesc * ) PG_GETARG_POINTER ( 0 ) ;
BrinValues * column = ( BrinValues * ) PG_GETARG_POINTER ( 1 ) ;
ScanKey * keys = ( ScanKey * ) PG_GETARG_POINTER ( 2 ) ;
int nkeys = PG_GETARG_INT32 ( 3 ) ;
Oid colloid = PG_GET_COLLATION ( ) ;
int keyno ;
ScanKey key = ( ScanKey ) PG_GETARG_POINTER ( 2 ) ;
Oid colloid = PG_GET_COLLATION ( ) ,
subtype ;
Datum unionval ;
AttrNumber attno ;
Datum query ;
FmgrInfo * finfo ;
Datum result ;
/* make sure we got some scan keys */
Assert ( ( nkeys > 0 ) & & ( keys ! = NULL ) ) ;
/* This opclass uses the old signature with only three arguments. */
Assert ( PG_NARGS ( ) = = 3 ) ;
/*
* If is all nulls , it cannot possibly be consistent ( at this point we
* know there are at least some regular scan keys ) .
*/
if ( column - > bv_allnulls )
PG_RETURN_BOOL ( false ) ;
/* Should not be dealing with all-NULL ranges. */
Assert ( ! column - > bv_allnulls ) ;
/* It has to be checked, if it contains elements that are not mergeable. */
if ( DatumGetBool ( column - > bv_values [ INCLUSION_UNMERGEABLE ] ) )
PG_RETURN_BOOL ( true ) ;
/* Check that the range is consistent with all regular scan keys. */
for ( keyno = 0 ; keyno < nkeys ; keyno + + )
{
ScanKey key = keys [ keyno ] ;
/* NULL keys are handled and filtered-out in bringetbitmap */
Assert ( ! ( key - > sk_flags & SK_ISNULL ) ) ;
/*
* When there are multiple scan keys , failure to meet the criteria for
* a single one of them is enough to discard the range as a whole , so
* break out of the loop as soon as a false return value is obtained .
*/
if ( ! inclusion_consistent_key ( bdesc , column , key , colloid ) )
PG_RETURN_BOOL ( false ) ;
}
PG_RETURN_BOOL ( true ) ;
}
/*
* inclusion_consistent_key
* Determine if the range is consistent with a single scan key .
*/
static bool
inclusion_consistent_key ( BrinDesc * bdesc , BrinValues * column , ScanKey key ,
Oid colloid )
{
FmgrInfo * finfo ;
AttrNumber attno = key - > sk_attno ;
Oid subtype = key - > sk_subtype ;
Datum query = key - > sk_argument ;
Datum unionval = column - > bv_values [ INCLUSION_UNION ] ;
Datum result ;
/* This should be called only for regular keys, not for IS [NOT] NULL. */
Assert ( ! ( key - > sk_flags & SK_ISNULL ) ) ;
attno = key - > sk_attno ;
subtype = key - > sk_subtype ;
query = key - > sk_argument ;
unionval = column - > bv_values [ INCLUSION_UNION ] ;
switch ( key - > sk_strategy )
{
/*
@ -330,49 +294,49 @@ inclusion_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTOverRightStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return ! DatumGetBool ( result ) ;
PG_RETURN_BOOL ( ! DatumGetBool ( result ) ) ;
case RTOverLeftStrategyNumber :
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTRightStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return ! DatumGetBool ( result ) ;
PG_RETURN_BOOL ( ! DatumGetBool ( result ) ) ;
case RTOverRightStrategyNumber :
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTLeftStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return ! DatumGetBool ( result ) ;
PG_RETURN_BOOL ( ! DatumGetBool ( result ) ) ;
case RTRightStrategyNumber :
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTOverLeftStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return ! DatumGetBool ( result ) ;
PG_RETURN_BOOL ( ! DatumGetBool ( result ) ) ;
case RTBelowStrategyNumber :
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTOverAboveStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return ! DatumGetBool ( result ) ;
PG_RETURN_BOOL ( ! DatumGetBool ( result ) ) ;
case RTOverBelowStrategyNumber :
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTAboveStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return ! DatumGetBool ( result ) ;
PG_RETURN_BOOL ( ! DatumGetBool ( result ) ) ;
case RTOverAboveStrategyNumber :
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTBelowStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return ! DatumGetBool ( result ) ;
PG_RETURN_BOOL ( ! DatumGetBool ( result ) ) ;
case RTAboveStrategyNumber :
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTOverBelowStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return ! DatumGetBool ( result ) ;
PG_RETURN_BOOL ( ! DatumGetBool ( result ) ) ;
/*
* Overlap and contains strategies
@ -390,7 +354,7 @@ inclusion_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
key - > sk_strategy ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return DatumGetBool ( result ) ;
PG_RETURN_DATUM ( result ) ;
/*
* Contained by strategies
@ -410,9 +374,9 @@ inclusion_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
RTOverlapStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
if ( DatumGetBool ( result ) )
return true ;
PG_RETURN_BOOL ( true ) ;
return DatumGetBool ( column - > bv_values [ INCLUSION_CONTAINS_EMPTY ] ) ;
PG_RETURN_DATUM ( column - > bv_values [ INCLUSION_CONTAINS_EMPTY ] ) ;
/*
* Adjacent strategy
@ -429,12 +393,12 @@ inclusion_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
RTOverlapStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
if ( DatumGetBool ( result ) )
return true ;
PG_RETURN_BOOL ( true ) ;
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTAdjacentStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return DatumGetBool ( result ) ;
PG_RETURN_DATUM ( result ) ;
/*
* Basic comparison strategies
@ -464,9 +428,9 @@ inclusion_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
RTRightStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
if ( ! DatumGetBool ( result ) )
return true ;
PG_RETURN_BOOL ( true ) ;
return DatumGetBool ( column - > bv_values [ INCLUSION_CONTAINS_EMPTY ] ) ;
PG_RETURN_DATUM ( column - > bv_values [ INCLUSION_CONTAINS_EMPTY ] ) ;
case RTSameStrategyNumber :
case RTEqualStrategyNumber :
@ -474,30 +438,30 @@ inclusion_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
RTContainsStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
if ( DatumGetBool ( result ) )
return true ;
PG_RETURN_BOOL ( true ) ;
return DatumGetBool ( column - > bv_values [ INCLUSION_CONTAINS_EMPTY ] ) ;
PG_RETURN_DATUM ( column - > bv_values [ INCLUSION_CONTAINS_EMPTY ] ) ;
case RTGreaterEqualStrategyNumber :
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTLeftStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
if ( ! DatumGetBool ( result ) )
return true ;
PG_RETURN_BOOL ( true ) ;
return DatumGetBool ( column - > bv_values [ INCLUSION_CONTAINS_EMPTY ] ) ;
PG_RETURN_DATUM ( column - > bv_values [ INCLUSION_CONTAINS_EMPTY ] ) ;
case RTGreaterStrategyNumber :
/* no need to check for empty elements */
finfo = inclusion_get_strategy_procinfo ( bdesc , attno , subtype ,
RTLeftStrategyNumber ) ;
result = FunctionCall2Coll ( finfo , colloid , unionval , query ) ;
return ! DatumGetBool ( result ) ;
PG_RETURN_BOOL ( ! DatumGetBool ( result ) ) ;
default :
/* shouldn't happen */
elog ( ERROR , " invalid strategy number %d " , key - > sk_strategy ) ;
return false ;
PG_RETURN_BOOL ( false ) ;
}
}