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