mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-18 18:44:06 +08:00
Support the old signature of BRIN consistent function
Commita1c649d889
changed the signature of the BRIN consistent function by adding a new required parameter. Treating the parameter as optional, which would make the change backwards incompatibile, was rejected with the justification that there are few out-of-core extensions, so it's not worth adding making the code more complex, and it's better to deal with that in the extension. But after further thought, that would be rather problematic, because pg_upgrade simply dumps catalog contents and the same version of an extension needs to work on both PostgreSQL versions. Supporting both variants of the consistent function (with 3 or 4 arguments) makes that possible. The signature is not the only thing that changed, as commit72ccf55cb9
moved handling of IS [NOT] NULL keys from the support procedures. But this change is backward compatible - handling the keys in exension is unnecessary, but harmless. The consistent function will do a bit of unnecessary work, but it should be very cheap. This also undoes most of the changes to the existing opclasses (minmax and inclusion), making them use the old signature again. This should make backpatching simpler. Catversion bump, because of changes in pg_amproc. Author: Tomas Vondra <tomas.vondra@postgresql.org> Author: Nikita Glukhov <n.gluhov@postgrespro.ru> Reviewed-by: Mark Dilger <hornschnorter@gmail.com> Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com> Reviewed-by: Masahiko Sawada <masahiko.sawada@enterprisedb.com> Reviewed-by: John Naylor <john.naylor@enterprisedb.com> Discussion: https://postgr.es/m/c1138ead-7668-f0e1-0638-c3be3237e812@2ndquadrant.com
This commit is contained in:
parent
a68dfa27d4
commit
a681e3c107
@ -476,6 +476,19 @@ typedef struct BrinOpcInfo
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><function>bool consistent(BrinDesc *bdesc, BrinValues *column,
|
||||||
|
ScanKey key)</function></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Returns whether the ScanKey is consistent with the given indexed
|
||||||
|
values for a range.
|
||||||
|
The attribute number to use is passed as part of the scan key.
|
||||||
|
This is an older backward-compatible variant of the consistent function.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><function>bool addValue(BrinDesc *bdesc, BrinValues *column,
|
<term><function>bool addValue(BrinDesc *bdesc, BrinValues *column,
|
||||||
Datum newval, bool isnull)</function></term>
|
Datum newval, bool isnull)</function></term>
|
||||||
|
@ -634,26 +634,58 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Collation from the first key (has to be the same for
|
||||||
|
* all keys for the same attribue).
|
||||||
|
*/
|
||||||
|
collation = keys[attno - 1][0]->sk_collation;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether the scan key is consistent with the page
|
* Check whether the scan key is consistent with the page
|
||||||
* range values; if so, have the pages in the range added
|
* range values; if so, have the pages in the range added
|
||||||
* to the output bitmap.
|
* to the output bitmap.
|
||||||
*
|
*
|
||||||
* XXX We simply use the collation from the first key (it
|
* The opclass may or may not support processing of multiple
|
||||||
* has to be the same for all keys for the same attribue).
|
* scan keys. We can determine that based on the number of
|
||||||
|
* arguments - functions with extra parameter (number of scan
|
||||||
|
* keys) do support this, otherwise we have to simply pass the
|
||||||
|
* scan keys one by one.
|
||||||
*/
|
*/
|
||||||
collation = keys[attno - 1][0]->sk_collation;
|
if (consistentFn[attno - 1].fn_nargs >= 4)
|
||||||
|
{
|
||||||
|
/* Check all keys at once */
|
||||||
|
add = FunctionCall4Coll(&consistentFn[attno - 1],
|
||||||
|
collation,
|
||||||
|
PointerGetDatum(bdesc),
|
||||||
|
PointerGetDatum(bval),
|
||||||
|
PointerGetDatum(keys[attno - 1]),
|
||||||
|
Int32GetDatum(nkeys[attno - 1]));
|
||||||
|
addrange = DatumGetBool(add);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Check keys one by one
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
int keyno;
|
||||||
|
|
||||||
/* Check all keys at once */
|
for (keyno = 0; keyno < nkeys[attno - 1]; keyno++)
|
||||||
add = FunctionCall4Coll(&consistentFn[attno - 1],
|
{
|
||||||
collation,
|
add = FunctionCall3Coll(&consistentFn[attno - 1],
|
||||||
PointerGetDatum(bdesc),
|
keys[attno - 1][keyno]->sk_collation,
|
||||||
PointerGetDatum(bval),
|
PointerGetDatum(bdesc),
|
||||||
PointerGetDatum(keys[attno - 1]),
|
PointerGetDatum(bval),
|
||||||
Int32GetDatum(nkeys[attno - 1]));
|
PointerGetDatum(keys[attno - 1][keyno]));
|
||||||
addrange = DatumGetBool(add);
|
addrange = DatumGetBool(add);
|
||||||
if (!addrange)
|
if (!addrange)
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,6 @@ typedef struct MinmaxOpaque
|
|||||||
|
|
||||||
static FmgrInfo *minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno,
|
static FmgrInfo *minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno,
|
||||||
Oid subtype, uint16 strategynum);
|
Oid subtype, uint16 strategynum);
|
||||||
static bool minmax_consistent_key(BrinDesc *bdesc, BrinValues *column,
|
|
||||||
ScanKey key, Oid colloid);
|
|
||||||
|
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
@ -133,64 +131,32 @@ brin_minmax_add_value(PG_FUNCTION_ARGS)
|
|||||||
* return whether the scan key is consistent with the index tuple's min/max
|
* return whether the scan key is consistent with the index tuple's min/max
|
||||||
* values. Return true if so, false otherwise.
|
* values. Return true if so, false otherwise.
|
||||||
*
|
*
|
||||||
* 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 all those keys, we check the regular scan keys.
|
* either, because those can't be consistent with regular (not [IS] NULL) keys.
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
brin_minmax_consistent(PG_FUNCTION_ARGS)
|
brin_minmax_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;
|
AttrNumber attno;
|
||||||
|
Datum value;
|
||||||
/* make sure we got some scan keys */
|
|
||||||
Assert((nkeys > 0) && (keys != NULL));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
/* Check that the range is consistent with all 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 (!minmax_consistent_key(bdesc, column, key, colloid))
|
|
||||||
PG_RETURN_DATUM(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
PG_RETURN_DATUM(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* minmax_consistent_key
|
|
||||||
* Determine if the range is consistent with a single scan key.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
minmax_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
|
|
||||||
Oid colloid)
|
|
||||||
{
|
|
||||||
FmgrInfo *finfo;
|
|
||||||
AttrNumber attno = key->sk_attno;
|
|
||||||
Oid subtype = key->sk_subtype;
|
|
||||||
Datum value = key->sk_argument;
|
|
||||||
Datum matches;
|
Datum matches;
|
||||||
|
FmgrInfo *finfo;
|
||||||
|
|
||||||
|
/* This opclass uses the old signature with only three arguments. */
|
||||||
|
Assert(PG_NARGS() == 3);
|
||||||
|
|
||||||
|
/* Should not be dealing with all-NULL ranges. */
|
||||||
|
Assert(!column->bv_allnulls);
|
||||||
|
|
||||||
|
attno = key->sk_attno;
|
||||||
|
subtype = key->sk_subtype;
|
||||||
|
value = key->sk_argument;
|
||||||
switch (key->sk_strategy)
|
switch (key->sk_strategy)
|
||||||
{
|
{
|
||||||
case BTLessStrategyNumber:
|
case BTLessStrategyNumber:
|
||||||
@ -233,7 +199,7 @@ minmax_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DatumGetBool(matches);
|
PG_RETURN_DATUM(matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -97,7 +97,7 @@ brinvalidate(Oid opclassoid)
|
|||||||
break;
|
break;
|
||||||
case BRIN_PROCNUM_CONSISTENT:
|
case BRIN_PROCNUM_CONSISTENT:
|
||||||
ok = check_amproc_signature(procform->amproc, BOOLOID, true,
|
ok = check_amproc_signature(procform->amproc, BOOLOID, true,
|
||||||
4, 4, INTERNALOID, INTERNALOID,
|
3, 4, INTERNALOID, INTERNALOID,
|
||||||
INTERNALOID, INT4OID);
|
INTERNALOID, INT4OID);
|
||||||
break;
|
break;
|
||||||
case BRIN_PROCNUM_UNION:
|
case BRIN_PROCNUM_UNION:
|
||||||
|
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202103261
|
#define CATALOG_VERSION_NO 202103262
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8232,7 +8232,7 @@
|
|||||||
prosrc => 'brin_minmax_add_value' },
|
prosrc => 'brin_minmax_add_value' },
|
||||||
{ oid => '3385', descr => 'BRIN minmax support',
|
{ oid => '3385', descr => 'BRIN minmax support',
|
||||||
proname => 'brin_minmax_consistent', prorettype => 'bool',
|
proname => 'brin_minmax_consistent', prorettype => 'bool',
|
||||||
proargtypes => 'internal internal internal int4',
|
proargtypes => 'internal internal internal',
|
||||||
prosrc => 'brin_minmax_consistent' },
|
prosrc => 'brin_minmax_consistent' },
|
||||||
{ oid => '3386', descr => 'BRIN minmax support',
|
{ oid => '3386', descr => 'BRIN minmax support',
|
||||||
proname => 'brin_minmax_union', prorettype => 'bool',
|
proname => 'brin_minmax_union', prorettype => 'bool',
|
||||||
@ -8248,7 +8248,7 @@
|
|||||||
prosrc => 'brin_inclusion_add_value' },
|
prosrc => 'brin_inclusion_add_value' },
|
||||||
{ oid => '4107', descr => 'BRIN inclusion support',
|
{ oid => '4107', descr => 'BRIN inclusion support',
|
||||||
proname => 'brin_inclusion_consistent', prorettype => 'bool',
|
proname => 'brin_inclusion_consistent', prorettype => 'bool',
|
||||||
proargtypes => 'internal internal internal int4',
|
proargtypes => 'internal internal internal',
|
||||||
prosrc => 'brin_inclusion_consistent' },
|
prosrc => 'brin_inclusion_consistent' },
|
||||||
{ oid => '4108', descr => 'BRIN inclusion support',
|
{ oid => '4108', descr => 'BRIN inclusion support',
|
||||||
proname => 'brin_inclusion_union', prorettype => 'bool',
|
proname => 'brin_inclusion_union', prorettype => 'bool',
|
||||||
|
Loading…
Reference in New Issue
Block a user