aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-04-12 19:19:24 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-04-12 19:19:24 -0400
commitd64713df7e5996ab3ab337b5e0901cf2c53773f9 (patch)
tree7105a61bf9fef5cef674cea7f1305dfeb77aa39a /src/backend/utils/adt
parent88543ecfec9c754b5f14b898bccbc68d941748b3 (diff)
downloadpostgresql-d64713df7e5996ab3ab337b5e0901cf2c53773f9.tar.gz
postgresql-d64713df7e5996ab3ab337b5e0901cf2c53773f9.zip
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...
Diffstat (limited to 'src/backend/utils/adt')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c26
-rw-r--r--src/backend/utils/adt/int.c3
-rw-r--r--src/backend/utils/adt/like.c6
-rw-r--r--src/backend/utils/adt/oid.c3
-rw-r--r--src/backend/utils/adt/ri_triggers.c5
-rw-r--r--src/backend/utils/adt/rowtypes.c22
-rw-r--r--src/backend/utils/adt/selfuncs.c114
7 files changed, 105 insertions, 74 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 0869de66cef..a234f35eb8f 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -3127,6 +3127,7 @@ array_eq(PG_FUNCTION_ARGS)
{
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
+ Oid collation = PG_GET_COLLATION();
int ndims1 = ARR_NDIM(array1);
int ndims2 = ARR_NDIM(array2);
int *dims1 = ARR_DIMS(array1);
@@ -3184,7 +3185,7 @@ array_eq(PG_FUNCTION_ARGS)
* apply the operator to each pair of array elements.
*/
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
- NULL, NULL);
+ collation, NULL, NULL);
/* Loop over source data */
nitems = ArrayGetNItems(ndims1, dims1);
@@ -3367,8 +3368,7 @@ array_cmp(FunctionCallInfo fcinfo)
*/
typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
if (typentry == NULL ||
- typentry->type_id != element_type ||
- typentry->cmp_proc_finfo.fn_collation != collation)
+ typentry->type_id != element_type)
{
typentry = lookup_type_cache(element_type,
TYPECACHE_CMP_PROC_FINFO);
@@ -3378,7 +3378,6 @@ array_cmp(FunctionCallInfo fcinfo)
errmsg("could not identify a comparison function for type %s",
format_type_be(element_type))));
fcinfo->flinfo->fn_extra = (void *) typentry;
- typentry->cmp_proc_finfo.fn_collation = collation;
}
typlen = typentry->typlen;
typbyval = typentry->typbyval;
@@ -3388,7 +3387,7 @@ array_cmp(FunctionCallInfo fcinfo)
* apply the operator to each pair of array elements.
*/
InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
- NULL, NULL);
+ collation, NULL, NULL);
/* Loop over source data */
min_nitems = Min(nitems1, nitems2);
@@ -3573,7 +3572,7 @@ hash_array(PG_FUNCTION_ARGS)
* apply the hash function to each array element.
*/
InitFunctionCallInfoData(locfcinfo, &typentry->hash_proc_finfo, 1,
- NULL, NULL);
+ InvalidOid, NULL, NULL);
/* Loop over source data */
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.
*/
static bool
-array_contain_compare(ArrayType *array1, ArrayType *array2, bool matchall,
- void **fn_extra)
+array_contain_compare(ArrayType *array1, ArrayType *array2, Oid collation,
+ bool matchall, void **fn_extra)
{
bool result = matchall;
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.
*/
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
- NULL, NULL);
+ collation, NULL, NULL);
/* Loop over source data */
nelems1 = ArrayGetNItems(ARR_NDIM(array1), ARR_DIMS(array1));
@@ -3811,9 +3810,10 @@ arrayoverlap(PG_FUNCTION_ARGS)
{
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
+ Oid collation = PG_GET_COLLATION();
bool result;
- result = array_contain_compare(array1, array2, false,
+ result = array_contain_compare(array1, array2, collation, false,
&fcinfo->flinfo->fn_extra);
/* Avoid leaking memory when handed toasted input. */
@@ -3828,9 +3828,10 @@ arraycontains(PG_FUNCTION_ARGS)
{
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
+ Oid collation = PG_GET_COLLATION();
bool result;
- result = array_contain_compare(array2, array1, true,
+ result = array_contain_compare(array2, array1, collation, true,
&fcinfo->flinfo->fn_extra);
/* Avoid leaking memory when handed toasted input. */
@@ -3845,9 +3846,10 @@ arraycontained(PG_FUNCTION_ARGS)
{
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
+ Oid collation = PG_GET_COLLATION();
bool result;
- result = array_contain_compare(array1, array2, true,
+ result = array_contain_compare(array1, array2, collation, true,
&fcinfo->flinfo->fn_extra);
/* Avoid leaking memory when handed toasted input. */
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index dcb31586b2b..019fcaaa36f 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -213,7 +213,8 @@ int2vectorrecv(PG_FUNCTION_ARGS)
* fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
* parameter.
*/
- InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3, NULL, NULL);
+ InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
+ InvalidOid, NULL, NULL);
locfcinfo.arg[0] = PointerGetDatum(buf);
locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID);
diff --git a/src/backend/utils/adt/like.c b/src/backend/utils/adt/like.c
index 0934c69ebe5..09e8698af2c 100644
--- a/src/backend/utils/adt/like.c
+++ b/src/backend/utils/adt/like.c
@@ -174,10 +174,12 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation)
if (pg_database_encoding_max_length() > 1)
{
/* 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);
plen = (VARSIZE(pat) - VARHDRSZ);
- str = DatumGetTextP(DirectFunctionCall1WithCollation(lower, collation, PointerGetDatum(str)));
+ str = DatumGetTextP(DirectFunctionCall1Coll(lower, collation,
+ PointerGetDatum(str)));
s = VARDATA(str);
slen = (VARSIZE(str) - VARHDRSZ);
if (GetDatabaseEncoding() == PG_UTF8)
diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c
index b2152a2491c..495b6261e62 100644
--- a/src/backend/utils/adt/oid.c
+++ b/src/backend/utils/adt/oid.c
@@ -263,7 +263,8 @@ oidvectorrecv(PG_FUNCTION_ARGS)
* fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
* parameter.
*/
- InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3, NULL, NULL);
+ InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
+ InvalidOid, NULL, NULL);
locfcinfo.arg[0] = PointerGetDatum(buf);
locfcinfo.arg[1] = ObjectIdGetDatum(OIDOID);
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 4e5dd4b772d..fde01a0f571 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -3963,7 +3963,10 @@ ri_AttributesEqual(Oid eq_opr, Oid typeid,
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,
oldvalue, newvalue));
}
diff --git a/src/backend/utils/adt/rowtypes.c b/src/backend/utils/adt/rowtypes.c
index 2c552e173bb..919ed9582a7 100644
--- a/src/backend/utils/adt/rowtypes.c
+++ b/src/backend/utils/adt/rowtypes.c
@@ -867,6 +867,7 @@ record_cmp(FunctionCallInfo fcinfo)
while (i1 < ncolumns1 || i2 < ncolumns2)
{
TypeCacheEntry *typentry;
+ Oid collation;
FunctionCallInfoData locfcinfo;
int32 cmpresult;
@@ -899,6 +900,14 @@ record_cmp(FunctionCallInfo fcinfo)
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
*/
typentry = my_extra->columns[j].typentry;
@@ -935,7 +944,7 @@ record_cmp(FunctionCallInfo fcinfo)
/* Compare the pair of elements */
InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
- NULL, NULL);
+ collation, NULL, NULL);
locfcinfo.arg[0] = values1[i1];
locfcinfo.arg[1] = values2[i2];
locfcinfo.argnull[0] = false;
@@ -1093,6 +1102,7 @@ record_eq(PG_FUNCTION_ARGS)
while (i1 < ncolumns1 || i2 < ncolumns2)
{
TypeCacheEntry *typentry;
+ Oid collation;
FunctionCallInfoData locfcinfo;
bool oprresult;
@@ -1125,6 +1135,14 @@ record_eq(PG_FUNCTION_ARGS)
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
*/
typentry = my_extra->columns[j].typentry;
@@ -1154,7 +1172,7 @@ record_eq(PG_FUNCTION_ARGS)
/* Compare the pair of elements */
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
- NULL, NULL);
+ collation, NULL, NULL);
locfcinfo.arg[0] = values1[i1];
locfcinfo.arg[1] = values2[i2];
locfcinfo.argnull[0] = false;
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index b046bc05e62..4d800f8a007 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -285,19 +285,20 @@ var_eq_const(VariableStatData *vardata, Oid operator,
FmgrInfo eqproc;
fmgr_info(get_opcode(operator), &eqproc);
- fmgr_info_set_collation(DEFAULT_COLLATION_OID, &eqproc);
for (i = 0; i < nvalues; i++)
{
/* be careful to apply operator right way 'round */
if (varonleft)
- match = DatumGetBool(FunctionCall2(&eqproc,
- values[i],
- constval));
+ match = DatumGetBool(FunctionCall2Coll(&eqproc,
+ DEFAULT_COLLATION_OID,
+ values[i],
+ constval));
else
- match = DatumGetBool(FunctionCall2(&eqproc,
- constval,
- values[i]));
+ match = DatumGetBool(FunctionCall2Coll(&eqproc,
+ DEFAULT_COLLATION_OID,
+ constval,
+ values[i]));
if (match)
break;
}
@@ -515,7 +516,6 @@ scalarineqsel(PlannerInfo *root, Oid operator, bool isgt,
stats = (Form_pg_statistic) GETSTRUCT(vardata->statsTuple);
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
@@ -598,12 +598,14 @@ mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc,
for (i = 0; i < nvalues; i++)
{
if (varonleft ?
- DatumGetBool(FunctionCall2(opproc,
- values[i],
- constval)) :
- DatumGetBool(FunctionCall2(opproc,
- constval,
- values[i])))
+ DatumGetBool(FunctionCall2Coll(opproc,
+ DEFAULT_COLLATION_OID,
+ values[i],
+ constval)) :
+ DatumGetBool(FunctionCall2Coll(opproc,
+ DEFAULT_COLLATION_OID,
+ constval,
+ values[i])))
mcv_selec += numbers[i];
sumcommon += numbers[i];
}
@@ -678,12 +680,14 @@ histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc,
for (i = n_skip; i < nvalues - n_skip; i++)
{
if (varonleft ?
- DatumGetBool(FunctionCall2(opproc,
- values[i],
- constval)) :
- DatumGetBool(FunctionCall2(opproc,
- constval,
- values[i])))
+ DatumGetBool(FunctionCall2Coll(opproc,
+ DEFAULT_COLLATION_OID,
+ values[i],
+ constval)) :
+ DatumGetBool(FunctionCall2Coll(opproc,
+ DEFAULT_COLLATION_OID,
+ constval,
+ values[i])))
nmatch++;
}
result = ((double) nmatch) / ((double) (nvalues - 2 * n_skip));
@@ -802,9 +806,10 @@ ineq_histogram_selectivity(PlannerInfo *root,
NULL,
&values[probe]);
- ltcmp = DatumGetBool(FunctionCall2(opproc,
- values[probe],
- constval));
+ ltcmp = DatumGetBool(FunctionCall2Coll(opproc,
+ DEFAULT_COLLATION_OID,
+ values[probe],
+ constval));
if (isgt)
ltcmp = !ltcmp;
if (ltcmp)
@@ -1255,7 +1260,6 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate)
/* Try to use the histogram entries to get selectivity */
fmgr_info(get_opcode(operator), &opproc);
- fmgr_info_set_collation(DEFAULT_COLLATION_OID, &opproc);
selec = histogram_selectivity(&vardata, &opproc, constval, true,
10, 1, &hist_size);
@@ -1705,7 +1709,6 @@ scalararraysel(PlannerInfo *root,
if (!oprsel)
return (Selectivity) 0.5;
fmgr_info(oprsel, &oprselproc);
- fmgr_info_set_collation(DEFAULT_COLLATION_OID, &oprselproc);
/* deconstruct the expression */
Assert(list_length(clause->args) == 2);
@@ -2126,7 +2129,6 @@ eqjoinsel_inner(Oid operator,
nmatches;
fmgr_info(get_opcode(operator), &eqproc);
- fmgr_info_set_collation(DEFAULT_COLLATION_OID, &eqproc);
hasmatch1 = (bool *) palloc0(nvalues1 * sizeof(bool));
hasmatch2 = (bool *) palloc0(nvalues2 * sizeof(bool));
@@ -2146,9 +2148,10 @@ eqjoinsel_inner(Oid operator,
{
if (hasmatch2[j])
continue;
- if (DatumGetBool(FunctionCall2(&eqproc,
- values1[i],
- values2[j])))
+ if (DatumGetBool(FunctionCall2Coll(&eqproc,
+ DEFAULT_COLLATION_OID,
+ values1[i],
+ values2[j])))
{
hasmatch1[i] = hasmatch2[j] = true;
matchprodfreq += numbers1[i] * numbers2[j];
@@ -2349,7 +2352,6 @@ eqjoinsel_semi(Oid operator,
nmatches;
fmgr_info(get_opcode(operator), &eqproc);
- fmgr_info_set_collation(DEFAULT_COLLATION_OID, &eqproc);
hasmatch1 = (bool *) palloc0(nvalues1 * sizeof(bool));
hasmatch2 = (bool *) palloc0(nvalues2 * sizeof(bool));
@@ -2368,9 +2370,10 @@ eqjoinsel_semi(Oid operator,
{
if (hasmatch2[j])
continue;
- if (DatumGetBool(FunctionCall2(&eqproc,
- values1[i],
- values2[j])))
+ if (DatumGetBool(FunctionCall2Coll(&eqproc,
+ DEFAULT_COLLATION_OID,
+ values1[i],
+ values2[j])))
{
hasmatch1[i] = hasmatch2[j] = true;
nmatches++;
@@ -4503,7 +4506,6 @@ get_variable_range(PlannerInfo *root, VariableStatData *vardata, Oid sortop,
FmgrInfo opproc;
fmgr_info(get_opcode(sortop), &opproc);
- fmgr_info_set_collation(DEFAULT_COLLATION_OID, &opproc);
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;
continue;
}
- if (DatumGetBool(FunctionCall2(&opproc, values[i], tmin)))
+ if (DatumGetBool(FunctionCall2Coll(&opproc,
+ DEFAULT_COLLATION_OID,
+ values[i], tmin)))
{
tmin = values[i];
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_is_mcv = true;
@@ -5183,7 +5189,6 @@ prefix_selectivity(PlannerInfo *root, VariableStatData *vardata,
if (cmpopr == InvalidOid)
elog(ERROR, "no >= operator for opfamily %u", opfamily);
fmgr_info(get_opcode(cmpopr), &opproc);
- fmgr_info_set_collation(DEFAULT_COLLATION_OID, &opproc);
prefixsel = ineq_histogram_selectivity(root, vardata, &opproc, true,
prefixcon->constvalue,
@@ -5205,9 +5210,8 @@ prefix_selectivity(PlannerInfo *root, VariableStatData *vardata,
if (cmpopr == InvalidOid)
elog(ERROR, "no < operator for opfamily %u", opfamily);
fmgr_info(get_opcode(cmpopr), &opproc);
- fmgr_info_set_collation(DEFAULT_COLLATION_OID, &opproc);
-
- greaterstrcon = make_greater_string(prefixcon, &opproc);
+ greaterstrcon = make_greater_string(prefixcon, &opproc,
+ DEFAULT_COLLATION_OID);
if (greaterstrcon)
{
Selectivity topsel;
@@ -5502,22 +5506,21 @@ pattern_selectivity(Const *patt, Pattern_Type ptype)
* in the form of a Const node; else return NULL.
*
* The caller must provide the appropriate "less than" comparison function
- * for testing the strings. In particular, ltproc->fn_collation specifies
- * the locale for comparisons.
+ * for testing the strings, along with the collation to use.
*
* 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
* 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
* 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
* 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
* 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.
*
* 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.
*/
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;
char *workstr;
@@ -5565,7 +5568,7 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc)
{
workstr = TextDatumGetCString(str_const->constvalue);
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;
else
{
@@ -5573,19 +5576,19 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc)
static char suffixchar = 0;
static Oid suffixcollation = 0;
- if (!suffixchar || suffixcollation != ltproc->fn_collation)
+ if (!suffixchar || suffixcollation != collation)
{
char *best;
best = "Z";
- if (varstr_cmp(best, 1, "z", 1, ltproc->fn_collation) < 0)
+ if (varstr_cmp(best, 1, "z", 1, collation) < 0)
best = "z";
- if (varstr_cmp(best, 1, "y", 1, ltproc->fn_collation) < 0)
+ if (varstr_cmp(best, 1, "y", 1, collation) < 0)
best = "y";
- if (varstr_cmp(best, 1, "9", 1, ltproc->fn_collation) < 0)
+ if (varstr_cmp(best, 1, "9", 1, collation) < 0)
best = "9";
suffixchar = *best;
- suffixcollation = ltproc->fn_collation;
+ suffixcollation = collation;
}
/* And build the string to compare to */
@@ -5621,9 +5624,10 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc)
else
workstr_const = string_to_bytea_const(workstr, len);
- if (DatumGetBool(FunctionCall2(ltproc,
- cmpstr,
- workstr_const->constvalue)))
+ if (DatumGetBool(FunctionCall2Coll(ltproc,
+ collation,
+ cmpstr,
+ workstr_const->constvalue)))
{
/* Successfully made a string larger than cmpstr */
if (cmptxt)