mirror of
https://github.com/postgres/postgres.git
synced 2025-05-13 01:13:08 -04:00
Pass collations to functions in FunctionCallInfoData, not FmgrInfo.
Since collation is effectively an argument, not a property of the function, FmgrInfo is really the wrong place for it; and this becomes critical in cases where a cached FmgrInfo is used for varying purposes that might need different collation settings. Fix by passing it in FunctionCallInfoData instead. In particular this allows a clean fix for bug #5970 (record_cmp not working). This requires touching a bit more code than the original method, but nobody ever thought that collations would not be an invasive patch...
This commit is contained in:
parent
88543ecfec
commit
d64713df7e
@ -121,7 +121,7 @@ gin_compare_prefix_##type(PG_FUNCTION_ARGS) \
|
|||||||
int32 res, \
|
int32 res, \
|
||||||
cmp; \
|
cmp; \
|
||||||
\
|
\
|
||||||
cmp = DatumGetInt32(DirectFunctionCall2WithCollation( \
|
cmp = DatumGetInt32(DirectFunctionCall2Coll( \
|
||||||
TypeInfo_##type.typecmp, \
|
TypeInfo_##type.typecmp, \
|
||||||
DEFAULT_COLLATION_OID, \
|
DEFAULT_COLLATION_OID, \
|
||||||
(data->strategy == BTLessStrategyNumber || \
|
(data->strategy == BTLessStrategyNumber || \
|
||||||
|
@ -33,37 +33,55 @@ Datum gbt_text_same(PG_FUNCTION_ARGS);
|
|||||||
static bool
|
static bool
|
||||||
gbt_textgt(const void *a, const void *b)
|
gbt_textgt(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return (DatumGetBool(DirectFunctionCall2WithCollation(text_gt, DEFAULT_COLLATION_OID, PointerGetDatum(a), PointerGetDatum(b))));
|
return DatumGetBool(DirectFunctionCall2Coll(text_gt,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
|
PointerGetDatum(a),
|
||||||
|
PointerGetDatum(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
gbt_textge(const void *a, const void *b)
|
gbt_textge(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return (DatumGetBool(DirectFunctionCall2WithCollation(text_ge, DEFAULT_COLLATION_OID, PointerGetDatum(a), PointerGetDatum(b))));
|
return DatumGetBool(DirectFunctionCall2Coll(text_ge,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
|
PointerGetDatum(a),
|
||||||
|
PointerGetDatum(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
gbt_texteq(const void *a, const void *b)
|
gbt_texteq(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return (DatumGetBool(DirectFunctionCall2WithCollation(texteq, DEFAULT_COLLATION_OID, PointerGetDatum(a), PointerGetDatum(b))));
|
return DatumGetBool(DirectFunctionCall2Coll(texteq,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
|
PointerGetDatum(a),
|
||||||
|
PointerGetDatum(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
gbt_textle(const void *a, const void *b)
|
gbt_textle(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return (DatumGetBool(DirectFunctionCall2WithCollation(text_le, DEFAULT_COLLATION_OID, PointerGetDatum(a), PointerGetDatum(b))));
|
return DatumGetBool(DirectFunctionCall2Coll(text_le,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
|
PointerGetDatum(a),
|
||||||
|
PointerGetDatum(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
gbt_textlt(const void *a, const void *b)
|
gbt_textlt(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return (DatumGetBool(DirectFunctionCall2WithCollation(text_lt, DEFAULT_COLLATION_OID, PointerGetDatum(a), PointerGetDatum(b))));
|
return DatumGetBool(DirectFunctionCall2Coll(text_lt,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
|
PointerGetDatum(a),
|
||||||
|
PointerGetDatum(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32
|
static int32
|
||||||
gbt_textcmp(const bytea *a, const bytea *b)
|
gbt_textcmp(const bytea *a, const bytea *b)
|
||||||
{
|
{
|
||||||
return DatumGetInt32(DirectFunctionCall2WithCollation(bttextcmp, DEFAULT_COLLATION_OID, PointerGetDatum(a), PointerGetDatum(b)));
|
return DatumGetInt32(DirectFunctionCall2Coll(bttextcmp,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
|
PointerGetDatum(a),
|
||||||
|
PointerGetDatum(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gbtree_vinfo tinfo =
|
static gbtree_vinfo tinfo =
|
||||||
|
@ -1206,7 +1206,7 @@ index_reloptions(RegProcedure amoptions, Datum reloptions, bool validate)
|
|||||||
/* Can't use OidFunctionCallN because we might get a NULL result */
|
/* Can't use OidFunctionCallN because we might get a NULL result */
|
||||||
fmgr_info(amoptions, &flinfo);
|
fmgr_info(amoptions, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 2, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 2, InvalidOid, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = reloptions;
|
fcinfo.arg[0] = reloptions;
|
||||||
fcinfo.arg[1] = BoolGetDatum(validate);
|
fcinfo.arg[1] = BoolGetDatum(validate);
|
||||||
|
@ -42,11 +42,11 @@ ScanKeyEntryInitialize(ScanKey entry,
|
|||||||
entry->sk_attno = attributeNumber;
|
entry->sk_attno = attributeNumber;
|
||||||
entry->sk_strategy = strategy;
|
entry->sk_strategy = strategy;
|
||||||
entry->sk_subtype = subtype;
|
entry->sk_subtype = subtype;
|
||||||
|
entry->sk_collation = collation;
|
||||||
entry->sk_argument = argument;
|
entry->sk_argument = argument;
|
||||||
if (RegProcedureIsValid(procedure))
|
if (RegProcedureIsValid(procedure))
|
||||||
{
|
{
|
||||||
fmgr_info(procedure, &entry->sk_func);
|
fmgr_info(procedure, &entry->sk_func);
|
||||||
entry->sk_func.fn_collation = collation;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -83,9 +83,9 @@ ScanKeyInit(ScanKey entry,
|
|||||||
entry->sk_attno = attributeNumber;
|
entry->sk_attno = attributeNumber;
|
||||||
entry->sk_strategy = strategy;
|
entry->sk_strategy = strategy;
|
||||||
entry->sk_subtype = InvalidOid;
|
entry->sk_subtype = InvalidOid;
|
||||||
|
entry->sk_collation = DEFAULT_COLLATION_OID;
|
||||||
entry->sk_argument = argument;
|
entry->sk_argument = argument;
|
||||||
fmgr_info(procedure, &entry->sk_func);
|
fmgr_info(procedure, &entry->sk_func);
|
||||||
entry->sk_func.fn_collation = DEFAULT_COLLATION_OID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -111,7 +111,7 @@ ScanKeyEntryInitializeWithInfo(ScanKey entry,
|
|||||||
entry->sk_attno = attributeNumber;
|
entry->sk_attno = attributeNumber;
|
||||||
entry->sk_strategy = strategy;
|
entry->sk_strategy = strategy;
|
||||||
entry->sk_subtype = subtype;
|
entry->sk_subtype = subtype;
|
||||||
|
entry->sk_collation = collation;
|
||||||
entry->sk_argument = argument;
|
entry->sk_argument = argument;
|
||||||
fmgr_info_copy(&entry->sk_func, finfo, CurrentMemoryContext);
|
fmgr_info_copy(&entry->sk_func, finfo, CurrentMemoryContext);
|
||||||
entry->sk_func.fn_collation = collation;
|
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,8 @@ callConsistentFn(GinState *ginstate, GinScanKey key)
|
|||||||
*/
|
*/
|
||||||
key->recheckCurItem = true;
|
key->recheckCurItem = true;
|
||||||
|
|
||||||
return DatumGetBool(FunctionCall8(&ginstate->consistentFn[key->attnum - 1],
|
return DatumGetBool(FunctionCall8Coll(&ginstate->consistentFn[key->attnum - 1],
|
||||||
|
ginstate->compareCollation[key->attnum - 1],
|
||||||
PointerGetDatum(key->entryRes),
|
PointerGetDatum(key->entryRes),
|
||||||
UInt16GetDatum(key->strategy),
|
UInt16GetDatum(key->strategy),
|
||||||
key->query,
|
key->query,
|
||||||
@ -250,7 +251,8 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
|
|||||||
* case cmp < 0 => not match and continue scan
|
* case cmp < 0 => not match and continue scan
|
||||||
*----------
|
*----------
|
||||||
*/
|
*/
|
||||||
cmp = DatumGetInt32(FunctionCall4(&btree->ginstate->comparePartialFn[attnum - 1],
|
cmp = DatumGetInt32(FunctionCall4Coll(&btree->ginstate->comparePartialFn[attnum - 1],
|
||||||
|
btree->ginstate->compareCollation[attnum - 1],
|
||||||
scanEntry->queryKey,
|
scanEntry->queryKey,
|
||||||
idatum,
|
idatum,
|
||||||
UInt16GetDatum(scanEntry->strategy),
|
UInt16GetDatum(scanEntry->strategy),
|
||||||
@ -1175,7 +1177,8 @@ matchPartialInPendingList(GinState *ginstate, Page page,
|
|||||||
* case cmp < 0 => not match and continue scan
|
* case cmp < 0 => not match and continue scan
|
||||||
*----------
|
*----------
|
||||||
*/
|
*/
|
||||||
cmp = DatumGetInt32(FunctionCall4(&ginstate->comparePartialFn[entry->attnum - 1],
|
cmp = DatumGetInt32(FunctionCall4Coll(&ginstate->comparePartialFn[entry->attnum - 1],
|
||||||
|
ginstate->compareCollation[entry->attnum - 1],
|
||||||
entry->queryKey,
|
entry->queryKey,
|
||||||
datum[off - 1],
|
datum[off - 1],
|
||||||
UInt16GetDatum(entry->strategy),
|
UInt16GetDatum(entry->strategy),
|
||||||
|
@ -63,23 +63,6 @@ initGinState(GinState *state, Relation index)
|
|||||||
fmgr_info_copy(&(state->compareFn[i]),
|
fmgr_info_copy(&(state->compareFn[i]),
|
||||||
index_getprocinfo(index, i + 1, GIN_COMPARE_PROC),
|
index_getprocinfo(index, i + 1, GIN_COMPARE_PROC),
|
||||||
CurrentMemoryContext);
|
CurrentMemoryContext);
|
||||||
|
|
||||||
/*
|
|
||||||
* If the index column has a specified collation, index_getprocinfo
|
|
||||||
* will have installed it into the fmgr info, and we should honor it.
|
|
||||||
* However, we may have a collatable storage type for a noncollatable
|
|
||||||
* indexed data type (for instance, hstore uses text index entries).
|
|
||||||
* If there's no index collation then specify default collation in
|
|
||||||
* case the comparison function needs one. This is harmless if the
|
|
||||||
* comparison function doesn't care about collation, so we just do it
|
|
||||||
* unconditionally. (We could alternatively call get_typcollation,
|
|
||||||
* but that seems like expensive overkill --- there aren't going to be
|
|
||||||
* any cases where a GIN storage type has a nondefault collation.)
|
|
||||||
*/
|
|
||||||
if (!OidIsValid(state->compareFn[i].fn_collation))
|
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID,
|
|
||||||
&(state->compareFn[i]));
|
|
||||||
|
|
||||||
fmgr_info_copy(&(state->extractValueFn[i]),
|
fmgr_info_copy(&(state->extractValueFn[i]),
|
||||||
index_getprocinfo(index, i + 1, GIN_EXTRACTVALUE_PROC),
|
index_getprocinfo(index, i + 1, GIN_EXTRACTVALUE_PROC),
|
||||||
CurrentMemoryContext);
|
CurrentMemoryContext);
|
||||||
@ -98,18 +81,29 @@ initGinState(GinState *state, Relation index)
|
|||||||
fmgr_info_copy(&(state->comparePartialFn[i]),
|
fmgr_info_copy(&(state->comparePartialFn[i]),
|
||||||
index_getprocinfo(index, i + 1, GIN_COMPARE_PARTIAL_PROC),
|
index_getprocinfo(index, i + 1, GIN_COMPARE_PARTIAL_PROC),
|
||||||
CurrentMemoryContext);
|
CurrentMemoryContext);
|
||||||
|
|
||||||
/* As above, install collation spec in case compare fn needs it */
|
|
||||||
if (!OidIsValid(state->comparePartialFn[i].fn_collation))
|
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID,
|
|
||||||
&(state->comparePartialFn[i]));
|
|
||||||
|
|
||||||
state->canPartialMatch[i] = true;
|
state->canPartialMatch[i] = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state->canPartialMatch[i] = false;
|
state->canPartialMatch[i] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the index column has a specified collation, we should honor that
|
||||||
|
* while doing comparisons. However, we may have a collatable storage
|
||||||
|
* type for a noncollatable indexed data type (for instance, hstore
|
||||||
|
* uses text index entries). If there's no index collation then
|
||||||
|
* specify default collation in case the comparison function needs
|
||||||
|
* collation. This is harmless if the comparison function doesn't
|
||||||
|
* care about collation, so we just do it unconditionally. (We could
|
||||||
|
* alternatively call get_typcollation, but that seems like expensive
|
||||||
|
* overkill --- there aren't going to be any cases where a GIN storage
|
||||||
|
* type has a nondefault collation.)
|
||||||
|
*/
|
||||||
|
if (OidIsValid(index->rd_indcollation[i]))
|
||||||
|
state->compareCollation[i] = index->rd_indcollation[i];
|
||||||
|
else
|
||||||
|
state->compareCollation[i] = DEFAULT_COLLATION_OID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +292,8 @@ ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* both not null, so safe to call the compareFn */
|
/* both not null, so safe to call the compareFn */
|
||||||
return DatumGetInt32(FunctionCall2(&ginstate->compareFn[attnum - 1],
|
return DatumGetInt32(FunctionCall2Coll(&ginstate->compareFn[attnum - 1],
|
||||||
|
ginstate->compareCollation[attnum - 1],
|
||||||
a, b));
|
a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,6 +329,7 @@ typedef struct
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FmgrInfo *cmpDatumFunc;
|
FmgrInfo *cmpDatumFunc;
|
||||||
|
Oid collation;
|
||||||
bool haveDups;
|
bool haveDups;
|
||||||
} cmpEntriesArg;
|
} cmpEntriesArg;
|
||||||
|
|
||||||
@ -355,7 +351,8 @@ cmpEntries(const void *a, const void *b, void *arg)
|
|||||||
else if (bb->isnull)
|
else if (bb->isnull)
|
||||||
res = -1; /* not-NULL "<" NULL */
|
res = -1; /* not-NULL "<" NULL */
|
||||||
else
|
else
|
||||||
res = DatumGetInt32(FunctionCall2(data->cmpDatumFunc,
|
res = DatumGetInt32(FunctionCall2Coll(data->cmpDatumFunc,
|
||||||
|
data->collation,
|
||||||
aa->datum, bb->datum));
|
aa->datum, bb->datum));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -456,6 +453,7 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
|
|||||||
}
|
}
|
||||||
|
|
||||||
arg.cmpDatumFunc = &ginstate->compareFn[attnum - 1];
|
arg.cmpDatumFunc = &ginstate->compareFn[attnum - 1];
|
||||||
|
arg.collation = ginstate->compareCollation[attnum - 1];
|
||||||
arg.haveDups = false;
|
arg.haveDups = false;
|
||||||
qsort_arg(keydata, *nentries, sizeof(keyEntryData),
|
qsort_arg(keydata, *nentries, sizeof(keyEntryData),
|
||||||
cmpEntries, (void *) &arg);
|
cmpEntries, (void *) &arg);
|
||||||
|
@ -137,7 +137,8 @@ gistindex_keytest(IndexScanDesc scan,
|
|||||||
*/
|
*/
|
||||||
recheck = true;
|
recheck = true;
|
||||||
|
|
||||||
test = FunctionCall5(&key->sk_func,
|
test = FunctionCall5Coll(&key->sk_func,
|
||||||
|
key->sk_collation,
|
||||||
PointerGetDatum(&de),
|
PointerGetDatum(&de),
|
||||||
key->sk_argument,
|
key->sk_argument,
|
||||||
Int32GetDatum(key->sk_strategy),
|
Int32GetDatum(key->sk_strategy),
|
||||||
@ -195,7 +196,8 @@ gistindex_keytest(IndexScanDesc scan,
|
|||||||
* can't tolerate lossy distance calculations on leaf tuples;
|
* can't tolerate lossy distance calculations on leaf tuples;
|
||||||
* there is no opportunity to re-sort the tuples afterwards.
|
* there is no opportunity to re-sort the tuples afterwards.
|
||||||
*/
|
*/
|
||||||
dist = FunctionCall4(&key->sk_func,
|
dist = FunctionCall4Coll(&key->sk_func,
|
||||||
|
key->sk_collation,
|
||||||
PointerGetDatum(&de),
|
PointerGetDatum(&de),
|
||||||
key->sk_argument,
|
key->sk_argument,
|
||||||
Int32GetDatum(key->sk_strategy),
|
Int32GetDatum(key->sk_strategy),
|
||||||
|
@ -169,8 +169,7 @@ gistrescan(PG_FUNCTION_ARGS)
|
|||||||
* comparisons. The original operator is passed to the Consistent
|
* comparisons. The original operator is passed to the Consistent
|
||||||
* function in the form of its strategy number, which is available
|
* function in the form of its strategy number, which is available
|
||||||
* from the sk_strategy field, and its subtype from the sk_subtype
|
* from the sk_strategy field, and its subtype from the sk_subtype
|
||||||
* field. Also, preserve sk_func.fn_collation which is the input
|
* field.
|
||||||
* collation for the operator.
|
|
||||||
*
|
*
|
||||||
* Next, if any of keys is a NULL and that key is not marked with
|
* Next, if any of keys is a NULL and that key is not marked with
|
||||||
* SK_SEARCHNULL/SK_SEARCHNOTNULL then nothing can be found (ie, we
|
* SK_SEARCHNULL/SK_SEARCHNOTNULL then nothing can be found (ie, we
|
||||||
@ -181,10 +180,8 @@ gistrescan(PG_FUNCTION_ARGS)
|
|||||||
for (i = 0; i < scan->numberOfKeys; i++)
|
for (i = 0; i < scan->numberOfKeys; i++)
|
||||||
{
|
{
|
||||||
ScanKey skey = scan->keyData + i;
|
ScanKey skey = scan->keyData + i;
|
||||||
Oid collation = skey->sk_func.fn_collation;
|
|
||||||
|
|
||||||
skey->sk_func = so->giststate->consistentFn[skey->sk_attno - 1];
|
skey->sk_func = so->giststate->consistentFn[skey->sk_attno - 1];
|
||||||
skey->sk_func.fn_collation = collation;
|
|
||||||
|
|
||||||
if (skey->sk_flags & SK_ISNULL)
|
if (skey->sk_flags & SK_ISNULL)
|
||||||
{
|
{
|
||||||
@ -205,16 +202,13 @@ gistrescan(PG_FUNCTION_ARGS)
|
|||||||
* all comparisons. The original operator is passed to the Distance
|
* all comparisons. The original operator is passed to the Distance
|
||||||
* function in the form of its strategy number, which is available
|
* function in the form of its strategy number, which is available
|
||||||
* from the sk_strategy field, and its subtype from the sk_subtype
|
* from the sk_strategy field, and its subtype from the sk_subtype
|
||||||
* field. Also, preserve sk_func.fn_collation which is the input
|
* field.
|
||||||
* collation for the operator.
|
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < scan->numberOfOrderBys; i++)
|
for (i = 0; i < scan->numberOfOrderBys; i++)
|
||||||
{
|
{
|
||||||
ScanKey skey = scan->orderByData + i;
|
ScanKey skey = scan->orderByData + i;
|
||||||
Oid collation = skey->sk_func.fn_collation;
|
|
||||||
|
|
||||||
skey->sk_func = so->giststate->distanceFn[skey->sk_attno - 1];
|
skey->sk_func = so->giststate->distanceFn[skey->sk_attno - 1];
|
||||||
skey->sk_func.fn_collation = collation;
|
|
||||||
|
|
||||||
/* Check we actually have a distance function ... */
|
/* Check we actually have a distance function ... */
|
||||||
if (!OidIsValid(skey->sk_func.fn_oid))
|
if (!OidIsValid(skey->sk_func.fn_oid))
|
||||||
|
@ -56,7 +56,8 @@ _hash_checkqual(IndexScanDesc scan, IndexTuple itup)
|
|||||||
if (key->sk_flags & SK_ISNULL)
|
if (key->sk_flags & SK_ISNULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
test = FunctionCall2(&key->sk_func, datum, key->sk_argument);
|
test = FunctionCall2Coll(&key->sk_func, key->sk_collation,
|
||||||
|
datum, key->sk_argument);
|
||||||
|
|
||||||
if (!DatumGetBool(test))
|
if (!DatumGetBool(test))
|
||||||
return false;
|
return false;
|
||||||
|
@ -872,7 +872,6 @@ index_getprocinfo(Relation irel,
|
|||||||
procnum, attnum, RelationGetRelationName(irel));
|
procnum, attnum, RelationGetRelationName(irel));
|
||||||
|
|
||||||
fmgr_info_cxt(procId, locinfo, irel->rd_indexcxt);
|
fmgr_info_cxt(procId, locinfo, irel->rd_indexcxt);
|
||||||
fmgr_info_set_collation(irel->rd_indcollation[attnum - 1], locinfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return locinfo;
|
return locinfo;
|
||||||
|
@ -2043,7 +2043,8 @@ _bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum,
|
|||||||
if (isNull || (scankey->sk_flags & SK_ISNULL))
|
if (isNull || (scankey->sk_flags & SK_ISNULL))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
result = DatumGetInt32(FunctionCall2(&scankey->sk_func,
|
result = DatumGetInt32(FunctionCall2Coll(&scankey->sk_func,
|
||||||
|
scankey->sk_collation,
|
||||||
datum,
|
datum,
|
||||||
scankey->sk_argument));
|
scankey->sk_argument));
|
||||||
|
|
||||||
|
@ -410,7 +410,8 @@ _bt_compare(Relation rel,
|
|||||||
* to flip the sign of the comparison result. (Unless it's a DESC
|
* to flip the sign of the comparison result. (Unless it's a DESC
|
||||||
* column, in which case we *don't* flip the sign.)
|
* column, in which case we *don't* flip the sign.)
|
||||||
*/
|
*/
|
||||||
result = DatumGetInt32(FunctionCall2(&scankey->sk_func,
|
result = DatumGetInt32(FunctionCall2Coll(&scankey->sk_func,
|
||||||
|
scankey->sk_collation,
|
||||||
datum,
|
datum,
|
||||||
scankey->sk_argument));
|
scankey->sk_argument));
|
||||||
|
|
||||||
@ -721,7 +722,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
cur->sk_attno,
|
cur->sk_attno,
|
||||||
InvalidStrategy,
|
InvalidStrategy,
|
||||||
cur->sk_subtype,
|
cur->sk_subtype,
|
||||||
cur->sk_func.fn_collation,
|
cur->sk_collation,
|
||||||
procinfo,
|
procinfo,
|
||||||
cur->sk_argument);
|
cur->sk_argument);
|
||||||
}
|
}
|
||||||
@ -742,7 +743,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
cur->sk_attno,
|
cur->sk_attno,
|
||||||
InvalidStrategy,
|
InvalidStrategy,
|
||||||
cur->sk_subtype,
|
cur->sk_subtype,
|
||||||
cur->sk_func.fn_collation,
|
cur->sk_collation,
|
||||||
cmp_proc,
|
cmp_proc,
|
||||||
cur->sk_argument);
|
cur->sk_argument);
|
||||||
}
|
}
|
||||||
|
@ -736,7 +736,9 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
compare = DatumGetInt32(FunctionCall2(&entry->sk_func,
|
compare =
|
||||||
|
DatumGetInt32(FunctionCall2Coll(&entry->sk_func,
|
||||||
|
entry->sk_collation,
|
||||||
attrDatum1,
|
attrDatum1,
|
||||||
attrDatum2));
|
attrDatum2));
|
||||||
|
|
||||||
|
@ -70,8 +70,7 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* We can use the cached (default) support procs since no cross-type
|
* We can use the cached (default) support procs since no cross-type
|
||||||
* comparison can be needed. The cached support proc entries have the
|
* comparison can be needed.
|
||||||
* right collation for the index, too.
|
|
||||||
*/
|
*/
|
||||||
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
|
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
|
||||||
arg = index_getattr(itup, i + 1, itupdesc, &null);
|
arg = index_getattr(itup, i + 1, itupdesc, &null);
|
||||||
@ -81,7 +80,7 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
|
|||||||
(AttrNumber) (i + 1),
|
(AttrNumber) (i + 1),
|
||||||
InvalidStrategy,
|
InvalidStrategy,
|
||||||
InvalidOid,
|
InvalidOid,
|
||||||
procinfo->fn_collation,
|
rel->rd_indcollation[i],
|
||||||
procinfo,
|
procinfo,
|
||||||
arg);
|
arg);
|
||||||
}
|
}
|
||||||
@ -120,8 +119,7 @@ _bt_mkscankey_nodata(Relation rel)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* We can use the cached (default) support procs since no cross-type
|
* We can use the cached (default) support procs since no cross-type
|
||||||
* comparison can be needed. The cached support proc entries have the
|
* comparison can be needed.
|
||||||
* right collation for the index, too.
|
|
||||||
*/
|
*/
|
||||||
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
|
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
|
||||||
flags = SK_ISNULL | (indoption[i] << SK_BT_INDOPTION_SHIFT);
|
flags = SK_ISNULL | (indoption[i] << SK_BT_INDOPTION_SHIFT);
|
||||||
@ -130,7 +128,7 @@ _bt_mkscankey_nodata(Relation rel)
|
|||||||
(AttrNumber) (i + 1),
|
(AttrNumber) (i + 1),
|
||||||
InvalidStrategy,
|
InvalidStrategy,
|
||||||
InvalidOid,
|
InvalidOid,
|
||||||
procinfo->fn_collation,
|
rel->rd_indcollation[i],
|
||||||
procinfo,
|
procinfo,
|
||||||
(Datum) 0);
|
(Datum) 0);
|
||||||
}
|
}
|
||||||
@ -604,7 +602,8 @@ _bt_compare_scankey_args(IndexScanDesc scan, ScanKey op,
|
|||||||
*/
|
*/
|
||||||
if (lefttype == opcintype && righttype == optype)
|
if (lefttype == opcintype && righttype == optype)
|
||||||
{
|
{
|
||||||
*result = DatumGetBool(FunctionCall2(&op->sk_func,
|
*result = DatumGetBool(FunctionCall2Coll(&op->sk_func,
|
||||||
|
op->sk_collation,
|
||||||
leftarg->sk_argument,
|
leftarg->sk_argument,
|
||||||
rightarg->sk_argument));
|
rightarg->sk_argument));
|
||||||
return true;
|
return true;
|
||||||
@ -633,7 +632,8 @@ _bt_compare_scankey_args(IndexScanDesc scan, ScanKey op,
|
|||||||
|
|
||||||
if (RegProcedureIsValid(cmp_proc))
|
if (RegProcedureIsValid(cmp_proc))
|
||||||
{
|
{
|
||||||
*result = DatumGetBool(OidFunctionCall2(cmp_proc,
|
*result = DatumGetBool(OidFunctionCall2Coll(cmp_proc,
|
||||||
|
op->sk_collation,
|
||||||
leftarg->sk_argument,
|
leftarg->sk_argument,
|
||||||
rightarg->sk_argument));
|
rightarg->sk_argument));
|
||||||
return true;
|
return true;
|
||||||
@ -689,6 +689,10 @@ _bt_fix_scankey_strategy(ScanKey skey, int16 *indoption)
|
|||||||
* Likewise, "x IS NOT NULL" is supported. We treat that as either "less
|
* Likewise, "x IS NOT NULL" is supported. We treat that as either "less
|
||||||
* than NULL" in a NULLS LAST index, or "greater than NULL" in a NULLS
|
* than NULL" in a NULLS LAST index, or "greater than NULL" in a NULLS
|
||||||
* FIRST index.
|
* FIRST index.
|
||||||
|
*
|
||||||
|
* Note: someday we might have to fill in sk_collation from the index
|
||||||
|
* column's collation. At the moment this is a non-issue because we'll
|
||||||
|
* never actually call the comparison operator on a NULL.
|
||||||
*/
|
*/
|
||||||
if (skey->sk_flags & SK_ISNULL)
|
if (skey->sk_flags & SK_ISNULL)
|
||||||
{
|
{
|
||||||
@ -703,6 +707,7 @@ _bt_fix_scankey_strategy(ScanKey skey, int16 *indoption)
|
|||||||
{
|
{
|
||||||
skey->sk_strategy = BTEqualStrategyNumber;
|
skey->sk_strategy = BTEqualStrategyNumber;
|
||||||
skey->sk_subtype = InvalidOid;
|
skey->sk_subtype = InvalidOid;
|
||||||
|
skey->sk_collation = InvalidOid;
|
||||||
}
|
}
|
||||||
else if (skey->sk_flags & SK_SEARCHNOTNULL)
|
else if (skey->sk_flags & SK_SEARCHNOTNULL)
|
||||||
{
|
{
|
||||||
@ -711,6 +716,7 @@ _bt_fix_scankey_strategy(ScanKey skey, int16 *indoption)
|
|||||||
else
|
else
|
||||||
skey->sk_strategy = BTLessStrategyNumber;
|
skey->sk_strategy = BTLessStrategyNumber;
|
||||||
skey->sk_subtype = InvalidOid;
|
skey->sk_subtype = InvalidOid;
|
||||||
|
skey->sk_collation = InvalidOid;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -976,7 +982,8 @@ _bt_checkkeys(IndexScanDesc scan,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
test = FunctionCall2(&key->sk_func, datum, key->sk_argument);
|
test = FunctionCall2Coll(&key->sk_func, key->sk_collation,
|
||||||
|
datum, key->sk_argument);
|
||||||
|
|
||||||
if (!DatumGetBool(test))
|
if (!DatumGetBool(test))
|
||||||
{
|
{
|
||||||
@ -1099,7 +1106,8 @@ _bt_check_rowcompare(ScanKey skey, IndexTuple tuple, TupleDesc tupdesc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Perform the test --- three-way comparison not bool operator */
|
/* Perform the test --- three-way comparison not bool operator */
|
||||||
cmpresult = DatumGetInt32(FunctionCall2(&subkey->sk_func,
|
cmpresult = DatumGetInt32(FunctionCall2Coll(&subkey->sk_func,
|
||||||
|
subkey->sk_collation,
|
||||||
datum,
|
datum,
|
||||||
subkey->sk_argument));
|
subkey->sk_argument));
|
||||||
|
|
||||||
|
@ -1930,8 +1930,6 @@ compute_minimal_stats(VacAttrStatsP stats,
|
|||||||
track_cnt = 0;
|
track_cnt = 0;
|
||||||
|
|
||||||
fmgr_info(mystats->eqfunc, &f_cmpeq);
|
fmgr_info(mystats->eqfunc, &f_cmpeq);
|
||||||
/* We always use the default collation for statistics */
|
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &f_cmpeq);
|
|
||||||
|
|
||||||
for (i = 0; i < samplerows; i++)
|
for (i = 0; i < samplerows; i++)
|
||||||
{
|
{
|
||||||
@ -1990,7 +1988,10 @@ compute_minimal_stats(VacAttrStatsP stats,
|
|||||||
firstcount1 = track_cnt;
|
firstcount1 = track_cnt;
|
||||||
for (j = 0; j < track_cnt; j++)
|
for (j = 0; j < track_cnt; j++)
|
||||||
{
|
{
|
||||||
if (DatumGetBool(FunctionCall2(&f_cmpeq, value, track[j].value)))
|
/* We always use the default collation for statistics */
|
||||||
|
if (DatumGetBool(FunctionCall2Coll(&f_cmpeq,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
|
value, track[j].value)))
|
||||||
{
|
{
|
||||||
match = true;
|
match = true;
|
||||||
break;
|
break;
|
||||||
@ -2253,8 +2254,6 @@ compute_scalar_stats(VacAttrStatsP stats,
|
|||||||
|
|
||||||
SelectSortFunction(mystats->ltopr, false, &cmpFn, &cmpFlags);
|
SelectSortFunction(mystats->ltopr, false, &cmpFn, &cmpFlags);
|
||||||
fmgr_info(cmpFn, &f_cmpfn);
|
fmgr_info(cmpFn, &f_cmpfn);
|
||||||
/* We always use the default collation for statistics */
|
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &f_cmpfn);
|
|
||||||
|
|
||||||
/* Initial scan to find sortable values */
|
/* Initial scan to find sortable values */
|
||||||
for (i = 0; i < samplerows; i++)
|
for (i = 0; i < samplerows; i++)
|
||||||
@ -2729,7 +2728,9 @@ compare_scalars(const void *a, const void *b, void *arg)
|
|||||||
CompareScalarsContext *cxt = (CompareScalarsContext *) arg;
|
CompareScalarsContext *cxt = (CompareScalarsContext *) arg;
|
||||||
int32 compare;
|
int32 compare;
|
||||||
|
|
||||||
|
/* We always use the default collation for statistics */
|
||||||
compare = ApplySortFunction(cxt->cmpFn, cxt->cmpFlags,
|
compare = ApplySortFunction(cxt->cmpFn, cxt->cmpFlags,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
da, false, db, false);
|
da, false, db, false);
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
return compare;
|
return compare;
|
||||||
|
@ -1822,7 +1822,8 @@ ExecCallTriggerFunc(TriggerData *trigdata,
|
|||||||
/*
|
/*
|
||||||
* Call the function, passing no arguments but setting a context.
|
* Call the function, passing no arguments but setting a context.
|
||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(fcinfo, finfo, 0, (Node *) trigdata, NULL);
|
InitFunctionCallInfoData(fcinfo, finfo, 0,
|
||||||
|
InvalidOid, (Node *) trigdata, NULL);
|
||||||
|
|
||||||
pgstat_init_function_usage(&fcinfo, &fcusage);
|
pgstat_init_function_usage(&fcinfo, &fcusage);
|
||||||
|
|
||||||
|
@ -96,6 +96,11 @@ get_ts_parser_func(DefElem *defel, int attnum)
|
|||||||
break;
|
break;
|
||||||
case Anum_pg_ts_parser_prslextype:
|
case Anum_pg_ts_parser_prslextype:
|
||||||
nargs = 1;
|
nargs = 1;
|
||||||
|
/*
|
||||||
|
* Note: because the lextype method returns type internal, it must
|
||||||
|
* have an internal-type argument for security reasons. The
|
||||||
|
* argument is not actually used, but is just passed as a zero.
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* should not be here */
|
/* should not be here */
|
||||||
@ -1947,7 +1952,7 @@ getTokenTypes(Oid prsId, List *tokennames)
|
|||||||
elog(ERROR, "method lextype isn't defined for text search parser %u",
|
elog(ERROR, "method lextype isn't defined for text search parser %u",
|
||||||
prsId);
|
prsId);
|
||||||
|
|
||||||
/* OidFunctionCall0 is absent */
|
/* lextype takes one dummy argument */
|
||||||
list = (LexDescr *) DatumGetPointer(OidFunctionCall1(prs->lextypeOid,
|
list = (LexDescr *) DatumGetPointer(OidFunctionCall1(prs->lextypeOid,
|
||||||
(Datum) 0));
|
(Datum) 0));
|
||||||
|
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
* execGrouping.c
|
* execGrouping.c
|
||||||
* executor utility routines for grouping, hashing, and aggregation
|
* executor utility routines for grouping, hashing, and aggregation
|
||||||
*
|
*
|
||||||
|
* Note: we currently assume that equality and hashing functions are not
|
||||||
|
* collation-sensitive, so the code in this file has no support for passing
|
||||||
|
* collation settings through from callers. That may have to change someday.
|
||||||
|
*
|
||||||
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
|
@ -1202,12 +1202,12 @@ init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache,
|
|||||||
|
|
||||||
/* Set up the primary fmgr lookup information */
|
/* Set up the primary fmgr lookup information */
|
||||||
fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
|
fmgr_info_cxt(foid, &(fcache->func), fcacheCxt);
|
||||||
fmgr_info_set_collation(input_collation, &(fcache->func));
|
|
||||||
fmgr_info_set_expr((Node *) fcache->xprstate.expr, &(fcache->func));
|
fmgr_info_set_expr((Node *) fcache->xprstate.expr, &(fcache->func));
|
||||||
|
|
||||||
/* Initialize the function call parameter struct as well */
|
/* Initialize the function call parameter struct as well */
|
||||||
InitFunctionCallInfoData(fcache->fcinfo_data, &(fcache->func),
|
InitFunctionCallInfoData(fcache->fcinfo_data, &(fcache->func),
|
||||||
list_length(fcache->args), NULL, NULL);
|
list_length(fcache->args),
|
||||||
|
input_collation, NULL, NULL);
|
||||||
|
|
||||||
/* If function returns set, prepare expected tuple descriptor */
|
/* If function returns set, prepare expected tuple descriptor */
|
||||||
if (fcache->func.fn_retset && needDescForSets)
|
if (fcache->func.fn_retset && needDescForSets)
|
||||||
@ -1980,6 +1980,7 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
|
|||||||
returnsSet = fcache->func.fn_retset;
|
returnsSet = fcache->func.fn_retset;
|
||||||
InitFunctionCallInfoData(fcinfo, &(fcache->func),
|
InitFunctionCallInfoData(fcinfo, &(fcache->func),
|
||||||
list_length(fcache->args),
|
list_length(fcache->args),
|
||||||
|
fcache->fcinfo_data.fncollation,
|
||||||
NULL, (Node *) &rsinfo);
|
NULL, (Node *) &rsinfo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2017,7 +2018,7 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
|
|||||||
{
|
{
|
||||||
/* Treat funcexpr as a generic expression */
|
/* Treat funcexpr as a generic expression */
|
||||||
direct_function_call = false;
|
direct_function_call = false;
|
||||||
InitFunctionCallInfoData(fcinfo, NULL, 0, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3154,6 +3155,7 @@ ExecEvalRowCompare(RowCompareExprState *rstate,
|
|||||||
FunctionCallInfoData locfcinfo;
|
FunctionCallInfoData locfcinfo;
|
||||||
|
|
||||||
InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
|
InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2,
|
||||||
|
rstate->collations[i],
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
|
locfcinfo.arg[0] = ExecEvalExpr(le, econtext,
|
||||||
&locfcinfo.argnull[0], NULL);
|
&locfcinfo.argnull[0], NULL);
|
||||||
@ -3234,7 +3236,9 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
|
|||||||
bool *isNull, ExprDoneCond *isDone)
|
bool *isNull, ExprDoneCond *isDone)
|
||||||
{
|
{
|
||||||
Datum result = (Datum) 0;
|
Datum result = (Datum) 0;
|
||||||
MinMaxOp op = ((MinMaxExpr *) minmaxExpr->xprstate.expr)->op;
|
MinMaxExpr *minmax = (MinMaxExpr *) minmaxExpr->xprstate.expr;
|
||||||
|
Oid collation = minmax->inputcollid;
|
||||||
|
MinMaxOp op = minmax->op;
|
||||||
FunctionCallInfoData locfcinfo;
|
FunctionCallInfoData locfcinfo;
|
||||||
ListCell *arg;
|
ListCell *arg;
|
||||||
|
|
||||||
@ -3242,7 +3246,8 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
|
|||||||
*isDone = ExprSingleResult;
|
*isDone = ExprSingleResult;
|
||||||
*isNull = true; /* until we get a result */
|
*isNull = true; /* until we get a result */
|
||||||
|
|
||||||
InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2, NULL, NULL);
|
InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2,
|
||||||
|
collation, NULL, NULL);
|
||||||
locfcinfo.argnull[0] = false;
|
locfcinfo.argnull[0] = false;
|
||||||
locfcinfo.argnull[1] = false;
|
locfcinfo.argnull[1] = false;
|
||||||
|
|
||||||
@ -4115,7 +4120,6 @@ ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
|
|||||||
/* Set up the primary fmgr lookup information */
|
/* Set up the primary fmgr lookup information */
|
||||||
fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc),
|
fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc),
|
||||||
econtext->ecxt_per_query_memory);
|
econtext->ecxt_per_query_memory);
|
||||||
/* Note: coercion functions are assumed to not use collation */
|
|
||||||
fmgr_info_set_expr((Node *) acoerce, &(astate->elemfunc));
|
fmgr_info_set_expr((Node *) acoerce, &(astate->elemfunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4124,9 +4128,11 @@ ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
|
|||||||
*
|
*
|
||||||
* We pass on the desttypmod and isExplicit flags whether or not the
|
* We pass on the desttypmod and isExplicit flags whether or not the
|
||||||
* function wants them.
|
* function wants them.
|
||||||
|
*
|
||||||
|
* Note: coercion functions are assumed to not use collation.
|
||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(locfcinfo, &(astate->elemfunc), 3,
|
InitFunctionCallInfoData(locfcinfo, &(astate->elemfunc), 3,
|
||||||
NULL, NULL);
|
InvalidOid, NULL, NULL);
|
||||||
locfcinfo.arg[0] = PointerGetDatum(array);
|
locfcinfo.arg[0] = PointerGetDatum(array);
|
||||||
locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod);
|
locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod);
|
||||||
locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit);
|
locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit);
|
||||||
@ -4699,6 +4705,7 @@ ExecInitExpr(Expr *node, PlanState *parent)
|
|||||||
rstate->rargs = outlist;
|
rstate->rargs = outlist;
|
||||||
Assert(list_length(rcexpr->opfamilies) == nopers);
|
Assert(list_length(rcexpr->opfamilies) == nopers);
|
||||||
rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
|
rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo));
|
||||||
|
rstate->collations = (Oid *) palloc(nopers * sizeof(Oid));
|
||||||
i = 0;
|
i = 0;
|
||||||
forthree(l, rcexpr->opnos, l2, rcexpr->opfamilies, l3, rcexpr->inputcollids)
|
forthree(l, rcexpr->opnos, l2, rcexpr->opfamilies, l3, rcexpr->inputcollids)
|
||||||
{
|
{
|
||||||
@ -4726,7 +4733,7 @@ ExecInitExpr(Expr *node, PlanState *parent)
|
|||||||
* does this code.
|
* does this code.
|
||||||
*/
|
*/
|
||||||
fmgr_info(proc, &(rstate->funcs[i]));
|
fmgr_info(proc, &(rstate->funcs[i]));
|
||||||
fmgr_info_set_collation(inputcollid, &(rstate->funcs[i]));
|
rstate->collations[i] = inputcollid;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
state = (ExprState *) rstate;
|
state = (ExprState *) rstate;
|
||||||
@ -4786,8 +4793,6 @@ ExecInitExpr(Expr *node, PlanState *parent)
|
|||||||
* code.
|
* code.
|
||||||
*/
|
*/
|
||||||
fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
|
fmgr_info(typentry->cmp_proc, &(mstate->cfunc));
|
||||||
fmgr_info_set_collation(minmaxexpr->inputcollid,
|
|
||||||
&(mstate->cfunc));
|
|
||||||
state = (ExprState *) mstate;
|
state = (ExprState *) mstate;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1349,7 +1349,8 @@ index_recheck_constraint(Relation index, Oid *constr_procs,
|
|||||||
if (existing_isnull[i])
|
if (existing_isnull[i])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!DatumGetBool(OidFunctionCall2(constr_procs[i],
|
if (!DatumGetBool(OidFunctionCall2Coll(constr_procs[i],
|
||||||
|
index->rd_indcollation[i],
|
||||||
existing_values[i],
|
existing_values[i],
|
||||||
new_values[i])))
|
new_values[i])))
|
||||||
return false;
|
return false;
|
||||||
|
@ -127,7 +127,7 @@ static Node *sql_fn_param_ref(ParseState *pstate, ParamRef *pref);
|
|||||||
static List *init_execution_state(List *queryTree_list,
|
static List *init_execution_state(List *queryTree_list,
|
||||||
SQLFunctionCachePtr fcache,
|
SQLFunctionCachePtr fcache,
|
||||||
bool lazyEvalOK);
|
bool lazyEvalOK);
|
||||||
static void init_sql_fcache(FmgrInfo *finfo, bool lazyEvalOK);
|
static void init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK);
|
||||||
static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache);
|
static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache);
|
||||||
static bool postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache);
|
static bool postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache);
|
||||||
static void postquel_end(execution_state *es);
|
static void postquel_end(execution_state *es);
|
||||||
@ -363,7 +363,7 @@ init_execution_state(List *queryTree_list,
|
|||||||
* Initialize the SQLFunctionCache for a SQL function
|
* Initialize the SQLFunctionCache for a SQL function
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
init_sql_fcache(FmgrInfo *finfo, bool lazyEvalOK)
|
init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK)
|
||||||
{
|
{
|
||||||
Oid foid = finfo->fn_oid;
|
Oid foid = finfo->fn_oid;
|
||||||
Oid rettype;
|
Oid rettype;
|
||||||
@ -428,7 +428,7 @@ init_sql_fcache(FmgrInfo *finfo, bool lazyEvalOK)
|
|||||||
*/
|
*/
|
||||||
fcache->pinfo = prepare_sql_fn_parse_info(procedureTuple,
|
fcache->pinfo = prepare_sql_fn_parse_info(procedureTuple,
|
||||||
finfo->fn_expr,
|
finfo->fn_expr,
|
||||||
finfo->fn_collation);
|
collation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* And of course we need the function body text.
|
* And of course we need the function body text.
|
||||||
@ -798,7 +798,7 @@ fmgr_sql(PG_FUNCTION_ARGS)
|
|||||||
fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
|
fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
|
||||||
if (fcache == NULL)
|
if (fcache == NULL)
|
||||||
{
|
{
|
||||||
init_sql_fcache(fcinfo->flinfo, lazyEvalOK);
|
init_sql_fcache(fcinfo->flinfo, PG_GET_COLLATION(), lazyEvalOK);
|
||||||
fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
|
fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
|
||||||
}
|
}
|
||||||
eslist = fcache->func_state;
|
eslist = fcache->func_state;
|
||||||
|
@ -130,6 +130,9 @@ typedef struct AggStatePerAggData
|
|||||||
FmgrInfo transfn;
|
FmgrInfo transfn;
|
||||||
FmgrInfo finalfn;
|
FmgrInfo finalfn;
|
||||||
|
|
||||||
|
/* Input collation derived for aggregate */
|
||||||
|
Oid aggCollation;
|
||||||
|
|
||||||
/* number of sorting columns */
|
/* number of sorting columns */
|
||||||
int numSortCols;
|
int numSortCols;
|
||||||
|
|
||||||
@ -430,6 +433,7 @@ advance_transition_function(AggState *aggstate,
|
|||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(*fcinfo, &(peraggstate->transfn),
|
InitFunctionCallInfoData(*fcinfo, &(peraggstate->transfn),
|
||||||
numArguments + 1,
|
numArguments + 1,
|
||||||
|
peraggstate->aggCollation,
|
||||||
(void *) aggstate, NULL);
|
(void *) aggstate, NULL);
|
||||||
fcinfo->arg[0] = pergroupstate->transValue;
|
fcinfo->arg[0] = pergroupstate->transValue;
|
||||||
fcinfo->argnull[0] = pergroupstate->transValueIsNull;
|
fcinfo->argnull[0] = pergroupstate->transValueIsNull;
|
||||||
@ -597,6 +601,8 @@ process_ordered_aggregate_single(AggState *aggstate,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If DISTINCT mode, and not distinct from prior, skip it.
|
* If DISTINCT mode, and not distinct from prior, skip it.
|
||||||
|
*
|
||||||
|
* Note: we assume equality functions don't care about collation.
|
||||||
*/
|
*/
|
||||||
if (isDistinct &&
|
if (isDistinct &&
|
||||||
haveOldVal &&
|
haveOldVal &&
|
||||||
@ -737,6 +743,7 @@ finalize_aggregate(AggState *aggstate,
|
|||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn), 1,
|
InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn), 1,
|
||||||
|
peraggstate->aggCollation,
|
||||||
(void *) aggstate, NULL);
|
(void *) aggstate, NULL);
|
||||||
fcinfo.arg[0] = pergroupstate->transValue;
|
fcinfo.arg[0] = pergroupstate->transValue;
|
||||||
fcinfo.argnull[0] = pergroupstate->transValueIsNull;
|
fcinfo.argnull[0] = pergroupstate->transValueIsNull;
|
||||||
@ -1676,16 +1683,16 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
|
|||||||
&finalfnexpr);
|
&finalfnexpr);
|
||||||
|
|
||||||
fmgr_info(transfn_oid, &peraggstate->transfn);
|
fmgr_info(transfn_oid, &peraggstate->transfn);
|
||||||
fmgr_info_set_collation(aggref->inputcollid, &peraggstate->transfn);
|
|
||||||
fmgr_info_set_expr((Node *) transfnexpr, &peraggstate->transfn);
|
fmgr_info_set_expr((Node *) transfnexpr, &peraggstate->transfn);
|
||||||
|
|
||||||
if (OidIsValid(finalfn_oid))
|
if (OidIsValid(finalfn_oid))
|
||||||
{
|
{
|
||||||
fmgr_info(finalfn_oid, &peraggstate->finalfn);
|
fmgr_info(finalfn_oid, &peraggstate->finalfn);
|
||||||
fmgr_info_set_collation(aggref->inputcollid, &peraggstate->finalfn);
|
|
||||||
fmgr_info_set_expr((Node *) finalfnexpr, &peraggstate->finalfn);
|
fmgr_info_set_expr((Node *) finalfnexpr, &peraggstate->finalfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peraggstate->aggCollation = aggref->inputcollid;
|
||||||
|
|
||||||
get_typlenbyval(aggref->aggtype,
|
get_typlenbyval(aggref->aggtype,
|
||||||
&peraggstate->resulttypeLen,
|
&peraggstate->resulttypeLen,
|
||||||
&peraggstate->resulttypeByVal);
|
&peraggstate->resulttypeByVal);
|
||||||
@ -1833,8 +1840,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
|
|||||||
SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
|
SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
|
||||||
|
|
||||||
fmgr_info(get_opcode(sortcl->eqop), &peraggstate->equalfns[i]);
|
fmgr_info(get_opcode(sortcl->eqop), &peraggstate->equalfns[i]);
|
||||||
fmgr_info_set_collation(aggref->inputcollid,
|
|
||||||
&peraggstate->equalfns[i]);
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
Assert(i == numDistinctCols);
|
Assert(i == numDistinctCols);
|
||||||
|
@ -973,7 +973,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, Index scanrelid,
|
|||||||
this_scan_key->sk_flags = SK_ROW_HEADER;
|
this_scan_key->sk_flags = SK_ROW_HEADER;
|
||||||
this_scan_key->sk_attno = first_sub_key->sk_attno;
|
this_scan_key->sk_attno = first_sub_key->sk_attno;
|
||||||
this_scan_key->sk_strategy = rc->rctype;
|
this_scan_key->sk_strategy = rc->rctype;
|
||||||
/* sk_subtype, sk_func not used in a header */
|
/* sk_subtype, sk_collation, sk_func not used in a header */
|
||||||
this_scan_key->sk_argument = PointerGetDatum(first_sub_key);
|
this_scan_key->sk_argument = PointerGetDatum(first_sub_key);
|
||||||
}
|
}
|
||||||
else if (IsA(clause, ScalarArrayOpExpr))
|
else if (IsA(clause, ScalarArrayOpExpr))
|
||||||
|
@ -327,7 +327,8 @@ heap_compare_slots(MergeAppendState *node, SlotNumber slot1, SlotNumber slot2)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
compare = DatumGetInt32(FunctionCall2(&scankey->sk_func,
|
compare = DatumGetInt32(FunctionCall2Coll(&scankey->sk_func,
|
||||||
|
scankey->sk_collation,
|
||||||
datum1, datum2));
|
datum1, datum2));
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
{
|
{
|
||||||
|
@ -138,11 +138,12 @@ typedef struct MergeJoinClauseData
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The comparison strategy in use, and the lookup info to let us call the
|
* The comparison strategy in use, and the lookup info to let us call the
|
||||||
* btree comparison support function.
|
* btree comparison support function, and the collation to use.
|
||||||
*/
|
*/
|
||||||
bool reverse; /* if true, negate the cmpfn's output */
|
bool reverse; /* if true, negate the cmpfn's output */
|
||||||
bool nulls_first; /* if true, nulls sort low */
|
bool nulls_first; /* if true, nulls sort low */
|
||||||
FmgrInfo cmpfinfo;
|
FmgrInfo cmpfinfo;
|
||||||
|
Oid collation;
|
||||||
} MergeJoinClauseData;
|
} MergeJoinClauseData;
|
||||||
|
|
||||||
/* Result type for MJEvalOuterValues and MJEvalInnerValues */
|
/* Result type for MJEvalOuterValues and MJEvalInnerValues */
|
||||||
@ -242,7 +243,6 @@ MJExamineQuals(List *mergeclauses,
|
|||||||
|
|
||||||
/* Set up the fmgr lookup information */
|
/* Set up the fmgr lookup information */
|
||||||
fmgr_info(cmpproc, &(clause->cmpfinfo));
|
fmgr_info(cmpproc, &(clause->cmpfinfo));
|
||||||
fmgr_info_set_collation(collation, &(clause->cmpfinfo));
|
|
||||||
|
|
||||||
/* Fill the additional comparison-strategy flags */
|
/* Fill the additional comparison-strategy flags */
|
||||||
if (opstrategy == BTLessStrategyNumber)
|
if (opstrategy == BTLessStrategyNumber)
|
||||||
@ -254,6 +254,9 @@ MJExamineQuals(List *mergeclauses,
|
|||||||
|
|
||||||
clause->nulls_first = nulls_first;
|
clause->nulls_first = nulls_first;
|
||||||
|
|
||||||
|
/* ... and the collation too */
|
||||||
|
clause->collation = collation;
|
||||||
|
|
||||||
iClause++;
|
iClause++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,7 +432,7 @@ MJCompare(MergeJoinState *mergestate)
|
|||||||
* OK to call the comparison function.
|
* OK to call the comparison function.
|
||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(fcinfo, &(clause->cmpfinfo), 2,
|
InitFunctionCallInfoData(fcinfo, &(clause->cmpfinfo), 2,
|
||||||
NULL, NULL);
|
clause->collation, NULL, NULL);
|
||||||
fcinfo.arg[0] = clause->ldatum;
|
fcinfo.arg[0] = clause->ldatum;
|
||||||
fcinfo.arg[1] = clause->rdatum;
|
fcinfo.arg[1] = clause->rdatum;
|
||||||
fcinfo.argnull[0] = false;
|
fcinfo.argnull[0] = false;
|
||||||
|
@ -831,8 +831,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
|
|||||||
|
|
||||||
/* Lookup the equality function (potentially cross-type) */
|
/* Lookup the equality function (potentially cross-type) */
|
||||||
fmgr_info(opexpr->opfuncid, &sstate->cur_eq_funcs[i - 1]);
|
fmgr_info(opexpr->opfuncid, &sstate->cur_eq_funcs[i - 1]);
|
||||||
fmgr_info_set_collation(opexpr->inputcollid,
|
|
||||||
&sstate->cur_eq_funcs[i - 1]);
|
|
||||||
fmgr_info_set_expr((Node *) opexpr, &sstate->cur_eq_funcs[i - 1]);
|
fmgr_info_set_expr((Node *) opexpr, &sstate->cur_eq_funcs[i - 1]);
|
||||||
|
|
||||||
/* Look up the equality function for the RHS type */
|
/* Look up the equality function for the RHS type */
|
||||||
@ -841,8 +839,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
|
|||||||
elog(ERROR, "could not find compatible hash operator for operator %u",
|
elog(ERROR, "could not find compatible hash operator for operator %u",
|
||||||
opexpr->opno);
|
opexpr->opno);
|
||||||
fmgr_info(get_opcode(rhs_eq_oper), &sstate->tab_eq_funcs[i - 1]);
|
fmgr_info(get_opcode(rhs_eq_oper), &sstate->tab_eq_funcs[i - 1]);
|
||||||
fmgr_info_set_collation(opexpr->inputcollid,
|
|
||||||
&sstate->tab_eq_funcs[i - 1]);
|
|
||||||
|
|
||||||
/* Lookup the associated hash functions */
|
/* Lookup the associated hash functions */
|
||||||
if (!get_op_hash_functions(opexpr->opno,
|
if (!get_op_hash_functions(opexpr->opno,
|
||||||
|
@ -81,6 +81,8 @@ typedef struct WindowStatePerFuncData
|
|||||||
|
|
||||||
FmgrInfo flinfo; /* fmgr lookup data for window function */
|
FmgrInfo flinfo; /* fmgr lookup data for window function */
|
||||||
|
|
||||||
|
Oid winCollation; /* collation derived for window function */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need the len and byval info for the result of each function in order
|
* We need the len and byval info for the result of each function in order
|
||||||
* to know how to copy/delete values.
|
* to know how to copy/delete values.
|
||||||
@ -289,6 +291,7 @@ advance_windowaggregate(WindowAggState *winstate,
|
|||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(*fcinfo, &(peraggstate->transfn),
|
InitFunctionCallInfoData(*fcinfo, &(peraggstate->transfn),
|
||||||
numArguments + 1,
|
numArguments + 1,
|
||||||
|
perfuncstate->winCollation,
|
||||||
(void *) winstate, NULL);
|
(void *) winstate, NULL);
|
||||||
fcinfo->arg[0] = peraggstate->transValue;
|
fcinfo->arg[0] = peraggstate->transValue;
|
||||||
fcinfo->argnull[0] = peraggstate->transValueIsNull;
|
fcinfo->argnull[0] = peraggstate->transValueIsNull;
|
||||||
@ -340,6 +343,7 @@ finalize_windowaggregate(WindowAggState *winstate,
|
|||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn), 1,
|
InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn), 1,
|
||||||
|
perfuncstate->winCollation,
|
||||||
(void *) winstate, NULL);
|
(void *) winstate, NULL);
|
||||||
fcinfo.arg[0] = peraggstate->transValue;
|
fcinfo.arg[0] = peraggstate->transValue;
|
||||||
fcinfo.argnull[0] = peraggstate->transValueIsNull;
|
fcinfo.argnull[0] = peraggstate->transValueIsNull;
|
||||||
@ -627,6 +631,7 @@ eval_windowfunction(WindowAggState *winstate, WindowStatePerFunc perfuncstate,
|
|||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(fcinfo, &(perfuncstate->flinfo),
|
InitFunctionCallInfoData(fcinfo, &(perfuncstate->flinfo),
|
||||||
perfuncstate->numArguments,
|
perfuncstate->numArguments,
|
||||||
|
perfuncstate->winCollation,
|
||||||
(void *) perfuncstate->winobj, NULL);
|
(void *) perfuncstate->winobj, NULL);
|
||||||
/* Just in case, make all the regular argument slots be null */
|
/* Just in case, make all the regular argument slots be null */
|
||||||
memset(fcinfo.argnull, true, perfuncstate->numArguments);
|
memset(fcinfo.argnull, true, perfuncstate->numArguments);
|
||||||
@ -1561,9 +1566,10 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
|
|||||||
|
|
||||||
fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo,
|
fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo,
|
||||||
econtext->ecxt_per_query_memory);
|
econtext->ecxt_per_query_memory);
|
||||||
fmgr_info_set_collation(wfunc->inputcollid, &perfuncstate->flinfo);
|
|
||||||
fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo);
|
fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo);
|
||||||
|
|
||||||
|
perfuncstate->winCollation = wfunc->inputcollid;
|
||||||
|
|
||||||
get_typlenbyval(wfunc->wintype,
|
get_typlenbyval(wfunc->wintype,
|
||||||
&perfuncstate->resulttypeLen,
|
&perfuncstate->resulttypeLen,
|
||||||
&perfuncstate->resulttypeByVal);
|
&perfuncstate->resulttypeByVal);
|
||||||
@ -1801,13 +1807,11 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc,
|
|||||||
&finalfnexpr);
|
&finalfnexpr);
|
||||||
|
|
||||||
fmgr_info(transfn_oid, &peraggstate->transfn);
|
fmgr_info(transfn_oid, &peraggstate->transfn);
|
||||||
fmgr_info_set_collation(wfunc->inputcollid, &peraggstate->transfn);
|
|
||||||
fmgr_info_set_expr((Node *) transfnexpr, &peraggstate->transfn);
|
fmgr_info_set_expr((Node *) transfnexpr, &peraggstate->transfn);
|
||||||
|
|
||||||
if (OidIsValid(finalfn_oid))
|
if (OidIsValid(finalfn_oid))
|
||||||
{
|
{
|
||||||
fmgr_info(finalfn_oid, &peraggstate->finalfn);
|
fmgr_info(finalfn_oid, &peraggstate->finalfn);
|
||||||
fmgr_info_set_collation(wfunc->inputcollid, &peraggstate->finalfn);
|
|
||||||
fmgr_info_set_expr((Node *) finalfnexpr, &peraggstate->finalfn);
|
fmgr_info_set_expr((Node *) finalfnexpr, &peraggstate->finalfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3189,8 +3189,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
|
|||||||
if (oproid == InvalidOid)
|
if (oproid == InvalidOid)
|
||||||
elog(ERROR, "no < operator for opfamily %u", opfamily);
|
elog(ERROR, "no < operator for opfamily %u", opfamily);
|
||||||
fmgr_info(get_opcode(oproid), <proc);
|
fmgr_info(get_opcode(oproid), <proc);
|
||||||
fmgr_info_set_collation(collation, <proc);
|
greaterstr = make_greater_string(prefix_const, <proc, collation);
|
||||||
greaterstr = make_greater_string(prefix_const, <proc);
|
|
||||||
if (greaterstr)
|
if (greaterstr)
|
||||||
{
|
{
|
||||||
expr = make_opclause(oproid, BOOLOID, false,
|
expr = make_opclause(oproid, BOOLOID, false,
|
||||||
|
@ -349,8 +349,12 @@ HandleFunctionRequest(StringInfo msgBuf)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare function call info block and insert arguments.
|
* Prepare function call info block and insert arguments.
|
||||||
|
*
|
||||||
|
* Note: for now we pass collation = InvalidOid, so collation-sensitive
|
||||||
|
* functions can't be called this way. Perhaps we should pass
|
||||||
|
* DEFAULT_COLLATION_OID, instead?
|
||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(fcinfo, &fip->flinfo, 0, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &fip->flinfo, 0, InvalidOid, NULL, NULL);
|
||||||
|
|
||||||
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
|
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
|
||||||
rformat = parse_fcall_arguments(msgBuf, fip, &fcinfo);
|
rformat = parse_fcall_arguments(msgBuf, fip, &fcinfo);
|
||||||
|
@ -54,7 +54,7 @@ tt_setup_firstcall(FuncCallContext *funcctx, Oid prsid)
|
|||||||
|
|
||||||
st = (TSTokenTypeStorage *) palloc(sizeof(TSTokenTypeStorage));
|
st = (TSTokenTypeStorage *) palloc(sizeof(TSTokenTypeStorage));
|
||||||
st->cur = 0;
|
st->cur = 0;
|
||||||
/* OidFunctionCall0 is absent */
|
/* lextype takes one dummy argument */
|
||||||
st->list = (LexDescr *) DatumGetPointer(OidFunctionCall1(prs->lextypeOid,
|
st->list = (LexDescr *) DatumGetPointer(OidFunctionCall1(prs->lextypeOid,
|
||||||
(Datum) 0));
|
(Datum) 0));
|
||||||
funcctx->user_fctx = (void *) st;
|
funcctx->user_fctx = (void *) st;
|
||||||
|
@ -3127,6 +3127,7 @@ array_eq(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
||||||
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
||||||
|
Oid collation = PG_GET_COLLATION();
|
||||||
int ndims1 = ARR_NDIM(array1);
|
int ndims1 = ARR_NDIM(array1);
|
||||||
int ndims2 = ARR_NDIM(array2);
|
int ndims2 = ARR_NDIM(array2);
|
||||||
int *dims1 = ARR_DIMS(array1);
|
int *dims1 = ARR_DIMS(array1);
|
||||||
@ -3184,7 +3185,7 @@ array_eq(PG_FUNCTION_ARGS)
|
|||||||
* apply the operator to each pair of array elements.
|
* apply the operator to each pair of array elements.
|
||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
|
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
|
||||||
NULL, NULL);
|
collation, NULL, NULL);
|
||||||
|
|
||||||
/* Loop over source data */
|
/* Loop over source data */
|
||||||
nitems = ArrayGetNItems(ndims1, dims1);
|
nitems = ArrayGetNItems(ndims1, dims1);
|
||||||
@ -3367,8 +3368,7 @@ array_cmp(FunctionCallInfo fcinfo)
|
|||||||
*/
|
*/
|
||||||
typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
|
typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
|
||||||
if (typentry == NULL ||
|
if (typentry == NULL ||
|
||||||
typentry->type_id != element_type ||
|
typentry->type_id != element_type)
|
||||||
typentry->cmp_proc_finfo.fn_collation != collation)
|
|
||||||
{
|
{
|
||||||
typentry = lookup_type_cache(element_type,
|
typentry = lookup_type_cache(element_type,
|
||||||
TYPECACHE_CMP_PROC_FINFO);
|
TYPECACHE_CMP_PROC_FINFO);
|
||||||
@ -3378,7 +3378,6 @@ array_cmp(FunctionCallInfo fcinfo)
|
|||||||
errmsg("could not identify a comparison function for type %s",
|
errmsg("could not identify a comparison function for type %s",
|
||||||
format_type_be(element_type))));
|
format_type_be(element_type))));
|
||||||
fcinfo->flinfo->fn_extra = (void *) typentry;
|
fcinfo->flinfo->fn_extra = (void *) typentry;
|
||||||
typentry->cmp_proc_finfo.fn_collation = collation;
|
|
||||||
}
|
}
|
||||||
typlen = typentry->typlen;
|
typlen = typentry->typlen;
|
||||||
typbyval = typentry->typbyval;
|
typbyval = typentry->typbyval;
|
||||||
@ -3388,7 +3387,7 @@ array_cmp(FunctionCallInfo fcinfo)
|
|||||||
* apply the operator to each pair of array elements.
|
* apply the operator to each pair of array elements.
|
||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
|
InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
|
||||||
NULL, NULL);
|
collation, NULL, NULL);
|
||||||
|
|
||||||
/* Loop over source data */
|
/* Loop over source data */
|
||||||
min_nitems = Min(nitems1, nitems2);
|
min_nitems = Min(nitems1, nitems2);
|
||||||
@ -3573,7 +3572,7 @@ hash_array(PG_FUNCTION_ARGS)
|
|||||||
* apply the hash function to each array element.
|
* apply the hash function to each array element.
|
||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(locfcinfo, &typentry->hash_proc_finfo, 1,
|
InitFunctionCallInfoData(locfcinfo, &typentry->hash_proc_finfo, 1,
|
||||||
NULL, NULL);
|
InvalidOid, NULL, NULL);
|
||||||
|
|
||||||
/* Loop over source data */
|
/* Loop over source data */
|
||||||
nitems = ArrayGetNItems(ndims, dims);
|
nitems = ArrayGetNItems(ndims, dims);
|
||||||
@ -3647,8 +3646,8 @@ hash_array(PG_FUNCTION_ARGS)
|
|||||||
* When matchall is false, return true if any members of array1 are in array2.
|
* When matchall is false, return true if any members of array1 are in array2.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
array_contain_compare(ArrayType *array1, ArrayType *array2, bool matchall,
|
array_contain_compare(ArrayType *array1, ArrayType *array2, Oid collation,
|
||||||
void **fn_extra)
|
bool matchall, void **fn_extra)
|
||||||
{
|
{
|
||||||
bool result = matchall;
|
bool result = matchall;
|
||||||
Oid element_type = ARR_ELEMTYPE(array1);
|
Oid element_type = ARR_ELEMTYPE(array1);
|
||||||
@ -3707,7 +3706,7 @@ array_contain_compare(ArrayType *array1, ArrayType *array2, bool matchall,
|
|||||||
* Apply the comparison operator to each pair of array elements.
|
* Apply the comparison operator to each pair of array elements.
|
||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
|
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
|
||||||
NULL, NULL);
|
collation, NULL, NULL);
|
||||||
|
|
||||||
/* Loop over source data */
|
/* Loop over source data */
|
||||||
nelems1 = ArrayGetNItems(ARR_NDIM(array1), ARR_DIMS(array1));
|
nelems1 = ArrayGetNItems(ARR_NDIM(array1), ARR_DIMS(array1));
|
||||||
@ -3811,9 +3810,10 @@ arrayoverlap(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
||||||
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
||||||
|
Oid collation = PG_GET_COLLATION();
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
result = array_contain_compare(array1, array2, false,
|
result = array_contain_compare(array1, array2, collation, false,
|
||||||
&fcinfo->flinfo->fn_extra);
|
&fcinfo->flinfo->fn_extra);
|
||||||
|
|
||||||
/* Avoid leaking memory when handed toasted input. */
|
/* Avoid leaking memory when handed toasted input. */
|
||||||
@ -3828,9 +3828,10 @@ arraycontains(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
||||||
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
||||||
|
Oid collation = PG_GET_COLLATION();
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
result = array_contain_compare(array2, array1, true,
|
result = array_contain_compare(array2, array1, collation, true,
|
||||||
&fcinfo->flinfo->fn_extra);
|
&fcinfo->flinfo->fn_extra);
|
||||||
|
|
||||||
/* Avoid leaking memory when handed toasted input. */
|
/* Avoid leaking memory when handed toasted input. */
|
||||||
@ -3845,9 +3846,10 @@ arraycontained(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
||||||
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
||||||
|
Oid collation = PG_GET_COLLATION();
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
result = array_contain_compare(array1, array2, true,
|
result = array_contain_compare(array1, array2, collation, true,
|
||||||
&fcinfo->flinfo->fn_extra);
|
&fcinfo->flinfo->fn_extra);
|
||||||
|
|
||||||
/* Avoid leaking memory when handed toasted input. */
|
/* Avoid leaking memory when handed toasted input. */
|
||||||
|
@ -213,7 +213,8 @@ int2vectorrecv(PG_FUNCTION_ARGS)
|
|||||||
* fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
|
* fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
|
||||||
* parameter.
|
* parameter.
|
||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3, NULL, NULL);
|
InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
|
||||||
|
InvalidOid, NULL, NULL);
|
||||||
|
|
||||||
locfcinfo.arg[0] = PointerGetDatum(buf);
|
locfcinfo.arg[0] = PointerGetDatum(buf);
|
||||||
locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID);
|
locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID);
|
||||||
|
@ -174,10 +174,12 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation)
|
|||||||
if (pg_database_encoding_max_length() > 1)
|
if (pg_database_encoding_max_length() > 1)
|
||||||
{
|
{
|
||||||
/* lower's result is never packed, so OK to use old macros here */
|
/* lower's result is never packed, so OK to use old macros here */
|
||||||
pat = DatumGetTextP(DirectFunctionCall1WithCollation(lower, collation, PointerGetDatum(pat)));
|
pat = DatumGetTextP(DirectFunctionCall1Coll(lower, collation,
|
||||||
|
PointerGetDatum(pat)));
|
||||||
p = VARDATA(pat);
|
p = VARDATA(pat);
|
||||||
plen = (VARSIZE(pat) - VARHDRSZ);
|
plen = (VARSIZE(pat) - VARHDRSZ);
|
||||||
str = DatumGetTextP(DirectFunctionCall1WithCollation(lower, collation, PointerGetDatum(str)));
|
str = DatumGetTextP(DirectFunctionCall1Coll(lower, collation,
|
||||||
|
PointerGetDatum(str)));
|
||||||
s = VARDATA(str);
|
s = VARDATA(str);
|
||||||
slen = (VARSIZE(str) - VARHDRSZ);
|
slen = (VARSIZE(str) - VARHDRSZ);
|
||||||
if (GetDatabaseEncoding() == PG_UTF8)
|
if (GetDatabaseEncoding() == PG_UTF8)
|
||||||
|
@ -263,7 +263,8 @@ oidvectorrecv(PG_FUNCTION_ARGS)
|
|||||||
* fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
|
* fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
|
||||||
* parameter.
|
* parameter.
|
||||||
*/
|
*/
|
||||||
InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3, NULL, NULL);
|
InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
|
||||||
|
InvalidOid, NULL, NULL);
|
||||||
|
|
||||||
locfcinfo.arg[0] = PointerGetDatum(buf);
|
locfcinfo.arg[0] = PointerGetDatum(buf);
|
||||||
locfcinfo.arg[1] = ObjectIdGetDatum(OIDOID);
|
locfcinfo.arg[1] = ObjectIdGetDatum(OIDOID);
|
||||||
|
@ -3963,7 +3963,10 @@ ri_AttributesEqual(Oid eq_opr, Oid typeid,
|
|||||||
BoolGetDatum(false)); /* implicit coercion */
|
BoolGetDatum(false)); /* implicit coercion */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply the comparison operator */
|
/*
|
||||||
|
* Apply the comparison operator. We assume it doesn't
|
||||||
|
* care about collations.
|
||||||
|
*/
|
||||||
return DatumGetBool(FunctionCall2(&entry->eq_opr_finfo,
|
return DatumGetBool(FunctionCall2(&entry->eq_opr_finfo,
|
||||||
oldvalue, newvalue));
|
oldvalue, newvalue));
|
||||||
}
|
}
|
||||||
|
@ -867,6 +867,7 @@ record_cmp(FunctionCallInfo fcinfo)
|
|||||||
while (i1 < ncolumns1 || i2 < ncolumns2)
|
while (i1 < ncolumns1 || i2 < ncolumns2)
|
||||||
{
|
{
|
||||||
TypeCacheEntry *typentry;
|
TypeCacheEntry *typentry;
|
||||||
|
Oid collation;
|
||||||
FunctionCallInfoData locfcinfo;
|
FunctionCallInfoData locfcinfo;
|
||||||
int32 cmpresult;
|
int32 cmpresult;
|
||||||
|
|
||||||
@ -898,6 +899,14 @@ record_cmp(FunctionCallInfo fcinfo)
|
|||||||
format_type_be(tupdesc2->attrs[i2]->atttypid),
|
format_type_be(tupdesc2->attrs[i2]->atttypid),
|
||||||
j + 1)));
|
j + 1)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If they're not same collation, we don't complain here, but the
|
||||||
|
* comparison function might.
|
||||||
|
*/
|
||||||
|
collation = tupdesc1->attrs[i1]->attcollation;
|
||||||
|
if (collation != tupdesc2->attrs[i2]->attcollation)
|
||||||
|
collation = InvalidOid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup the comparison function if not done already
|
* Lookup the comparison function if not done already
|
||||||
*/
|
*/
|
||||||
@ -935,7 +944,7 @@ record_cmp(FunctionCallInfo fcinfo)
|
|||||||
|
|
||||||
/* Compare the pair of elements */
|
/* Compare the pair of elements */
|
||||||
InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
|
InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
|
||||||
NULL, NULL);
|
collation, NULL, NULL);
|
||||||
locfcinfo.arg[0] = values1[i1];
|
locfcinfo.arg[0] = values1[i1];
|
||||||
locfcinfo.arg[1] = values2[i2];
|
locfcinfo.arg[1] = values2[i2];
|
||||||
locfcinfo.argnull[0] = false;
|
locfcinfo.argnull[0] = false;
|
||||||
@ -1093,6 +1102,7 @@ record_eq(PG_FUNCTION_ARGS)
|
|||||||
while (i1 < ncolumns1 || i2 < ncolumns2)
|
while (i1 < ncolumns1 || i2 < ncolumns2)
|
||||||
{
|
{
|
||||||
TypeCacheEntry *typentry;
|
TypeCacheEntry *typentry;
|
||||||
|
Oid collation;
|
||||||
FunctionCallInfoData locfcinfo;
|
FunctionCallInfoData locfcinfo;
|
||||||
bool oprresult;
|
bool oprresult;
|
||||||
|
|
||||||
@ -1124,6 +1134,14 @@ record_eq(PG_FUNCTION_ARGS)
|
|||||||
format_type_be(tupdesc2->attrs[i2]->atttypid),
|
format_type_be(tupdesc2->attrs[i2]->atttypid),
|
||||||
j + 1)));
|
j + 1)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If they're not same collation, we don't complain here, but the
|
||||||
|
* equality function might.
|
||||||
|
*/
|
||||||
|
collation = tupdesc1->attrs[i1]->attcollation;
|
||||||
|
if (collation != tupdesc2->attrs[i2]->attcollation)
|
||||||
|
collation = InvalidOid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup the equality function if not done already
|
* Lookup the equality function if not done already
|
||||||
*/
|
*/
|
||||||
@ -1154,7 +1172,7 @@ record_eq(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
/* Compare the pair of elements */
|
/* Compare the pair of elements */
|
||||||
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
|
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
|
||||||
NULL, NULL);
|
collation, NULL, NULL);
|
||||||
locfcinfo.arg[0] = values1[i1];
|
locfcinfo.arg[0] = values1[i1];
|
||||||
locfcinfo.arg[1] = values2[i2];
|
locfcinfo.arg[1] = values2[i2];
|
||||||
locfcinfo.argnull[0] = false;
|
locfcinfo.argnull[0] = false;
|
||||||
|
@ -285,17 +285,18 @@ var_eq_const(VariableStatData *vardata, Oid operator,
|
|||||||
FmgrInfo eqproc;
|
FmgrInfo eqproc;
|
||||||
|
|
||||||
fmgr_info(get_opcode(operator), &eqproc);
|
fmgr_info(get_opcode(operator), &eqproc);
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &eqproc);
|
|
||||||
|
|
||||||
for (i = 0; i < nvalues; i++)
|
for (i = 0; i < nvalues; i++)
|
||||||
{
|
{
|
||||||
/* be careful to apply operator right way 'round */
|
/* be careful to apply operator right way 'round */
|
||||||
if (varonleft)
|
if (varonleft)
|
||||||
match = DatumGetBool(FunctionCall2(&eqproc,
|
match = DatumGetBool(FunctionCall2Coll(&eqproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
values[i],
|
values[i],
|
||||||
constval));
|
constval));
|
||||||
else
|
else
|
||||||
match = DatumGetBool(FunctionCall2(&eqproc,
|
match = DatumGetBool(FunctionCall2Coll(&eqproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
constval,
|
constval,
|
||||||
values[i]));
|
values[i]));
|
||||||
if (match)
|
if (match)
|
||||||
@ -515,7 +516,6 @@ scalarineqsel(PlannerInfo *root, Oid operator, bool isgt,
|
|||||||
stats = (Form_pg_statistic) GETSTRUCT(vardata->statsTuple);
|
stats = (Form_pg_statistic) GETSTRUCT(vardata->statsTuple);
|
||||||
|
|
||||||
fmgr_info(get_opcode(operator), &opproc);
|
fmgr_info(get_opcode(operator), &opproc);
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &opproc);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have most-common-values info, add up the fractions of the MCV
|
* If we have most-common-values info, add up the fractions of the MCV
|
||||||
@ -598,10 +598,12 @@ mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc,
|
|||||||
for (i = 0; i < nvalues; i++)
|
for (i = 0; i < nvalues; i++)
|
||||||
{
|
{
|
||||||
if (varonleft ?
|
if (varonleft ?
|
||||||
DatumGetBool(FunctionCall2(opproc,
|
DatumGetBool(FunctionCall2Coll(opproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
values[i],
|
values[i],
|
||||||
constval)) :
|
constval)) :
|
||||||
DatumGetBool(FunctionCall2(opproc,
|
DatumGetBool(FunctionCall2Coll(opproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
constval,
|
constval,
|
||||||
values[i])))
|
values[i])))
|
||||||
mcv_selec += numbers[i];
|
mcv_selec += numbers[i];
|
||||||
@ -678,10 +680,12 @@ histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc,
|
|||||||
for (i = n_skip; i < nvalues - n_skip; i++)
|
for (i = n_skip; i < nvalues - n_skip; i++)
|
||||||
{
|
{
|
||||||
if (varonleft ?
|
if (varonleft ?
|
||||||
DatumGetBool(FunctionCall2(opproc,
|
DatumGetBool(FunctionCall2Coll(opproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
values[i],
|
values[i],
|
||||||
constval)) :
|
constval)) :
|
||||||
DatumGetBool(FunctionCall2(opproc,
|
DatumGetBool(FunctionCall2Coll(opproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
constval,
|
constval,
|
||||||
values[i])))
|
values[i])))
|
||||||
nmatch++;
|
nmatch++;
|
||||||
@ -802,7 +806,8 @@ ineq_histogram_selectivity(PlannerInfo *root,
|
|||||||
NULL,
|
NULL,
|
||||||
&values[probe]);
|
&values[probe]);
|
||||||
|
|
||||||
ltcmp = DatumGetBool(FunctionCall2(opproc,
|
ltcmp = DatumGetBool(FunctionCall2Coll(opproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
values[probe],
|
values[probe],
|
||||||
constval));
|
constval));
|
||||||
if (isgt)
|
if (isgt)
|
||||||
@ -1255,7 +1260,6 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate)
|
|||||||
|
|
||||||
/* Try to use the histogram entries to get selectivity */
|
/* Try to use the histogram entries to get selectivity */
|
||||||
fmgr_info(get_opcode(operator), &opproc);
|
fmgr_info(get_opcode(operator), &opproc);
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &opproc);
|
|
||||||
|
|
||||||
selec = histogram_selectivity(&vardata, &opproc, constval, true,
|
selec = histogram_selectivity(&vardata, &opproc, constval, true,
|
||||||
10, 1, &hist_size);
|
10, 1, &hist_size);
|
||||||
@ -1705,7 +1709,6 @@ scalararraysel(PlannerInfo *root,
|
|||||||
if (!oprsel)
|
if (!oprsel)
|
||||||
return (Selectivity) 0.5;
|
return (Selectivity) 0.5;
|
||||||
fmgr_info(oprsel, &oprselproc);
|
fmgr_info(oprsel, &oprselproc);
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &oprselproc);
|
|
||||||
|
|
||||||
/* deconstruct the expression */
|
/* deconstruct the expression */
|
||||||
Assert(list_length(clause->args) == 2);
|
Assert(list_length(clause->args) == 2);
|
||||||
@ -2126,7 +2129,6 @@ eqjoinsel_inner(Oid operator,
|
|||||||
nmatches;
|
nmatches;
|
||||||
|
|
||||||
fmgr_info(get_opcode(operator), &eqproc);
|
fmgr_info(get_opcode(operator), &eqproc);
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &eqproc);
|
|
||||||
hasmatch1 = (bool *) palloc0(nvalues1 * sizeof(bool));
|
hasmatch1 = (bool *) palloc0(nvalues1 * sizeof(bool));
|
||||||
hasmatch2 = (bool *) palloc0(nvalues2 * sizeof(bool));
|
hasmatch2 = (bool *) palloc0(nvalues2 * sizeof(bool));
|
||||||
|
|
||||||
@ -2146,7 +2148,8 @@ eqjoinsel_inner(Oid operator,
|
|||||||
{
|
{
|
||||||
if (hasmatch2[j])
|
if (hasmatch2[j])
|
||||||
continue;
|
continue;
|
||||||
if (DatumGetBool(FunctionCall2(&eqproc,
|
if (DatumGetBool(FunctionCall2Coll(&eqproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
values1[i],
|
values1[i],
|
||||||
values2[j])))
|
values2[j])))
|
||||||
{
|
{
|
||||||
@ -2349,7 +2352,6 @@ eqjoinsel_semi(Oid operator,
|
|||||||
nmatches;
|
nmatches;
|
||||||
|
|
||||||
fmgr_info(get_opcode(operator), &eqproc);
|
fmgr_info(get_opcode(operator), &eqproc);
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &eqproc);
|
|
||||||
hasmatch1 = (bool *) palloc0(nvalues1 * sizeof(bool));
|
hasmatch1 = (bool *) palloc0(nvalues1 * sizeof(bool));
|
||||||
hasmatch2 = (bool *) palloc0(nvalues2 * sizeof(bool));
|
hasmatch2 = (bool *) palloc0(nvalues2 * sizeof(bool));
|
||||||
|
|
||||||
@ -2368,7 +2370,8 @@ eqjoinsel_semi(Oid operator,
|
|||||||
{
|
{
|
||||||
if (hasmatch2[j])
|
if (hasmatch2[j])
|
||||||
continue;
|
continue;
|
||||||
if (DatumGetBool(FunctionCall2(&eqproc,
|
if (DatumGetBool(FunctionCall2Coll(&eqproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
values1[i],
|
values1[i],
|
||||||
values2[j])))
|
values2[j])))
|
||||||
{
|
{
|
||||||
@ -4503,7 +4506,6 @@ get_variable_range(PlannerInfo *root, VariableStatData *vardata, Oid sortop,
|
|||||||
FmgrInfo opproc;
|
FmgrInfo opproc;
|
||||||
|
|
||||||
fmgr_info(get_opcode(sortop), &opproc);
|
fmgr_info(get_opcode(sortop), &opproc);
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &opproc);
|
|
||||||
|
|
||||||
for (i = 0; i < nvalues; i++)
|
for (i = 0; i < nvalues; i++)
|
||||||
{
|
{
|
||||||
@ -4513,12 +4515,16 @@ get_variable_range(PlannerInfo *root, VariableStatData *vardata, Oid sortop,
|
|||||||
tmin_is_mcv = tmax_is_mcv = have_data = true;
|
tmin_is_mcv = tmax_is_mcv = have_data = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (DatumGetBool(FunctionCall2(&opproc, values[i], tmin)))
|
if (DatumGetBool(FunctionCall2Coll(&opproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
|
values[i], tmin)))
|
||||||
{
|
{
|
||||||
tmin = values[i];
|
tmin = values[i];
|
||||||
tmin_is_mcv = true;
|
tmin_is_mcv = true;
|
||||||
}
|
}
|
||||||
if (DatumGetBool(FunctionCall2(&opproc, tmax, values[i])))
|
if (DatumGetBool(FunctionCall2Coll(&opproc,
|
||||||
|
DEFAULT_COLLATION_OID,
|
||||||
|
tmax, values[i])))
|
||||||
{
|
{
|
||||||
tmax = values[i];
|
tmax = values[i];
|
||||||
tmax_is_mcv = true;
|
tmax_is_mcv = true;
|
||||||
@ -5183,7 +5189,6 @@ prefix_selectivity(PlannerInfo *root, VariableStatData *vardata,
|
|||||||
if (cmpopr == InvalidOid)
|
if (cmpopr == InvalidOid)
|
||||||
elog(ERROR, "no >= operator for opfamily %u", opfamily);
|
elog(ERROR, "no >= operator for opfamily %u", opfamily);
|
||||||
fmgr_info(get_opcode(cmpopr), &opproc);
|
fmgr_info(get_opcode(cmpopr), &opproc);
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &opproc);
|
|
||||||
|
|
||||||
prefixsel = ineq_histogram_selectivity(root, vardata, &opproc, true,
|
prefixsel = ineq_histogram_selectivity(root, vardata, &opproc, true,
|
||||||
prefixcon->constvalue,
|
prefixcon->constvalue,
|
||||||
@ -5205,9 +5210,8 @@ prefix_selectivity(PlannerInfo *root, VariableStatData *vardata,
|
|||||||
if (cmpopr == InvalidOid)
|
if (cmpopr == InvalidOid)
|
||||||
elog(ERROR, "no < operator for opfamily %u", opfamily);
|
elog(ERROR, "no < operator for opfamily %u", opfamily);
|
||||||
fmgr_info(get_opcode(cmpopr), &opproc);
|
fmgr_info(get_opcode(cmpopr), &opproc);
|
||||||
fmgr_info_set_collation(DEFAULT_COLLATION_OID, &opproc);
|
greaterstrcon = make_greater_string(prefixcon, &opproc,
|
||||||
|
DEFAULT_COLLATION_OID);
|
||||||
greaterstrcon = make_greater_string(prefixcon, &opproc);
|
|
||||||
if (greaterstrcon)
|
if (greaterstrcon)
|
||||||
{
|
{
|
||||||
Selectivity topsel;
|
Selectivity topsel;
|
||||||
@ -5502,22 +5506,21 @@ pattern_selectivity(Const *patt, Pattern_Type ptype)
|
|||||||
* in the form of a Const node; else return NULL.
|
* in the form of a Const node; else return NULL.
|
||||||
*
|
*
|
||||||
* The caller must provide the appropriate "less than" comparison function
|
* The caller must provide the appropriate "less than" comparison function
|
||||||
* for testing the strings. In particular, ltproc->fn_collation specifies
|
* for testing the strings, along with the collation to use.
|
||||||
* the locale for comparisons.
|
|
||||||
*
|
*
|
||||||
* The key requirement here is that given a prefix string, say "foo",
|
* The key requirement here is that given a prefix string, say "foo",
|
||||||
* we must be able to generate another string "fop" that is greater than
|
* we must be able to generate another string "fop" that is greater than
|
||||||
* all strings "foobar" starting with "foo". We can test that we have
|
* all strings "foobar" starting with "foo". We can test that we have
|
||||||
* generated a string greater than the prefix string, but in non-C locales
|
* generated a string greater than the prefix string, but in non-C collations
|
||||||
* that is not a bulletproof guarantee that an extension of the string might
|
* that is not a bulletproof guarantee that an extension of the string might
|
||||||
* not sort after it; an example is that "foo " is less than "foo!", but it
|
* not sort after it; an example is that "foo " is less than "foo!", but it
|
||||||
* is not clear that a "dictionary" sort ordering will consider "foo!" less
|
* is not clear that a "dictionary" sort ordering will consider "foo!" less
|
||||||
* than "foo bar". CAUTION: Therefore, this function should be used only for
|
* than "foo bar". CAUTION: Therefore, this function should be used only for
|
||||||
* estimation purposes when working in a non-C locale.
|
* estimation purposes when working in a non-C collation.
|
||||||
*
|
*
|
||||||
* To try to catch most cases where an extended string might otherwise sort
|
* To try to catch most cases where an extended string might otherwise sort
|
||||||
* before the result value, we determine which of the strings "Z", "z", "y",
|
* before the result value, we determine which of the strings "Z", "z", "y",
|
||||||
* and "9" is seen as largest by the locale, and append that to the given
|
* and "9" is seen as largest by the collation, and append that to the given
|
||||||
* prefix before trying to find a string that compares as larger.
|
* prefix before trying to find a string that compares as larger.
|
||||||
*
|
*
|
||||||
* If we max out the righthand byte, truncate off the last character
|
* If we max out the righthand byte, truncate off the last character
|
||||||
@ -5529,7 +5532,7 @@ pattern_selectivity(Const *patt, Pattern_Type ptype)
|
|||||||
* won't have to try more than one or two strings before succeeding.
|
* won't have to try more than one or two strings before succeeding.
|
||||||
*/
|
*/
|
||||||
Const *
|
Const *
|
||||||
make_greater_string(const Const *str_const, FmgrInfo *ltproc)
|
make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation)
|
||||||
{
|
{
|
||||||
Oid datatype = str_const->consttype;
|
Oid datatype = str_const->consttype;
|
||||||
char *workstr;
|
char *workstr;
|
||||||
@ -5565,7 +5568,7 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc)
|
|||||||
{
|
{
|
||||||
workstr = TextDatumGetCString(str_const->constvalue);
|
workstr = TextDatumGetCString(str_const->constvalue);
|
||||||
len = strlen(workstr);
|
len = strlen(workstr);
|
||||||
if (lc_collate_is_c(ltproc->fn_collation) || len == 0)
|
if (lc_collate_is_c(collation) || len == 0)
|
||||||
cmpstr = str_const->constvalue;
|
cmpstr = str_const->constvalue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5573,19 +5576,19 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc)
|
|||||||
static char suffixchar = 0;
|
static char suffixchar = 0;
|
||||||
static Oid suffixcollation = 0;
|
static Oid suffixcollation = 0;
|
||||||
|
|
||||||
if (!suffixchar || suffixcollation != ltproc->fn_collation)
|
if (!suffixchar || suffixcollation != collation)
|
||||||
{
|
{
|
||||||
char *best;
|
char *best;
|
||||||
|
|
||||||
best = "Z";
|
best = "Z";
|
||||||
if (varstr_cmp(best, 1, "z", 1, ltproc->fn_collation) < 0)
|
if (varstr_cmp(best, 1, "z", 1, collation) < 0)
|
||||||
best = "z";
|
best = "z";
|
||||||
if (varstr_cmp(best, 1, "y", 1, ltproc->fn_collation) < 0)
|
if (varstr_cmp(best, 1, "y", 1, collation) < 0)
|
||||||
best = "y";
|
best = "y";
|
||||||
if (varstr_cmp(best, 1, "9", 1, ltproc->fn_collation) < 0)
|
if (varstr_cmp(best, 1, "9", 1, collation) < 0)
|
||||||
best = "9";
|
best = "9";
|
||||||
suffixchar = *best;
|
suffixchar = *best;
|
||||||
suffixcollation = ltproc->fn_collation;
|
suffixcollation = collation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And build the string to compare to */
|
/* And build the string to compare to */
|
||||||
@ -5621,7 +5624,8 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc)
|
|||||||
else
|
else
|
||||||
workstr_const = string_to_bytea_const(workstr, len);
|
workstr_const = string_to_bytea_const(workstr, len);
|
||||||
|
|
||||||
if (DatumGetBool(FunctionCall2(ltproc,
|
if (DatumGetBool(FunctionCall2Coll(ltproc,
|
||||||
|
collation,
|
||||||
cmpstr,
|
cmpstr,
|
||||||
workstr_const->constvalue)))
|
workstr_const->constvalue)))
|
||||||
{
|
{
|
||||||
|
2
src/backend/utils/cache/catcache.c
vendored
2
src/backend/utils/cache/catcache.c
vendored
@ -935,7 +935,7 @@ CatalogCacheInitializeCache(CatCache *cache)
|
|||||||
cache->cc_skey[i].sk_strategy = BTEqualStrategyNumber;
|
cache->cc_skey[i].sk_strategy = BTEqualStrategyNumber;
|
||||||
cache->cc_skey[i].sk_subtype = InvalidOid;
|
cache->cc_skey[i].sk_subtype = InvalidOid;
|
||||||
/* Currently, there are no catcaches on collation-aware data types */
|
/* Currently, there are no catcaches on collation-aware data types */
|
||||||
cache->cc_skey[i].sk_func.fn_collation = InvalidOid;
|
cache->cc_skey[i].sk_collation = InvalidOid;
|
||||||
|
|
||||||
CACHE4_elog(DEBUG2, "CatalogCacheInitializeCache %s %d %p",
|
CACHE4_elog(DEBUG2, "CatalogCacheInitializeCache %s %d %p",
|
||||||
cache->cc_relname,
|
cache->cc_relname,
|
||||||
|
@ -71,7 +71,6 @@ typedef struct
|
|||||||
bool fn_strict; /* function is "strict" (NULL in => NULL out) */
|
bool fn_strict; /* function is "strict" (NULL in => NULL out) */
|
||||||
bool fn_retset; /* function returns a set (over multiple calls) */
|
bool fn_retset; /* function returns a set (over multiple calls) */
|
||||||
unsigned char fn_stats; /* collect stats if track_functions > this */
|
unsigned char fn_stats; /* collect stats if track_functions > this */
|
||||||
Oid fn_collation; /* collation that function should use */
|
|
||||||
void *fn_extra; /* extra space for use by handler */
|
void *fn_extra; /* extra space for use by handler */
|
||||||
MemoryContext fn_mcxt; /* memory context to store fn_extra in */
|
MemoryContext fn_mcxt; /* memory context to store fn_extra in */
|
||||||
Node *fn_expr; /* expression parse tree for call, or NULL */
|
Node *fn_expr; /* expression parse tree for call, or NULL */
|
||||||
@ -92,14 +91,12 @@ these values come from the function's pg_proc entry. fn_stats is also
|
|||||||
set up to control whether or not to track runtime statistics for calling
|
set up to control whether or not to track runtime statistics for calling
|
||||||
this function.
|
this function.
|
||||||
|
|
||||||
fn_collation supplies the collation to use for collation-sensitive
|
If the function is being called as part of a SQL expression, fn_expr will
|
||||||
functions. If the function is being called as part of a SQL expression,
|
point to the expression parse tree for the function call; this can be used
|
||||||
fn_expr will point to the expression parse tree for the function call; this
|
to extract parse-time knowledge about the actual arguments. Note that this
|
||||||
can be used to extract parse-time knowledge about the actual arguments.
|
field really is information about the arguments rather than information
|
||||||
Note that these two fields really are information about the arguments
|
about the function, but it's proven to be more convenient to keep it in
|
||||||
rather than information about the function, but it's proven to be more
|
FmgrInfo than in FunctionCallInfoData where it might more logically go.
|
||||||
convenient to keep them in FmgrInfo than in FunctionCallInfoData where
|
|
||||||
they might more logically go.
|
|
||||||
|
|
||||||
|
|
||||||
During a call of a function, the following data structure is created
|
During a call of a function, the following data structure is created
|
||||||
@ -110,6 +107,7 @@ typedef struct
|
|||||||
FmgrInfo *flinfo; /* ptr to lookup info used for this call */
|
FmgrInfo *flinfo; /* ptr to lookup info used for this call */
|
||||||
Node *context; /* pass info about context of call */
|
Node *context; /* pass info about context of call */
|
||||||
Node *resultinfo; /* pass or return extra info about result */
|
Node *resultinfo; /* pass or return extra info about result */
|
||||||
|
Oid fncollation; /* collation for function to use */
|
||||||
bool isnull; /* function must set true if result is NULL */
|
bool isnull; /* function must set true if result is NULL */
|
||||||
short nargs; /* # arguments actually passed */
|
short nargs; /* # arguments actually passed */
|
||||||
Datum arg[FUNC_MAX_ARGS]; /* Arguments passed to function */
|
Datum arg[FUNC_MAX_ARGS]; /* Arguments passed to function */
|
||||||
@ -137,6 +135,11 @@ function that returns a set, as discussed below.) Like the context field,
|
|||||||
resultinfo is a hook for expansion; fmgr itself doesn't constrain the use
|
resultinfo is a hook for expansion; fmgr itself doesn't constrain the use
|
||||||
of the field.
|
of the field.
|
||||||
|
|
||||||
|
fncollation is the input collation derived by the parser, or InvalidOid
|
||||||
|
when there are no inputs of collatable types or they don't share a common
|
||||||
|
collation. This is effectively a hidden additional argument, which
|
||||||
|
collation-sensitive functions can use to determine their behavior.
|
||||||
|
|
||||||
nargs, arg[], and argnull[] hold the arguments being passed to the function.
|
nargs, arg[], and argnull[] hold the arguments being passed to the function.
|
||||||
Notice that all the arguments passed to a function (as well as its result
|
Notice that all the arguments passed to a function (as well as its result
|
||||||
value) will now uniformly be of type Datum. As discussed below, callers
|
value) will now uniformly be of type Datum. As discussed below, callers
|
||||||
|
@ -192,7 +192,6 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
|
|||||||
* elogs.
|
* elogs.
|
||||||
*/
|
*/
|
||||||
finfo->fn_oid = InvalidOid;
|
finfo->fn_oid = InvalidOid;
|
||||||
finfo->fn_collation = InvalidOid; /* caller may set this later */
|
|
||||||
finfo->fn_extra = NULL;
|
finfo->fn_extra = NULL;
|
||||||
finfo->fn_mcxt = mcxt;
|
finfo->fn_mcxt = mcxt;
|
||||||
finfo->fn_expr = NULL; /* caller may set this later */
|
finfo->fn_expr = NULL; /* caller may set this later */
|
||||||
@ -901,7 +900,6 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
|
fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
|
||||||
fcinfo->flinfo->fn_mcxt, true);
|
fcinfo->flinfo->fn_mcxt, true);
|
||||||
fcache->flinfo.fn_collation = fcinfo->flinfo->fn_collation;
|
|
||||||
fcache->flinfo.fn_expr = fcinfo->flinfo->fn_expr;
|
fcache->flinfo.fn_expr = fcinfo->flinfo->fn_expr;
|
||||||
|
|
||||||
tuple = SearchSysCache1(PROCOID,
|
tuple = SearchSysCache1(PROCOID,
|
||||||
@ -1012,12 +1010,12 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
|
|||||||
* look at FmgrInfo, since there won't be any.
|
* look at FmgrInfo, since there won't be any.
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
DirectFunctionCall1(PGFunction func, Datum arg1)
|
DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, NULL, 1, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, NULL, 1, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.argnull[0] = false;
|
fcinfo.argnull[0] = false;
|
||||||
@ -1032,12 +1030,12 @@ DirectFunctionCall1(PGFunction func, Datum arg1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
DirectFunctionCall2(PGFunction func, Datum arg1, Datum arg2)
|
DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, NULL, 2, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, NULL, 2, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1054,13 +1052,13 @@ DirectFunctionCall2(PGFunction func, Datum arg1, Datum arg2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
DirectFunctionCall3(PGFunction func, Datum arg1, Datum arg2,
|
DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3)
|
Datum arg3)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, NULL, 3, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, NULL, 3, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1079,13 +1077,13 @@ DirectFunctionCall3(PGFunction func, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
DirectFunctionCall4(PGFunction func, Datum arg1, Datum arg2,
|
DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4)
|
Datum arg3, Datum arg4)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, NULL, 4, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, NULL, 4, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1106,13 +1104,13 @@ DirectFunctionCall4(PGFunction func, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
DirectFunctionCall5(PGFunction func, Datum arg1, Datum arg2,
|
DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5)
|
Datum arg3, Datum arg4, Datum arg5)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, NULL, 5, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, NULL, 5, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1135,14 +1133,14 @@ DirectFunctionCall5(PGFunction func, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
DirectFunctionCall6(PGFunction func, Datum arg1, Datum arg2,
|
DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6)
|
Datum arg6)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, NULL, 6, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, NULL, 6, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1167,14 +1165,14 @@ DirectFunctionCall6(PGFunction func, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
DirectFunctionCall7(PGFunction func, Datum arg1, Datum arg2,
|
DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7)
|
Datum arg6, Datum arg7)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, NULL, 7, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, NULL, 7, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1201,14 +1199,14 @@ DirectFunctionCall7(PGFunction func, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
DirectFunctionCall8(PGFunction func, Datum arg1, Datum arg2,
|
DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8)
|
Datum arg6, Datum arg7, Datum arg8)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, NULL, 8, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, NULL, 8, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1237,7 +1235,7 @@ DirectFunctionCall8(PGFunction func, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
DirectFunctionCall9(PGFunction func, Datum arg1, Datum arg2,
|
DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8,
|
Datum arg6, Datum arg7, Datum arg8,
|
||||||
Datum arg9)
|
Datum arg9)
|
||||||
@ -1245,7 +1243,7 @@ DirectFunctionCall9(PGFunction func, Datum arg1, Datum arg2,
|
|||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, NULL, 9, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, NULL, 9, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1276,72 +1274,18 @@ DirectFunctionCall9(PGFunction func, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These are the same as DirectFunctionCallN except that a nonzero
|
|
||||||
* collation can be specified. No other fields of FmgrInfo are made valid.
|
|
||||||
*/
|
|
||||||
Datum
|
|
||||||
DirectFunctionCall1WithCollation(PGFunction func, Oid collation, Datum arg1)
|
|
||||||
{
|
|
||||||
FunctionCallInfoData fcinfo;
|
|
||||||
FmgrInfo flinfo;
|
|
||||||
Datum result;
|
|
||||||
|
|
||||||
MemSet(&flinfo, 0, sizeof(flinfo));
|
|
||||||
flinfo.fn_collation = collation;
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 1, NULL, NULL);
|
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
|
||||||
fcinfo.argnull[0] = false;
|
|
||||||
|
|
||||||
result = (*func) (&fcinfo);
|
|
||||||
|
|
||||||
/* Check for null result, since caller is clearly not expecting one */
|
|
||||||
if (fcinfo.isnull)
|
|
||||||
elog(ERROR, "function %p returned NULL", (void *) func);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Datum
|
|
||||||
DirectFunctionCall2WithCollation(PGFunction func, Oid collation,
|
|
||||||
Datum arg1, Datum arg2)
|
|
||||||
{
|
|
||||||
FunctionCallInfoData fcinfo;
|
|
||||||
FmgrInfo flinfo;
|
|
||||||
Datum result;
|
|
||||||
|
|
||||||
MemSet(&flinfo, 0, sizeof(flinfo));
|
|
||||||
flinfo.fn_collation = collation;
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 2, NULL, NULL);
|
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
|
||||||
fcinfo.arg[1] = arg2;
|
|
||||||
fcinfo.argnull[0] = false;
|
|
||||||
fcinfo.argnull[1] = false;
|
|
||||||
|
|
||||||
result = (*func) (&fcinfo);
|
|
||||||
|
|
||||||
/* Check for null result, since caller is clearly not expecting one */
|
|
||||||
if (fcinfo.isnull)
|
|
||||||
elog(ERROR, "function %p returned NULL", (void *) func);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are for invocation of a previously-looked-up function with a
|
* These are for invocation of a previously-looked-up function with a
|
||||||
* directly-computed parameter list. Note that neither arguments nor result
|
* directly-computed parameter list. Note that neither arguments nor result
|
||||||
* are allowed to be NULL.
|
* are allowed to be NULL.
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
FunctionCall1(FmgrInfo *flinfo, Datum arg1)
|
FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 1, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.argnull[0] = false;
|
fcinfo.argnull[0] = false;
|
||||||
@ -1356,7 +1300,7 @@ FunctionCall1(FmgrInfo *flinfo, Datum arg1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
FunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2)
|
FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* XXX if you change this routine, see also the inlined version in
|
* XXX if you change this routine, see also the inlined version in
|
||||||
@ -1365,7 +1309,7 @@ FunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2)
|
|||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 2, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1382,13 +1326,13 @@ FunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
FunctionCall3(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3)
|
Datum arg3)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 3, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 3, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1407,13 +1351,13 @@ FunctionCall3(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
FunctionCall4(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4)
|
Datum arg3, Datum arg4)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 4, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 4, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1434,13 +1378,13 @@ FunctionCall4(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
FunctionCall5(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5)
|
Datum arg3, Datum arg4, Datum arg5)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 5, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 5, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1463,14 +1407,14 @@ FunctionCall5(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
FunctionCall6(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6)
|
Datum arg6)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 6, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 6, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1495,14 +1439,14 @@ FunctionCall6(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
FunctionCall7(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7)
|
Datum arg6, Datum arg7)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 7, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 7, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1529,14 +1473,14 @@ FunctionCall7(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
FunctionCall8(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8)
|
Datum arg6, Datum arg7, Datum arg8)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 8, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 8, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1565,7 +1509,7 @@ FunctionCall8(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
FunctionCall9(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8,
|
Datum arg6, Datum arg7, Datum arg8,
|
||||||
Datum arg9)
|
Datum arg9)
|
||||||
@ -1573,7 +1517,7 @@ FunctionCall9(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
|||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 9, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 9, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1612,7 +1556,7 @@ FunctionCall9(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
|||||||
* do the fmgr_info() once and then use FunctionCallN().
|
* do the fmgr_info() once and then use FunctionCallN().
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
OidFunctionCall0(Oid functionId)
|
OidFunctionCall0Coll(Oid functionId, Oid collation)
|
||||||
{
|
{
|
||||||
FmgrInfo flinfo;
|
FmgrInfo flinfo;
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
@ -1620,7 +1564,7 @@ OidFunctionCall0(Oid functionId)
|
|||||||
|
|
||||||
fmgr_info(functionId, &flinfo);
|
fmgr_info(functionId, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 0, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 0, collation, NULL, NULL);
|
||||||
|
|
||||||
result = FunctionCallInvoke(&fcinfo);
|
result = FunctionCallInvoke(&fcinfo);
|
||||||
|
|
||||||
@ -1632,7 +1576,7 @@ OidFunctionCall0(Oid functionId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
OidFunctionCall1(Oid functionId, Datum arg1)
|
OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
|
||||||
{
|
{
|
||||||
FmgrInfo flinfo;
|
FmgrInfo flinfo;
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
@ -1640,7 +1584,7 @@ OidFunctionCall1(Oid functionId, Datum arg1)
|
|||||||
|
|
||||||
fmgr_info(functionId, &flinfo);
|
fmgr_info(functionId, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 1, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 1, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.argnull[0] = false;
|
fcinfo.argnull[0] = false;
|
||||||
@ -1655,7 +1599,7 @@ OidFunctionCall1(Oid functionId, Datum arg1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
OidFunctionCall2(Oid functionId, Datum arg1, Datum arg2)
|
OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
|
||||||
{
|
{
|
||||||
FmgrInfo flinfo;
|
FmgrInfo flinfo;
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
@ -1663,7 +1607,7 @@ OidFunctionCall2(Oid functionId, Datum arg1, Datum arg2)
|
|||||||
|
|
||||||
fmgr_info(functionId, &flinfo);
|
fmgr_info(functionId, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 2, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 2, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1680,7 +1624,7 @@ OidFunctionCall2(Oid functionId, Datum arg1, Datum arg2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
OidFunctionCall3(Oid functionId, Datum arg1, Datum arg2,
|
OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3)
|
Datum arg3)
|
||||||
{
|
{
|
||||||
FmgrInfo flinfo;
|
FmgrInfo flinfo;
|
||||||
@ -1689,7 +1633,7 @@ OidFunctionCall3(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
|
|
||||||
fmgr_info(functionId, &flinfo);
|
fmgr_info(functionId, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 3, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 3, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1708,7 +1652,7 @@ OidFunctionCall3(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
OidFunctionCall4(Oid functionId, Datum arg1, Datum arg2,
|
OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4)
|
Datum arg3, Datum arg4)
|
||||||
{
|
{
|
||||||
FmgrInfo flinfo;
|
FmgrInfo flinfo;
|
||||||
@ -1717,7 +1661,7 @@ OidFunctionCall4(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
|
|
||||||
fmgr_info(functionId, &flinfo);
|
fmgr_info(functionId, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 4, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 4, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1738,7 +1682,7 @@ OidFunctionCall4(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
OidFunctionCall5(Oid functionId, Datum arg1, Datum arg2,
|
OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5)
|
Datum arg3, Datum arg4, Datum arg5)
|
||||||
{
|
{
|
||||||
FmgrInfo flinfo;
|
FmgrInfo flinfo;
|
||||||
@ -1747,7 +1691,7 @@ OidFunctionCall5(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
|
|
||||||
fmgr_info(functionId, &flinfo);
|
fmgr_info(functionId, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 5, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 5, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1770,7 +1714,7 @@ OidFunctionCall5(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
OidFunctionCall6(Oid functionId, Datum arg1, Datum arg2,
|
OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6)
|
Datum arg6)
|
||||||
{
|
{
|
||||||
@ -1780,7 +1724,7 @@ OidFunctionCall6(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
|
|
||||||
fmgr_info(functionId, &flinfo);
|
fmgr_info(functionId, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 6, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 6, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1805,7 +1749,7 @@ OidFunctionCall6(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
OidFunctionCall7(Oid functionId, Datum arg1, Datum arg2,
|
OidFunctionCall7Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7)
|
Datum arg6, Datum arg7)
|
||||||
{
|
{
|
||||||
@ -1815,7 +1759,7 @@ OidFunctionCall7(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
|
|
||||||
fmgr_info(functionId, &flinfo);
|
fmgr_info(functionId, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 7, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 7, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1842,7 +1786,7 @@ OidFunctionCall7(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
OidFunctionCall8(Oid functionId, Datum arg1, Datum arg2,
|
OidFunctionCall8Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8)
|
Datum arg6, Datum arg7, Datum arg8)
|
||||||
{
|
{
|
||||||
@ -1852,7 +1796,7 @@ OidFunctionCall8(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
|
|
||||||
fmgr_info(functionId, &flinfo);
|
fmgr_info(functionId, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 8, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 8, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1881,7 +1825,7 @@ OidFunctionCall8(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
|
OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8,
|
Datum arg6, Datum arg7, Datum arg8,
|
||||||
Datum arg9)
|
Datum arg9)
|
||||||
@ -1892,7 +1836,7 @@ OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
|
|||||||
|
|
||||||
fmgr_info(functionId, &flinfo);
|
fmgr_info(functionId, &flinfo);
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, &flinfo, 9, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, &flinfo, 9, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -1953,7 +1897,7 @@ InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
|
|||||||
|
|
||||||
pushed = SPI_push_conditional();
|
pushed = SPI_push_conditional();
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 3, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = CStringGetDatum(str);
|
fcinfo.arg[0] = CStringGetDatum(str);
|
||||||
fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
|
fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
|
||||||
@ -2028,7 +1972,7 @@ ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf,
|
|||||||
|
|
||||||
pushed = SPI_push_conditional();
|
pushed = SPI_push_conditional();
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 3, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = PointerGetDatum(buf);
|
fcinfo.arg[0] = PointerGetDatum(buf);
|
||||||
fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
|
fcinfo.arg[1] = ObjectIdGetDatum(typioparam);
|
||||||
|
@ -373,6 +373,7 @@ struct Tuplesortstate
|
|||||||
Oid datumType;
|
Oid datumType;
|
||||||
FmgrInfo sortOpFn; /* cached lookup data for sortOperator */
|
FmgrInfo sortOpFn; /* cached lookup data for sortOperator */
|
||||||
int sortFnFlags; /* equivalent to sk_flags */
|
int sortFnFlags; /* equivalent to sk_flags */
|
||||||
|
Oid sortCollation; /* equivalent to sk_collation */
|
||||||
/* we need typelen and byval in order to know how to copy the Datums. */
|
/* we need typelen and byval in order to know how to copy the Datums. */
|
||||||
int datumTypeLen;
|
int datumTypeLen;
|
||||||
bool datumTypeByVal;
|
bool datumTypeByVal;
|
||||||
@ -582,7 +583,8 @@ tuplesort_begin_common(int workMem, bool randomAccess)
|
|||||||
Tuplesortstate *
|
Tuplesortstate *
|
||||||
tuplesort_begin_heap(TupleDesc tupDesc,
|
tuplesort_begin_heap(TupleDesc tupDesc,
|
||||||
int nkeys, AttrNumber *attNums,
|
int nkeys, AttrNumber *attNums,
|
||||||
Oid *sortOperators, Oid *collations, bool *nullsFirstFlags,
|
Oid *sortOperators, Oid *sortCollations,
|
||||||
|
bool *nullsFirstFlags,
|
||||||
int workMem, bool randomAccess)
|
int workMem, bool randomAccess)
|
||||||
{
|
{
|
||||||
Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
|
Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
|
||||||
@ -647,7 +649,7 @@ tuplesort_begin_heap(TupleDesc tupDesc,
|
|||||||
attNums[i],
|
attNums[i],
|
||||||
InvalidStrategy,
|
InvalidStrategy,
|
||||||
InvalidOid,
|
InvalidOid,
|
||||||
collations ? collations[i] : InvalidOid,
|
sortCollations[i],
|
||||||
sortFunction,
|
sortFunction,
|
||||||
(Datum) 0);
|
(Datum) 0);
|
||||||
}
|
}
|
||||||
@ -795,8 +797,8 @@ tuplesort_begin_index_hash(Relation indexRel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Tuplesortstate *
|
Tuplesortstate *
|
||||||
tuplesort_begin_datum(Oid datumType,
|
tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation,
|
||||||
Oid sortOperator, Oid sortCollation, bool nullsFirstFlag,
|
bool nullsFirstFlag,
|
||||||
int workMem, bool randomAccess)
|
int workMem, bool randomAccess)
|
||||||
{
|
{
|
||||||
Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
|
Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess);
|
||||||
@ -837,12 +839,12 @@ tuplesort_begin_datum(Oid datumType,
|
|||||||
elog(ERROR, "operator %u is not a valid ordering operator",
|
elog(ERROR, "operator %u is not a valid ordering operator",
|
||||||
sortOperator);
|
sortOperator);
|
||||||
fmgr_info(sortFunction, &state->sortOpFn);
|
fmgr_info(sortFunction, &state->sortOpFn);
|
||||||
fmgr_info_set_collation(sortCollation, &state->sortOpFn);
|
|
||||||
|
|
||||||
/* set ordering flags */
|
/* set ordering flags and collation */
|
||||||
state->sortFnFlags = reverse ? SK_BT_DESC : 0;
|
state->sortFnFlags = reverse ? SK_BT_DESC : 0;
|
||||||
if (nullsFirstFlag)
|
if (nullsFirstFlag)
|
||||||
state->sortFnFlags |= SK_BT_NULLS_FIRST;
|
state->sortFnFlags |= SK_BT_NULLS_FIRST;
|
||||||
|
state->sortCollation = sortCollation;
|
||||||
|
|
||||||
/* lookup necessary attributes of the datum type */
|
/* lookup necessary attributes of the datum type */
|
||||||
get_typlenbyval(datumType, &typlen, &typbyval);
|
get_typlenbyval(datumType, &typlen, &typbyval);
|
||||||
@ -2630,15 +2632,15 @@ SelectSortFunction(Oid sortOperator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inline-able copy of FunctionCall2() to save some cycles in sorting.
|
* Inline-able copy of FunctionCall2Coll() to save some cycles in sorting.
|
||||||
*/
|
*/
|
||||||
static inline Datum
|
static inline Datum
|
||||||
myFunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2)
|
myFunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
|
||||||
{
|
{
|
||||||
FunctionCallInfoData fcinfo;
|
FunctionCallInfoData fcinfo;
|
||||||
Datum result;
|
Datum result;
|
||||||
|
|
||||||
InitFunctionCallInfoData(fcinfo, flinfo, 2, NULL, NULL);
|
InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
|
||||||
|
|
||||||
fcinfo.arg[0] = arg1;
|
fcinfo.arg[0] = arg1;
|
||||||
fcinfo.arg[1] = arg2;
|
fcinfo.arg[1] = arg2;
|
||||||
@ -2661,7 +2663,7 @@ myFunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2)
|
|||||||
* NULLS_FIRST options are encoded in sk_flags the same way btree does it.
|
* NULLS_FIRST options are encoded in sk_flags the same way btree does it.
|
||||||
*/
|
*/
|
||||||
static inline int32
|
static inline int32
|
||||||
inlineApplySortFunction(FmgrInfo *sortFunction, int sk_flags,
|
inlineApplySortFunction(FmgrInfo *sortFunction, int sk_flags, Oid collation,
|
||||||
Datum datum1, bool isNull1,
|
Datum datum1, bool isNull1,
|
||||||
Datum datum2, bool isNull2)
|
Datum datum2, bool isNull2)
|
||||||
{
|
{
|
||||||
@ -2685,7 +2687,7 @@ inlineApplySortFunction(FmgrInfo *sortFunction, int sk_flags,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
compare = DatumGetInt32(myFunctionCall2(sortFunction,
|
compare = DatumGetInt32(myFunctionCall2Coll(sortFunction, collation,
|
||||||
datum1, datum2));
|
datum1, datum2));
|
||||||
|
|
||||||
if (sk_flags & SK_BT_DESC)
|
if (sk_flags & SK_BT_DESC)
|
||||||
@ -2700,11 +2702,11 @@ inlineApplySortFunction(FmgrInfo *sortFunction, int sk_flags,
|
|||||||
* C99's brain-dead notions about how to implement inline functions...
|
* C99's brain-dead notions about how to implement inline functions...
|
||||||
*/
|
*/
|
||||||
int32
|
int32
|
||||||
ApplySortFunction(FmgrInfo *sortFunction, int sortFlags,
|
ApplySortFunction(FmgrInfo *sortFunction, int sortFlags, Oid collation,
|
||||||
Datum datum1, bool isNull1,
|
Datum datum1, bool isNull1,
|
||||||
Datum datum2, bool isNull2)
|
Datum datum2, bool isNull2)
|
||||||
{
|
{
|
||||||
return inlineApplySortFunction(sortFunction, sortFlags,
|
return inlineApplySortFunction(sortFunction, sortFlags, collation,
|
||||||
datum1, isNull1,
|
datum1, isNull1,
|
||||||
datum2, isNull2);
|
datum2, isNull2);
|
||||||
}
|
}
|
||||||
@ -2729,6 +2731,7 @@ comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
|
|||||||
|
|
||||||
/* Compare the leading sort key */
|
/* Compare the leading sort key */
|
||||||
compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags,
|
compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags,
|
||||||
|
scanKey->sk_collation,
|
||||||
a->datum1, a->isnull1,
|
a->datum1, a->isnull1,
|
||||||
b->datum1, b->isnull1);
|
b->datum1, b->isnull1);
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
@ -2753,6 +2756,7 @@ comparetup_heap(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
|
|||||||
datum2 = heap_getattr(&rtup, attno, tupDesc, &isnull2);
|
datum2 = heap_getattr(&rtup, attno, tupDesc, &isnull2);
|
||||||
|
|
||||||
compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags,
|
compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags,
|
||||||
|
scanKey->sk_collation,
|
||||||
datum1, isnull1,
|
datum1, isnull1,
|
||||||
datum2, isnull2);
|
datum2, isnull2);
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
@ -2874,6 +2878,7 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b,
|
|||||||
if (state->indexInfo->ii_KeyAttrNumbers[0] != 0)
|
if (state->indexInfo->ii_KeyAttrNumbers[0] != 0)
|
||||||
{
|
{
|
||||||
compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags,
|
compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags,
|
||||||
|
scanKey->sk_collation,
|
||||||
a->datum1, a->isnull1,
|
a->datum1, a->isnull1,
|
||||||
b->datum1, b->isnull1);
|
b->datum1, b->isnull1);
|
||||||
if (compare != 0 || state->nKeys == 1)
|
if (compare != 0 || state->nKeys == 1)
|
||||||
@ -2910,6 +2915,7 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b,
|
|||||||
|
|
||||||
compare = inlineApplySortFunction(&scanKey->sk_func,
|
compare = inlineApplySortFunction(&scanKey->sk_func,
|
||||||
scanKey->sk_flags,
|
scanKey->sk_flags,
|
||||||
|
scanKey->sk_collation,
|
||||||
datum1, isnull1,
|
datum1, isnull1,
|
||||||
datum2, isnull2);
|
datum2, isnull2);
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
@ -2947,6 +2953,7 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b,
|
|||||||
{
|
{
|
||||||
compare = inlineApplySortFunction(&scanKey->sk_func,
|
compare = inlineApplySortFunction(&scanKey->sk_func,
|
||||||
scanKey->sk_flags,
|
scanKey->sk_flags,
|
||||||
|
scanKey->sk_collation,
|
||||||
l_index_values[nkey],
|
l_index_values[nkey],
|
||||||
l_index_isnull[nkey],
|
l_index_isnull[nkey],
|
||||||
r_index_values[nkey],
|
r_index_values[nkey],
|
||||||
@ -3060,6 +3067,7 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b,
|
|||||||
|
|
||||||
/* Compare the leading sort key */
|
/* Compare the leading sort key */
|
||||||
compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags,
|
compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags,
|
||||||
|
scanKey->sk_collation,
|
||||||
a->datum1, a->isnull1,
|
a->datum1, a->isnull1,
|
||||||
b->datum1, b->isnull1);
|
b->datum1, b->isnull1);
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
@ -3086,6 +3094,7 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b,
|
|||||||
datum2 = index_getattr(tuple2, nkey, tupDes, &isnull2);
|
datum2 = index_getattr(tuple2, nkey, tupDes, &isnull2);
|
||||||
|
|
||||||
compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags,
|
compare = inlineApplySortFunction(&scanKey->sk_func, scanKey->sk_flags,
|
||||||
|
scanKey->sk_collation,
|
||||||
datum1, isnull1,
|
datum1, isnull1,
|
||||||
datum2, isnull2);
|
datum2, isnull2);
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
@ -3293,6 +3302,7 @@ comparetup_datum(const SortTuple *a, const SortTuple *b, Tuplesortstate *state)
|
|||||||
CHECK_FOR_INTERRUPTS();
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
|
||||||
return inlineApplySortFunction(&state->sortOpFn, state->sortFnFlags,
|
return inlineApplySortFunction(&state->sortOpFn, state->sortFnFlags,
|
||||||
|
state->sortCollation,
|
||||||
a->datum1, a->isnull1,
|
a->datum1, a->isnull1,
|
||||||
b->datum1, b->isnull1);
|
b->datum1, b->isnull1);
|
||||||
}
|
}
|
||||||
|
@ -303,6 +303,8 @@ typedef struct GinState
|
|||||||
FmgrInfo comparePartialFn[INDEX_MAX_KEYS]; /* optional method */
|
FmgrInfo comparePartialFn[INDEX_MAX_KEYS]; /* optional method */
|
||||||
/* canPartialMatch[i] is true if comparePartialFn[i] is valid */
|
/* canPartialMatch[i] is true if comparePartialFn[i] is valid */
|
||||||
bool canPartialMatch[INDEX_MAX_KEYS];
|
bool canPartialMatch[INDEX_MAX_KEYS];
|
||||||
|
/* Collations to supply to the compareFns and comparePartialFns */
|
||||||
|
Oid compareCollation[INDEX_MAX_KEYS];
|
||||||
} GinState;
|
} GinState;
|
||||||
|
|
||||||
/* XLog stuff */
|
/* XLog stuff */
|
||||||
|
@ -52,16 +52,16 @@ typedef uint16 StrategyNumber;
|
|||||||
* the operator. When using a ScanKey in a heap scan, these fields are not
|
* the operator. When using a ScanKey in a heap scan, these fields are not
|
||||||
* used and may be set to InvalidStrategy/InvalidOid.
|
* used and may be set to InvalidStrategy/InvalidOid.
|
||||||
*
|
*
|
||||||
* If the operator is collation-sensitive, sk_func.fn_collation must be set
|
* If the operator is collation-sensitive, sk_collation must be set
|
||||||
* correctly as well.
|
* correctly as well.
|
||||||
*
|
*
|
||||||
* A ScanKey can also represent a condition "column IS NULL" or "column
|
* A ScanKey can also represent a condition "column IS NULL" or "column
|
||||||
* IS NOT NULL"; these cases are signaled by the SK_SEARCHNULL and
|
* IS NOT NULL"; these cases are signaled by the SK_SEARCHNULL and
|
||||||
* SK_SEARCHNOTNULL flag bits respectively. The argument is always NULL,
|
* SK_SEARCHNOTNULL flag bits respectively. The argument is always NULL,
|
||||||
* and the sk_strategy, sk_subtype, and sk_func fields are not used (unless
|
* and the sk_strategy, sk_subtype, sk_collation, and sk_func fields are
|
||||||
* set by the index AM). Currently, SK_SEARCHNULL and SK_SEARCHNOTNULL are
|
* not used (unless set by the index AM). Currently, SK_SEARCHNULL and
|
||||||
* supported only for index scans, not heap scans; and not all index AMs
|
* SK_SEARCHNOTNULL are supported only for index scans, not heap scans;
|
||||||
* support them.
|
* and not all index AMs support them.
|
||||||
*
|
*
|
||||||
* A ScanKey can also represent an ordering operator invocation, that is
|
* A ScanKey can also represent an ordering operator invocation, that is
|
||||||
* an ordering requirement "ORDER BY indexedcol op constant". This looks
|
* an ordering requirement "ORDER BY indexedcol op constant". This looks
|
||||||
@ -70,8 +70,8 @@ typedef uint16 StrategyNumber;
|
|||||||
*
|
*
|
||||||
* Note: in some places, ScanKeys are used as a convenient representation
|
* Note: in some places, ScanKeys are used as a convenient representation
|
||||||
* for the invocation of an access method support procedure. In this case
|
* for the invocation of an access method support procedure. In this case
|
||||||
* sk_strategy/sk_subtype are not meaningful, and sk_func may refer to a
|
* sk_strategy/sk_subtype are not meaningful (but sk_collation can be); and
|
||||||
* function that returns something other than boolean.
|
* sk_func may refer to a function that returns something other than boolean.
|
||||||
*/
|
*/
|
||||||
typedef struct ScanKeyData
|
typedef struct ScanKeyData
|
||||||
{
|
{
|
||||||
@ -79,6 +79,7 @@ typedef struct ScanKeyData
|
|||||||
AttrNumber sk_attno; /* table or index column number */
|
AttrNumber sk_attno; /* table or index column number */
|
||||||
StrategyNumber sk_strategy; /* operator strategy number */
|
StrategyNumber sk_strategy; /* operator strategy number */
|
||||||
Oid sk_subtype; /* strategy subtype */
|
Oid sk_subtype; /* strategy subtype */
|
||||||
|
Oid sk_collation; /* collation to use, if needed */
|
||||||
FmgrInfo sk_func; /* lookup info for function to call */
|
FmgrInfo sk_func; /* lookup info for function to call */
|
||||||
Datum sk_argument; /* data to compare */
|
Datum sk_argument; /* data to compare */
|
||||||
} ScanKeyData;
|
} ScanKeyData;
|
||||||
@ -99,7 +100,7 @@ typedef ScanKeyData *ScanKey;
|
|||||||
* sk_attno = index column number for leading column of row comparison
|
* sk_attno = index column number for leading column of row comparison
|
||||||
* sk_strategy = btree strategy code for semantics of row comparison
|
* sk_strategy = btree strategy code for semantics of row comparison
|
||||||
* (ie, < <= > or >=)
|
* (ie, < <= > or >=)
|
||||||
* sk_subtype, sk_func: not used
|
* sk_subtype, sk_collation, sk_func: not used
|
||||||
* sk_argument: pointer to subsidiary ScanKey array
|
* sk_argument: pointer to subsidiary ScanKey array
|
||||||
* If the header is part of a ScanKey array that's sorted by attno, it
|
* If the header is part of a ScanKey array that's sorted by attno, it
|
||||||
* must be sorted according to the leading column number.
|
* must be sorted according to the leading column number.
|
||||||
|
@ -54,7 +54,8 @@ do \
|
|||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__test = FunctionCall2(&__cur_keys->sk_func, \
|
__test = FunctionCall2Coll(&__cur_keys->sk_func, \
|
||||||
|
__cur_keys->sk_collation, \
|
||||||
__atp, __cur_keys->sk_argument); \
|
__atp, __cur_keys->sk_argument); \
|
||||||
\
|
\
|
||||||
if (!DatumGetBool(__test)) \
|
if (!DatumGetBool(__test)) \
|
||||||
|
@ -41,10 +41,10 @@ typedef Datum (*PGFunction) (FunctionCallInfo fcinfo);
|
|||||||
* to be called multiple times, the lookup need be done only once and the
|
* to be called multiple times, the lookup need be done only once and the
|
||||||
* info struct saved for re-use.
|
* info struct saved for re-use.
|
||||||
*
|
*
|
||||||
* Note that fn_collation and fn_expr really are parse-time-determined
|
* Note that fn_expr really is parse-time-determined information about the
|
||||||
* information about the arguments, rather than about the function itself.
|
* arguments, rather than about the function itself. But it's convenient
|
||||||
* But it's convenient to store them here rather than in FunctionCallInfoData,
|
* to store it here rather than in FunctionCallInfoData, where it might more
|
||||||
* where they might more logically belong.
|
* logically belong.
|
||||||
*/
|
*/
|
||||||
typedef struct FmgrInfo
|
typedef struct FmgrInfo
|
||||||
{
|
{
|
||||||
@ -55,7 +55,6 @@ typedef struct FmgrInfo
|
|||||||
bool fn_strict; /* function is "strict" (NULL in => NULL out) */
|
bool fn_strict; /* function is "strict" (NULL in => NULL out) */
|
||||||
bool fn_retset; /* function returns a set */
|
bool fn_retset; /* function returns a set */
|
||||||
unsigned char fn_stats; /* collect stats if track_functions > this */
|
unsigned char fn_stats; /* collect stats if track_functions > this */
|
||||||
Oid fn_collation; /* collation that function should use */
|
|
||||||
void *fn_extra; /* extra space for use by handler */
|
void *fn_extra; /* extra space for use by handler */
|
||||||
MemoryContext fn_mcxt; /* memory context to store fn_extra in */
|
MemoryContext fn_mcxt; /* memory context to store fn_extra in */
|
||||||
fmNodePtr fn_expr; /* expression parse tree for call, or NULL */
|
fmNodePtr fn_expr; /* expression parse tree for call, or NULL */
|
||||||
@ -69,6 +68,7 @@ typedef struct FunctionCallInfoData
|
|||||||
FmgrInfo *flinfo; /* ptr to lookup info used for this call */
|
FmgrInfo *flinfo; /* ptr to lookup info used for this call */
|
||||||
fmNodePtr context; /* pass info about context of call */
|
fmNodePtr context; /* pass info about context of call */
|
||||||
fmNodePtr resultinfo; /* pass or return extra info about result */
|
fmNodePtr resultinfo; /* pass or return extra info about result */
|
||||||
|
Oid fncollation; /* collation for function to use */
|
||||||
bool isnull; /* function must set true if result is NULL */
|
bool isnull; /* function must set true if result is NULL */
|
||||||
short nargs; /* # arguments actually passed */
|
short nargs; /* # arguments actually passed */
|
||||||
Datum arg[FUNC_MAX_ARGS]; /* Arguments passed to function */
|
Datum arg[FUNC_MAX_ARGS]; /* Arguments passed to function */
|
||||||
@ -89,9 +89,7 @@ extern void fmgr_info(Oid functionId, FmgrInfo *finfo);
|
|||||||
extern void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo,
|
extern void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo,
|
||||||
MemoryContext mcxt);
|
MemoryContext mcxt);
|
||||||
|
|
||||||
/* Macros for setting the fn_collation and fn_expr fields */
|
/* Convenience macro for setting the fn_expr field */
|
||||||
#define fmgr_info_set_collation(collationId, finfo) \
|
|
||||||
((finfo)->fn_collation = (collationId))
|
|
||||||
#define fmgr_info_set_expr(expr, finfo) \
|
#define fmgr_info_set_expr(expr, finfo) \
|
||||||
((finfo)->fn_expr = (expr))
|
((finfo)->fn_expr = (expr))
|
||||||
|
|
||||||
@ -108,11 +106,12 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
|
|||||||
* explicitly set each required element to false, so we don't try to zero
|
* explicitly set each required element to false, so we don't try to zero
|
||||||
* out the argnull[] array in the macro.
|
* out the argnull[] array in the macro.
|
||||||
*/
|
*/
|
||||||
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Context, Resultinfo) \
|
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo) \
|
||||||
do { \
|
do { \
|
||||||
(Fcinfo).flinfo = (Flinfo); \
|
(Fcinfo).flinfo = (Flinfo); \
|
||||||
(Fcinfo).context = (Context); \
|
(Fcinfo).context = (Context); \
|
||||||
(Fcinfo).resultinfo = (Resultinfo); \
|
(Fcinfo).resultinfo = (Resultinfo); \
|
||||||
|
(Fcinfo).fncollation = (Collation); \
|
||||||
(Fcinfo).isnull = false; \
|
(Fcinfo).isnull = false; \
|
||||||
(Fcinfo).nargs = (Nargs); \
|
(Fcinfo).nargs = (Nargs); \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -150,8 +149,7 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
|
|||||||
/*
|
/*
|
||||||
* Get collation function should use.
|
* Get collation function should use.
|
||||||
*/
|
*/
|
||||||
#define PG_GET_COLLATION() \
|
#define PG_GET_COLLATION() (fcinfo->fncollation)
|
||||||
(fcinfo->flinfo ? fcinfo->flinfo->fn_collation : InvalidOid)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get number of arguments passed to function.
|
* Get number of arguments passed to function.
|
||||||
@ -434,56 +432,68 @@ extern int no_such_variable
|
|||||||
* directly-computed parameter list. Note that neither arguments nor result
|
* directly-computed parameter list. Note that neither arguments nor result
|
||||||
* are allowed to be NULL.
|
* are allowed to be NULL.
|
||||||
*/
|
*/
|
||||||
extern Datum DirectFunctionCall1(PGFunction func, Datum arg1);
|
extern Datum DirectFunctionCall1Coll(PGFunction func, Oid collation,
|
||||||
extern Datum DirectFunctionCall2(PGFunction func, Datum arg1, Datum arg2);
|
Datum arg1);
|
||||||
extern Datum DirectFunctionCall3(PGFunction func, Datum arg1, Datum arg2,
|
extern Datum DirectFunctionCall2Coll(PGFunction func, Oid collation,
|
||||||
|
Datum arg1, Datum arg2);
|
||||||
|
extern Datum DirectFunctionCall3Coll(PGFunction func, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3);
|
Datum arg3);
|
||||||
extern Datum DirectFunctionCall4(PGFunction func, Datum arg1, Datum arg2,
|
extern Datum DirectFunctionCall4Coll(PGFunction func, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4);
|
Datum arg3, Datum arg4);
|
||||||
extern Datum DirectFunctionCall5(PGFunction func, Datum arg1, Datum arg2,
|
extern Datum DirectFunctionCall5Coll(PGFunction func, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5);
|
Datum arg3, Datum arg4, Datum arg5);
|
||||||
extern Datum DirectFunctionCall6(PGFunction func, Datum arg1, Datum arg2,
|
extern Datum DirectFunctionCall6Coll(PGFunction func, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6);
|
Datum arg6);
|
||||||
extern Datum DirectFunctionCall7(PGFunction func, Datum arg1, Datum arg2,
|
extern Datum DirectFunctionCall7Coll(PGFunction func, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7);
|
Datum arg6, Datum arg7);
|
||||||
extern Datum DirectFunctionCall8(PGFunction func, Datum arg1, Datum arg2,
|
extern Datum DirectFunctionCall8Coll(PGFunction func, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8);
|
Datum arg6, Datum arg7, Datum arg8);
|
||||||
extern Datum DirectFunctionCall9(PGFunction func, Datum arg1, Datum arg2,
|
extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8,
|
Datum arg6, Datum arg7, Datum arg8,
|
||||||
Datum arg9);
|
Datum arg9);
|
||||||
|
|
||||||
/* The same, but passing a collation to use */
|
|
||||||
extern Datum DirectFunctionCall1WithCollation(PGFunction func, Oid collation,
|
|
||||||
Datum arg1);
|
|
||||||
extern Datum DirectFunctionCall2WithCollation(PGFunction func, Oid collation,
|
|
||||||
Datum arg1, Datum arg2);
|
|
||||||
|
|
||||||
/* These are for invocation of a previously-looked-up function with a
|
/* These are for invocation of a previously-looked-up function with a
|
||||||
* directly-computed parameter list. Note that neither arguments nor result
|
* directly-computed parameter list. Note that neither arguments nor result
|
||||||
* are allowed to be NULL.
|
* are allowed to be NULL.
|
||||||
*/
|
*/
|
||||||
extern Datum FunctionCall1(FmgrInfo *flinfo, Datum arg1);
|
extern Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation,
|
||||||
extern Datum FunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2);
|
Datum arg1);
|
||||||
extern Datum FunctionCall3(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
extern Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation,
|
||||||
|
Datum arg1, Datum arg2);
|
||||||
|
extern Datum FunctionCall3Coll(FmgrInfo *flinfo, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3);
|
Datum arg3);
|
||||||
extern Datum FunctionCall4(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
extern Datum FunctionCall4Coll(FmgrInfo *flinfo, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4);
|
Datum arg3, Datum arg4);
|
||||||
extern Datum FunctionCall5(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
extern Datum FunctionCall5Coll(FmgrInfo *flinfo, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5);
|
Datum arg3, Datum arg4, Datum arg5);
|
||||||
extern Datum FunctionCall6(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
extern Datum FunctionCall6Coll(FmgrInfo *flinfo, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6);
|
Datum arg6);
|
||||||
extern Datum FunctionCall7(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
extern Datum FunctionCall7Coll(FmgrInfo *flinfo, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7);
|
Datum arg6, Datum arg7);
|
||||||
extern Datum FunctionCall8(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
extern Datum FunctionCall8Coll(FmgrInfo *flinfo, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8);
|
Datum arg6, Datum arg7, Datum arg8);
|
||||||
extern Datum FunctionCall9(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
extern Datum FunctionCall9Coll(FmgrInfo *flinfo, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8,
|
Datum arg6, Datum arg7, Datum arg8,
|
||||||
Datum arg9);
|
Datum arg9);
|
||||||
@ -494,29 +504,100 @@ extern Datum FunctionCall9(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
|||||||
* by FunctionCallN(). If the same function is to be invoked repeatedly,
|
* by FunctionCallN(). If the same function is to be invoked repeatedly,
|
||||||
* do the FunctionLookup() once and then use FunctionCallN().
|
* do the FunctionLookup() once and then use FunctionCallN().
|
||||||
*/
|
*/
|
||||||
extern Datum OidFunctionCall0(Oid functionId);
|
extern Datum OidFunctionCall0Coll(Oid functionId, Oid collation);
|
||||||
extern Datum OidFunctionCall1(Oid functionId, Datum arg1);
|
extern Datum OidFunctionCall1Coll(Oid functionId, Oid collation,
|
||||||
extern Datum OidFunctionCall2(Oid functionId, Datum arg1, Datum arg2);
|
Datum arg1);
|
||||||
extern Datum OidFunctionCall3(Oid functionId, Datum arg1, Datum arg2,
|
extern Datum OidFunctionCall2Coll(Oid functionId, Oid collation,
|
||||||
|
Datum arg1, Datum arg2);
|
||||||
|
extern Datum OidFunctionCall3Coll(Oid functionId, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3);
|
Datum arg3);
|
||||||
extern Datum OidFunctionCall4(Oid functionId, Datum arg1, Datum arg2,
|
extern Datum OidFunctionCall4Coll(Oid functionId, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4);
|
Datum arg3, Datum arg4);
|
||||||
extern Datum OidFunctionCall5(Oid functionId, Datum arg1, Datum arg2,
|
extern Datum OidFunctionCall5Coll(Oid functionId, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5);
|
Datum arg3, Datum arg4, Datum arg5);
|
||||||
extern Datum OidFunctionCall6(Oid functionId, Datum arg1, Datum arg2,
|
extern Datum OidFunctionCall6Coll(Oid functionId, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6);
|
Datum arg6);
|
||||||
extern Datum OidFunctionCall7(Oid functionId, Datum arg1, Datum arg2,
|
extern Datum OidFunctionCall7Coll(Oid functionId, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7);
|
Datum arg6, Datum arg7);
|
||||||
extern Datum OidFunctionCall8(Oid functionId, Datum arg1, Datum arg2,
|
extern Datum OidFunctionCall8Coll(Oid functionId, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8);
|
Datum arg6, Datum arg7, Datum arg8);
|
||||||
extern Datum OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
|
extern Datum OidFunctionCall9Coll(Oid functionId, Oid collation,
|
||||||
|
Datum arg1, Datum arg2,
|
||||||
Datum arg3, Datum arg4, Datum arg5,
|
Datum arg3, Datum arg4, Datum arg5,
|
||||||
Datum arg6, Datum arg7, Datum arg8,
|
Datum arg6, Datum arg7, Datum arg8,
|
||||||
Datum arg9);
|
Datum arg9);
|
||||||
|
|
||||||
|
/* These macros allow the collation argument to be omitted (with a default of
|
||||||
|
* InvalidOid, ie, no collation). They exist mostly for backwards
|
||||||
|
* compatibility of source code.
|
||||||
|
*/
|
||||||
|
#define DirectFunctionCall1(func, arg1) \
|
||||||
|
DirectFunctionCall1Coll(func, InvalidOid, arg1)
|
||||||
|
#define DirectFunctionCall2(func, arg1, arg2) \
|
||||||
|
DirectFunctionCall2Coll(func, InvalidOid, arg1, arg2)
|
||||||
|
#define DirectFunctionCall3(func, arg1, arg2, arg3) \
|
||||||
|
DirectFunctionCall3Coll(func, InvalidOid, arg1, arg2, arg3)
|
||||||
|
#define DirectFunctionCall4(func, arg1, arg2, arg3, arg4) \
|
||||||
|
DirectFunctionCall4Coll(func, InvalidOid, arg1, arg2, arg3, arg4)
|
||||||
|
#define DirectFunctionCall5(func, arg1, arg2, arg3, arg4, arg5) \
|
||||||
|
DirectFunctionCall5Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5)
|
||||||
|
#define DirectFunctionCall6(func, arg1, arg2, arg3, arg4, arg5, arg6) \
|
||||||
|
DirectFunctionCall6Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||||
|
#define DirectFunctionCall7(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
|
||||||
|
DirectFunctionCall7Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||||
|
#define DirectFunctionCall8(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
|
||||||
|
DirectFunctionCall8Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||||
|
#define DirectFunctionCall9(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
|
||||||
|
DirectFunctionCall9Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||||
|
#define FunctionCall1(flinfo, arg1) \
|
||||||
|
FunctionCall1Coll(flinfo, InvalidOid, arg1)
|
||||||
|
#define FunctionCall2(flinfo, arg1, arg2) \
|
||||||
|
FunctionCall2Coll(flinfo, InvalidOid, arg1, arg2)
|
||||||
|
#define FunctionCall3(flinfo, arg1, arg2, arg3) \
|
||||||
|
FunctionCall3Coll(flinfo, InvalidOid, arg1, arg2, arg3)
|
||||||
|
#define FunctionCall4(flinfo, arg1, arg2, arg3, arg4) \
|
||||||
|
FunctionCall4Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4)
|
||||||
|
#define FunctionCall5(flinfo, arg1, arg2, arg3, arg4, arg5) \
|
||||||
|
FunctionCall5Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5)
|
||||||
|
#define FunctionCall6(flinfo, arg1, arg2, arg3, arg4, arg5, arg6) \
|
||||||
|
FunctionCall6Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||||
|
#define FunctionCall7(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
|
||||||
|
FunctionCall7Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||||
|
#define FunctionCall8(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
|
||||||
|
FunctionCall8Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||||
|
#define FunctionCall9(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
|
||||||
|
FunctionCall9Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||||
|
#define OidFunctionCall0(functionId) \
|
||||||
|
OidFunctionCall0Coll(functionId, InvalidOid)
|
||||||
|
#define OidFunctionCall1(functionId, arg1) \
|
||||||
|
OidFunctionCall1Coll(functionId, InvalidOid, arg1)
|
||||||
|
#define OidFunctionCall2(functionId, arg1, arg2) \
|
||||||
|
OidFunctionCall2Coll(functionId, InvalidOid, arg1, arg2)
|
||||||
|
#define OidFunctionCall3(functionId, arg1, arg2, arg3) \
|
||||||
|
OidFunctionCall3Coll(functionId, InvalidOid, arg1, arg2, arg3)
|
||||||
|
#define OidFunctionCall4(functionId, arg1, arg2, arg3, arg4) \
|
||||||
|
OidFunctionCall4Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4)
|
||||||
|
#define OidFunctionCall5(functionId, arg1, arg2, arg3, arg4, arg5) \
|
||||||
|
OidFunctionCall5Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5)
|
||||||
|
#define OidFunctionCall6(functionId, arg1, arg2, arg3, arg4, arg5, arg6) \
|
||||||
|
OidFunctionCall6Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||||
|
#define OidFunctionCall7(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
|
||||||
|
OidFunctionCall7Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||||
|
#define OidFunctionCall8(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
|
||||||
|
OidFunctionCall8Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||||
|
#define OidFunctionCall9(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
|
||||||
|
OidFunctionCall9Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||||
|
|
||||||
|
|
||||||
/* Special cases for convenient invocation of datatype I/O functions. */
|
/* Special cases for convenient invocation of datatype I/O functions. */
|
||||||
extern Datum InputFunctionCall(FmgrInfo *flinfo, char *str,
|
extern Datum InputFunctionCall(FmgrInfo *flinfo, char *str,
|
||||||
Oid typioparam, int32 typmod);
|
Oid typioparam, int32 typmod);
|
||||||
|
@ -864,6 +864,7 @@ typedef struct RowCompareExprState
|
|||||||
List *largs; /* the left-hand input arguments */
|
List *largs; /* the left-hand input arguments */
|
||||||
List *rargs; /* the right-hand input arguments */
|
List *rargs; /* the right-hand input arguments */
|
||||||
FmgrInfo *funcs; /* array of comparison function info */
|
FmgrInfo *funcs; /* array of comparison function info */
|
||||||
|
Oid *collations; /* array of collations to use */
|
||||||
} RowCompareExprState;
|
} RowCompareExprState;
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
|
@ -135,7 +135,8 @@ extern Pattern_Prefix_Status pattern_fixed_prefix(Const *patt,
|
|||||||
Oid collation,
|
Oid collation,
|
||||||
Const **prefix,
|
Const **prefix,
|
||||||
Const **rest);
|
Const **rest);
|
||||||
extern Const *make_greater_string(const Const *str_const, FmgrInfo *ltproc);
|
extern Const *make_greater_string(const Const *str_const, FmgrInfo *ltproc,
|
||||||
|
Oid collation);
|
||||||
|
|
||||||
extern Datum eqsel(PG_FUNCTION_ARGS);
|
extern Datum eqsel(PG_FUNCTION_ARGS);
|
||||||
extern Datum neqsel(PG_FUNCTION_ARGS);
|
extern Datum neqsel(PG_FUNCTION_ARGS);
|
||||||
|
@ -60,7 +60,8 @@ typedef struct Tuplesortstate Tuplesortstate;
|
|||||||
|
|
||||||
extern Tuplesortstate *tuplesort_begin_heap(TupleDesc tupDesc,
|
extern Tuplesortstate *tuplesort_begin_heap(TupleDesc tupDesc,
|
||||||
int nkeys, AttrNumber *attNums,
|
int nkeys, AttrNumber *attNums,
|
||||||
Oid *sortOperators, Oid *collations, bool *nullsFirstFlags,
|
Oid *sortOperators, Oid *sortCollations,
|
||||||
|
bool *nullsFirstFlags,
|
||||||
int workMem, bool randomAccess);
|
int workMem, bool randomAccess);
|
||||||
extern Tuplesortstate *tuplesort_begin_cluster(TupleDesc tupDesc,
|
extern Tuplesortstate *tuplesort_begin_cluster(TupleDesc tupDesc,
|
||||||
Relation indexRel,
|
Relation indexRel,
|
||||||
@ -72,7 +73,8 @@ extern Tuplesortstate *tuplesort_begin_index_hash(Relation indexRel,
|
|||||||
uint32 hash_mask,
|
uint32 hash_mask,
|
||||||
int workMem, bool randomAccess);
|
int workMem, bool randomAccess);
|
||||||
extern Tuplesortstate *tuplesort_begin_datum(Oid datumType,
|
extern Tuplesortstate *tuplesort_begin_datum(Oid datumType,
|
||||||
Oid sortOperator, Oid sortCollation, bool nullsFirstFlag,
|
Oid sortOperator, Oid sortCollation,
|
||||||
|
bool nullsFirstFlag,
|
||||||
int workMem, bool randomAccess);
|
int workMem, bool randomAccess);
|
||||||
|
|
||||||
extern void tuplesort_set_bound(Tuplesortstate *state, int64 bound);
|
extern void tuplesort_set_bound(Tuplesortstate *state, int64 bound);
|
||||||
@ -125,6 +127,7 @@ extern void SelectSortFunction(Oid sortOperator, bool nulls_first,
|
|||||||
* reverse-sort and NULLs-ordering properly.
|
* reverse-sort and NULLs-ordering properly.
|
||||||
*/
|
*/
|
||||||
extern int32 ApplySortFunction(FmgrInfo *sortFunction, int sortFlags,
|
extern int32 ApplySortFunction(FmgrInfo *sortFunction, int sortFlags,
|
||||||
|
Oid collation,
|
||||||
Datum datum1, bool isNull1,
|
Datum datum1, bool isNull1,
|
||||||
Datum datum2, bool isNull2);
|
Datum datum2, bool isNull2);
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ do_compile(FunctionCallInfo fcinfo,
|
|||||||
function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
|
function->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
|
||||||
function->fn_tid = procTup->t_self;
|
function->fn_tid = procTup->t_self;
|
||||||
function->fn_is_trigger = is_trigger;
|
function->fn_is_trigger = is_trigger;
|
||||||
function->fn_input_collation = fcinfo->flinfo->fn_collation;
|
function->fn_input_collation = fcinfo->fncollation;
|
||||||
function->fn_cxt = func_cxt;
|
function->fn_cxt = func_cxt;
|
||||||
function->out_param_varno = -1; /* set up for no OUT param */
|
function->out_param_varno = -1; /* set up for no OUT param */
|
||||||
function->resolve_option = plpgsql_variable_conflict;
|
function->resolve_option = plpgsql_variable_conflict;
|
||||||
@ -2331,7 +2331,7 @@ compute_function_hashkey(FunctionCallInfo fcinfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get input collation, if known */
|
/* get input collation, if known */
|
||||||
hashkey->inputCollation = fcinfo->flinfo->fn_collation;
|
hashkey->inputCollation = fcinfo->fncollation;
|
||||||
|
|
||||||
if (procStruct->pronargs > 0)
|
if (procStruct->pronargs > 0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user