mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
patternsel() was improperly stripping RelabelType from the derived
expressions it constructed, causing scalarineqsel to become confused if the underlying variable was of a domain type. Per report from Kevin Grittner.
This commit is contained in:
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.178 2005/04/25 01:30:14 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.179 2005/06/01 17:05:11 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -163,7 +163,7 @@ static void examine_variable(Query *root, Node *node, int varRelid,
|
|||||||
static double get_variable_numdistinct(VariableStatData *vardata);
|
static double get_variable_numdistinct(VariableStatData *vardata);
|
||||||
static bool get_variable_maximum(Query *root, VariableStatData *vardata,
|
static bool get_variable_maximum(Query *root, VariableStatData *vardata,
|
||||||
Oid sortop, Datum *max);
|
Oid sortop, Datum *max);
|
||||||
static Selectivity prefix_selectivity(Query *root, VariableStatData *vardata,
|
static Selectivity prefix_selectivity(Query *root, Node *variable,
|
||||||
Oid opclass, Const *prefix);
|
Oid opclass, Const *prefix);
|
||||||
static Selectivity pattern_selectivity(Const *patt, Pattern_Type ptype);
|
static Selectivity pattern_selectivity(Const *patt, Pattern_Type ptype);
|
||||||
static Datum string_to_datum(const char *str, Oid datatype);
|
static Datum string_to_datum(const char *str, Oid datatype);
|
||||||
@ -812,6 +812,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
|
|||||||
List *args = (List *) PG_GETARG_POINTER(2);
|
List *args = (List *) PG_GETARG_POINTER(2);
|
||||||
int varRelid = PG_GETARG_INT32(3);
|
int varRelid = PG_GETARG_INT32(3);
|
||||||
VariableStatData vardata;
|
VariableStatData vardata;
|
||||||
|
Node *variable;
|
||||||
Node *other;
|
Node *other;
|
||||||
bool varonleft;
|
bool varonleft;
|
||||||
Datum constval;
|
Datum constval;
|
||||||
@ -836,6 +837,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
|
|||||||
ReleaseVariableStats(vardata);
|
ReleaseVariableStats(vardata);
|
||||||
return DEFAULT_MATCH_SEL;
|
return DEFAULT_MATCH_SEL;
|
||||||
}
|
}
|
||||||
|
variable = (Node *) linitial(args);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the constant is NULL, assume operator is strict and return zero,
|
* If the constant is NULL, assume operator is strict and return zero,
|
||||||
@ -939,7 +941,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
|
|||||||
|
|
||||||
if (eqopr == InvalidOid)
|
if (eqopr == InvalidOid)
|
||||||
elog(ERROR, "no = operator for opclass %u", opclass);
|
elog(ERROR, "no = operator for opclass %u", opclass);
|
||||||
eqargs = list_make2(vardata.var, prefix);
|
eqargs = list_make2(variable, prefix);
|
||||||
result = DatumGetFloat8(DirectFunctionCall4(eqsel,
|
result = DatumGetFloat8(DirectFunctionCall4(eqsel,
|
||||||
PointerGetDatum(root),
|
PointerGetDatum(root),
|
||||||
ObjectIdGetDatum(eqopr),
|
ObjectIdGetDatum(eqopr),
|
||||||
@ -958,7 +960,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
|
|||||||
Selectivity selec;
|
Selectivity selec;
|
||||||
|
|
||||||
if (pstatus == Pattern_Prefix_Partial)
|
if (pstatus == Pattern_Prefix_Partial)
|
||||||
prefixsel = prefix_selectivity(root, &vardata, opclass, prefix);
|
prefixsel = prefix_selectivity(root, variable, opclass, prefix);
|
||||||
else
|
else
|
||||||
prefixsel = 1.0;
|
prefixsel = 1.0;
|
||||||
restsel = pattern_selectivity(rest, ptype);
|
restsel = pattern_selectivity(rest, ptype);
|
||||||
@ -3694,7 +3696,7 @@ pattern_fixed_prefix(Const *patt, Pattern_Type ptype,
|
|||||||
* more useful to use the upper-bound code than not.
|
* more useful to use the upper-bound code than not.
|
||||||
*/
|
*/
|
||||||
static Selectivity
|
static Selectivity
|
||||||
prefix_selectivity(Query *root, VariableStatData *vardata,
|
prefix_selectivity(Query *root, Node *variable,
|
||||||
Oid opclass, Const *prefixcon)
|
Oid opclass, Const *prefixcon)
|
||||||
{
|
{
|
||||||
Selectivity prefixsel;
|
Selectivity prefixsel;
|
||||||
@ -3706,7 +3708,7 @@ prefix_selectivity(Query *root, VariableStatData *vardata,
|
|||||||
BTGreaterEqualStrategyNumber);
|
BTGreaterEqualStrategyNumber);
|
||||||
if (cmpopr == InvalidOid)
|
if (cmpopr == InvalidOid)
|
||||||
elog(ERROR, "no >= operator for opclass %u", opclass);
|
elog(ERROR, "no >= operator for opclass %u", opclass);
|
||||||
cmpargs = list_make2(vardata->var, prefixcon);
|
cmpargs = list_make2(variable, prefixcon);
|
||||||
/* Assume scalargtsel is appropriate for all supported types */
|
/* Assume scalargtsel is appropriate for all supported types */
|
||||||
prefixsel = DatumGetFloat8(DirectFunctionCall4(scalargtsel,
|
prefixsel = DatumGetFloat8(DirectFunctionCall4(scalargtsel,
|
||||||
PointerGetDatum(root),
|
PointerGetDatum(root),
|
||||||
@ -3728,7 +3730,7 @@ prefix_selectivity(Query *root, VariableStatData *vardata,
|
|||||||
BTLessStrategyNumber);
|
BTLessStrategyNumber);
|
||||||
if (cmpopr == InvalidOid)
|
if (cmpopr == InvalidOid)
|
||||||
elog(ERROR, "no < operator for opclass %u", opclass);
|
elog(ERROR, "no < operator for opclass %u", opclass);
|
||||||
cmpargs = list_make2(vardata->var, greaterstrcon);
|
cmpargs = list_make2(variable, greaterstrcon);
|
||||||
/* Assume scalarltsel is appropriate for all supported types */
|
/* Assume scalarltsel is appropriate for all supported types */
|
||||||
topsel = DatumGetFloat8(DirectFunctionCall4(scalarltsel,
|
topsel = DatumGetFloat8(DirectFunctionCall4(scalarltsel,
|
||||||
PointerGetDatum(root),
|
PointerGetDatum(root),
|
||||||
@ -3743,7 +3745,7 @@ prefix_selectivity(Query *root, VariableStatData *vardata,
|
|||||||
prefixsel = topsel + prefixsel - 1.0;
|
prefixsel = topsel + prefixsel - 1.0;
|
||||||
|
|
||||||
/* Adjust for double-exclusion of NULLs */
|
/* Adjust for double-exclusion of NULLs */
|
||||||
prefixsel += nulltestsel(root, IS_NULL, vardata->var, 0);
|
prefixsel += nulltestsel(root, IS_NULL, variable, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A zero or slightly negative prefixsel should be converted into
|
* A zero or slightly negative prefixsel should be converted into
|
||||||
|
Reference in New Issue
Block a user