aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/selfuncs.c109
1 files changed, 52 insertions, 57 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index ad9f662b68d..5bf04d052a6 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.236 2007/08/31 23:35:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.237 2007/11/07 21:00:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -901,7 +901,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);
@@ -922,22 +922,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)
{
@@ -956,7 +973,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
if (consttype != TEXTOID && consttype != BYTEAOID)
{
ReleaseVariableStats(vardata);
- return DEFAULT_MATCH_SEL;
+ return result;
}
/*
@@ -988,7 +1005,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 */
@@ -1017,7 +1034,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);
@@ -1125,7 +1142,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
ReleaseVariableStats(vardata);
- return result;
+ return negate ? (1.0 - result) : result;
}
/*
@@ -1134,7 +1151,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));
}
/*
@@ -1143,7 +1160,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));
}
/*
@@ -1152,7 +1169,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));
}
/*
@@ -1161,7 +1178,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));
}
/*
@@ -1170,11 +1187,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));
}
/*
@@ -1183,11 +1196,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));
}
/*
@@ -1196,11 +1205,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));
}
/*
@@ -1209,11 +1214,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));
}
/*
@@ -2082,12 +2083,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));
}
/*
@@ -2096,7 +2107,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));
}
/*
@@ -2105,7 +2116,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));
}
/*
@@ -2114,7 +2125,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));
}
/*
@@ -2123,11 +2134,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));
}
/*
@@ -2136,11 +2143,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));
}
/*
@@ -2149,11 +2152,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));
}
/*
@@ -2162,11 +2161,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));
}
/*