diff options
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 109 |
1 files changed, 52 insertions, 57 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 56248a93b6a..f1a83b0875b 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.214.2.6 2007/08/31 23:35:29 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.214.2.7 2007/11/07 21:00:44 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -900,7 +900,7 @@ scalargtsel(PG_FUNCTION_ARGS) * patternsel - Generic code for pattern-match selectivity. */ static double -patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) +patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate) { PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); Oid operator = PG_GETARG_OID(1); @@ -921,22 +921,39 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) double result; /* + * If this is for a NOT LIKE or similar operator, get the corresponding + * positive-match operator and work with that. Set result to the + * correct default estimate, too. + */ + if (negate) + { + operator = get_negator(operator); + if (!OidIsValid(operator)) + elog(ERROR, "patternsel called for operator without a negator"); + result = 1.0 - DEFAULT_MATCH_SEL; + } + else + { + result = DEFAULT_MATCH_SEL; + } + + /* * If expression is not variable op constant, then punt and return a * default estimate. */ if (!get_restriction_variable(root, args, varRelid, &vardata, &other, &varonleft)) - return DEFAULT_MATCH_SEL; + return result; if (!varonleft || !IsA(other, Const)) { ReleaseVariableStats(vardata); - return DEFAULT_MATCH_SEL; + return result; } variable = (Node *) linitial(args); /* * If the constant is NULL, assume operator is strict and return zero, ie, - * operator will never return TRUE. + * operator will never return TRUE. (It's zero even for a negator op.) */ if (((Const *) other)->constisnull) { @@ -955,7 +972,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) if (consttype != TEXTOID && consttype != BYTEAOID) { ReleaseVariableStats(vardata); - return DEFAULT_MATCH_SEL; + return result; } /* @@ -990,7 +1007,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) break; default: ReleaseVariableStats(vardata); - return DEFAULT_MATCH_SEL; + return result; } /* divide pattern into fixed prefix and remainder */ @@ -1019,7 +1036,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) elog(ERROR, "unrecognized consttype: %u", prefix->consttype); ReleaseVariableStats(vardata); - return DEFAULT_MATCH_SEL; + return result; } prefix = string_to_const(prefixstr, vartype); pfree(prefixstr); @@ -1126,7 +1143,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) ReleaseVariableStats(vardata); - return result; + return negate ? (1.0 - result) : result; } /* @@ -1135,7 +1152,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) Datum regexeqsel(PG_FUNCTION_ARGS) { - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex)); + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex, false)); } /* @@ -1144,7 +1161,7 @@ regexeqsel(PG_FUNCTION_ARGS) Datum icregexeqsel(PG_FUNCTION_ARGS) { - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex_IC)); + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex_IC, false)); } /* @@ -1153,7 +1170,7 @@ icregexeqsel(PG_FUNCTION_ARGS) Datum likesel(PG_FUNCTION_ARGS) { - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like)); + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like, false)); } /* @@ -1162,7 +1179,7 @@ likesel(PG_FUNCTION_ARGS) Datum iclikesel(PG_FUNCTION_ARGS) { - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like_IC)); + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like_IC, false)); } /* @@ -1171,11 +1188,7 @@ iclikesel(PG_FUNCTION_ARGS) Datum regexnesel(PG_FUNCTION_ARGS) { - double result; - - result = patternsel(fcinfo, Pattern_Type_Regex); - result = 1.0 - result; - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex, true)); } /* @@ -1184,11 +1197,7 @@ regexnesel(PG_FUNCTION_ARGS) Datum icregexnesel(PG_FUNCTION_ARGS) { - double result; - - result = patternsel(fcinfo, Pattern_Type_Regex_IC); - result = 1.0 - result; - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex_IC, true)); } /* @@ -1197,11 +1206,7 @@ icregexnesel(PG_FUNCTION_ARGS) Datum nlikesel(PG_FUNCTION_ARGS) { - double result; - - result = patternsel(fcinfo, Pattern_Type_Like); - result = 1.0 - result; - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like, true)); } /* @@ -1210,11 +1215,7 @@ nlikesel(PG_FUNCTION_ARGS) Datum icnlikesel(PG_FUNCTION_ARGS) { - double result; - - result = patternsel(fcinfo, Pattern_Type_Like_IC); - result = 1.0 - result; - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like_IC, true)); } /* @@ -2110,12 +2111,22 @@ scalargtjoinsel(PG_FUNCTION_ARGS) } /* + * patternjoinsel - Generic code for pattern-match join selectivity. + */ +static double +patternjoinsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate) +{ + /* For the moment we just punt. */ + return negate ? (1.0 - DEFAULT_MATCH_SEL) : DEFAULT_MATCH_SEL; +} + +/* * regexeqjoinsel - Join selectivity of regular-expression pattern match. */ Datum regexeqjoinsel(PG_FUNCTION_ARGS) { - PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL); + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex, false)); } /* @@ -2124,7 +2135,7 @@ regexeqjoinsel(PG_FUNCTION_ARGS) Datum icregexeqjoinsel(PG_FUNCTION_ARGS) { - PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL); + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex_IC, false)); } /* @@ -2133,7 +2144,7 @@ icregexeqjoinsel(PG_FUNCTION_ARGS) Datum likejoinsel(PG_FUNCTION_ARGS) { - PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL); + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like, false)); } /* @@ -2142,7 +2153,7 @@ likejoinsel(PG_FUNCTION_ARGS) Datum iclikejoinsel(PG_FUNCTION_ARGS) { - PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL); + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like_IC, false)); } /* @@ -2151,11 +2162,7 @@ iclikejoinsel(PG_FUNCTION_ARGS) Datum regexnejoinsel(PG_FUNCTION_ARGS) { - float8 result; - - result = DatumGetFloat8(regexeqjoinsel(fcinfo)); - result = 1.0 - result; - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex, true)); } /* @@ -2164,11 +2171,7 @@ regexnejoinsel(PG_FUNCTION_ARGS) Datum icregexnejoinsel(PG_FUNCTION_ARGS) { - float8 result; - - result = DatumGetFloat8(icregexeqjoinsel(fcinfo)); - result = 1.0 - result; - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex_IC, true)); } /* @@ -2177,11 +2180,7 @@ icregexnejoinsel(PG_FUNCTION_ARGS) Datum nlikejoinsel(PG_FUNCTION_ARGS) { - float8 result; - - result = DatumGetFloat8(likejoinsel(fcinfo)); - result = 1.0 - result; - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like, true)); } /* @@ -2190,11 +2189,7 @@ nlikejoinsel(PG_FUNCTION_ARGS) Datum icnlikejoinsel(PG_FUNCTION_ARGS) { - float8 result; - - result = DatumGetFloat8(iclikejoinsel(fcinfo)); - result = 1.0 - result; - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like_IC, true)); } /* |