15
15
*
16
16
*
17
17
* IDENTIFICATION
18
- * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.236 2007/08/31 23:35:22 tgl Exp $
18
+ * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.237 2007/11/07 21:00:37 tgl Exp $
19
19
*
20
20
*-------------------------------------------------------------------------
21
21
*/
@@ -901,7 +901,7 @@ scalargtsel(PG_FUNCTION_ARGS)
901
901
* patternsel - Generic code for pattern-match selectivity.
902
902
*/
903
903
static double
904
- patternsel (PG_FUNCTION_ARGS , Pattern_Type ptype )
904
+ patternsel (PG_FUNCTION_ARGS , Pattern_Type ptype , bool negate )
905
905
{
906
906
PlannerInfo * root = (PlannerInfo * ) PG_GETARG_POINTER (0 );
907
907
Oid operator = PG_GETARG_OID (1 );
@@ -921,23 +921,40 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
921
921
Const * rest = NULL ;
922
922
double result ;
923
923
924
+ /*
925
+ * If this is for a NOT LIKE or similar operator, get the corresponding
926
+ * positive-match operator and work with that. Set result to the
927
+ * correct default estimate, too.
928
+ */
929
+ if (negate )
930
+ {
931
+ operator = get_negator (operator );
932
+ if (!OidIsValid (operator ))
933
+ elog (ERROR , "patternsel called for operator without a negator" );
934
+ result = 1.0 - DEFAULT_MATCH_SEL ;
935
+ }
936
+ else
937
+ {
938
+ result = DEFAULT_MATCH_SEL ;
939
+ }
940
+
924
941
/*
925
942
* If expression is not variable op constant, then punt and return a
926
943
* default estimate.
927
944
*/
928
945
if (!get_restriction_variable (root , args , varRelid ,
929
946
& vardata , & other , & varonleft ))
930
- return DEFAULT_MATCH_SEL ;
947
+ return result ;
931
948
if (!varonleft || !IsA (other , Const ))
932
949
{
933
950
ReleaseVariableStats (vardata );
934
- return DEFAULT_MATCH_SEL ;
951
+ return result ;
935
952
}
936
953
variable = (Node * ) linitial (args );
937
954
938
955
/*
939
956
* If the constant is NULL, assume operator is strict and return zero, ie,
940
- * operator will never return TRUE.
957
+ * operator will never return TRUE. (It's zero even for a negator op.)
941
958
*/
942
959
if (((Const * ) other )-> constisnull )
943
960
{
@@ -956,7 +973,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
956
973
if (consttype != TEXTOID && consttype != BYTEAOID )
957
974
{
958
975
ReleaseVariableStats (vardata );
959
- return DEFAULT_MATCH_SEL ;
976
+ return result ;
960
977
}
961
978
962
979
/*
@@ -988,7 +1005,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
988
1005
break ;
989
1006
default :
990
1007
ReleaseVariableStats (vardata );
991
- return DEFAULT_MATCH_SEL ;
1008
+ return result ;
992
1009
}
993
1010
994
1011
/* divide pattern into fixed prefix and remainder */
@@ -1017,7 +1034,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
1017
1034
elog (ERROR , "unrecognized consttype: %u" ,
1018
1035
prefix -> consttype );
1019
1036
ReleaseVariableStats (vardata );
1020
- return DEFAULT_MATCH_SEL ;
1037
+ return result ;
1021
1038
}
1022
1039
prefix = string_to_const (prefixstr , vartype );
1023
1040
pfree (prefixstr );
@@ -1125,7 +1142,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
1125
1142
1126
1143
ReleaseVariableStats (vardata );
1127
1144
1128
- return result ;
1145
+ return negate ? ( 1.0 - result ) : result ;
1129
1146
}
1130
1147
1131
1148
/*
@@ -1134,7 +1151,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
1134
1151
Datum
1135
1152
regexeqsel (PG_FUNCTION_ARGS )
1136
1153
{
1137
- PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Regex ));
1154
+ PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Regex , false ));
1138
1155
}
1139
1156
1140
1157
/*
@@ -1143,7 +1160,7 @@ regexeqsel(PG_FUNCTION_ARGS)
1143
1160
Datum
1144
1161
icregexeqsel (PG_FUNCTION_ARGS )
1145
1162
{
1146
- PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Regex_IC ));
1163
+ PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Regex_IC , false ));
1147
1164
}
1148
1165
1149
1166
/*
@@ -1152,7 +1169,7 @@ icregexeqsel(PG_FUNCTION_ARGS)
1152
1169
Datum
1153
1170
likesel (PG_FUNCTION_ARGS )
1154
1171
{
1155
- PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Like ));
1172
+ PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Like , false ));
1156
1173
}
1157
1174
1158
1175
/*
@@ -1161,7 +1178,7 @@ likesel(PG_FUNCTION_ARGS)
1161
1178
Datum
1162
1179
iclikesel (PG_FUNCTION_ARGS )
1163
1180
{
1164
- PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Like_IC ));
1181
+ PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Like_IC , false ));
1165
1182
}
1166
1183
1167
1184
/*
@@ -1170,11 +1187,7 @@ iclikesel(PG_FUNCTION_ARGS)
1170
1187
Datum
1171
1188
regexnesel (PG_FUNCTION_ARGS )
1172
1189
{
1173
- double result ;
1174
-
1175
- result = patternsel (fcinfo , Pattern_Type_Regex );
1176
- result = 1.0 - result ;
1177
- PG_RETURN_FLOAT8 (result );
1190
+ PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Regex , true));
1178
1191
}
1179
1192
1180
1193
/*
@@ -1183,11 +1196,7 @@ regexnesel(PG_FUNCTION_ARGS)
1183
1196
Datum
1184
1197
icregexnesel (PG_FUNCTION_ARGS )
1185
1198
{
1186
- double result ;
1187
-
1188
- result = patternsel (fcinfo , Pattern_Type_Regex_IC );
1189
- result = 1.0 - result ;
1190
- PG_RETURN_FLOAT8 (result );
1199
+ PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Regex_IC , true));
1191
1200
}
1192
1201
1193
1202
/*
@@ -1196,11 +1205,7 @@ icregexnesel(PG_FUNCTION_ARGS)
1196
1205
Datum
1197
1206
nlikesel (PG_FUNCTION_ARGS )
1198
1207
{
1199
- double result ;
1200
-
1201
- result = patternsel (fcinfo , Pattern_Type_Like );
1202
- result = 1.0 - result ;
1203
- PG_RETURN_FLOAT8 (result );
1208
+ PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Like , true));
1204
1209
}
1205
1210
1206
1211
/*
@@ -1209,11 +1214,7 @@ nlikesel(PG_FUNCTION_ARGS)
1209
1214
Datum
1210
1215
icnlikesel (PG_FUNCTION_ARGS )
1211
1216
{
1212
- double result ;
1213
-
1214
- result = patternsel (fcinfo , Pattern_Type_Like_IC );
1215
- result = 1.0 - result ;
1216
- PG_RETURN_FLOAT8 (result );
1217
+ PG_RETURN_FLOAT8 (patternsel (fcinfo , Pattern_Type_Like_IC , true));
1217
1218
}
1218
1219
1219
1220
/*
@@ -2081,13 +2082,23 @@ scalargtjoinsel(PG_FUNCTION_ARGS)
2081
2082
PG_RETURN_FLOAT8 (DEFAULT_INEQ_SEL );
2082
2083
}
2083
2084
2085
+ /*
2086
+ * patternjoinsel - Generic code for pattern-match join selectivity.
2087
+ */
2088
+ static double
2089
+ patternjoinsel (PG_FUNCTION_ARGS , Pattern_Type ptype , bool negate )
2090
+ {
2091
+ /* For the moment we just punt. */
2092
+ return negate ? (1.0 - DEFAULT_MATCH_SEL ) : DEFAULT_MATCH_SEL ;
2093
+ }
2094
+
2084
2095
/*
2085
2096
* regexeqjoinsel - Join selectivity of regular-expression pattern match.
2086
2097
*/
2087
2098
Datum
2088
2099
regexeqjoinsel (PG_FUNCTION_ARGS )
2089
2100
{
2090
- PG_RETURN_FLOAT8 (DEFAULT_MATCH_SEL );
2101
+ PG_RETURN_FLOAT8 (patternjoinsel ( fcinfo , Pattern_Type_Regex , false) );
2091
2102
}
2092
2103
2093
2104
/*
@@ -2096,7 +2107,7 @@ regexeqjoinsel(PG_FUNCTION_ARGS)
2096
2107
Datum
2097
2108
icregexeqjoinsel (PG_FUNCTION_ARGS )
2098
2109
{
2099
- PG_RETURN_FLOAT8 (DEFAULT_MATCH_SEL );
2110
+ PG_RETURN_FLOAT8 (patternjoinsel ( fcinfo , Pattern_Type_Regex_IC , false) );
2100
2111
}
2101
2112
2102
2113
/*
@@ -2105,7 +2116,7 @@ icregexeqjoinsel(PG_FUNCTION_ARGS)
2105
2116
Datum
2106
2117
likejoinsel (PG_FUNCTION_ARGS )
2107
2118
{
2108
- PG_RETURN_FLOAT8 (DEFAULT_MATCH_SEL );
2119
+ PG_RETURN_FLOAT8 (patternjoinsel ( fcinfo , Pattern_Type_Like , false) );
2109
2120
}
2110
2121
2111
2122
/*
@@ -2114,7 +2125,7 @@ likejoinsel(PG_FUNCTION_ARGS)
2114
2125
Datum
2115
2126
iclikejoinsel (PG_FUNCTION_ARGS )
2116
2127
{
2117
- PG_RETURN_FLOAT8 (DEFAULT_MATCH_SEL );
2128
+ PG_RETURN_FLOAT8 (patternjoinsel ( fcinfo , Pattern_Type_Like_IC , false) );
2118
2129
}
2119
2130
2120
2131
/*
@@ -2123,11 +2134,7 @@ iclikejoinsel(PG_FUNCTION_ARGS)
2123
2134
Datum
2124
2135
regexnejoinsel (PG_FUNCTION_ARGS )
2125
2136
{
2126
- float8 result ;
2127
-
2128
- result = DatumGetFloat8 (regexeqjoinsel (fcinfo ));
2129
- result = 1.0 - result ;
2130
- PG_RETURN_FLOAT8 (result );
2137
+ PG_RETURN_FLOAT8 (patternjoinsel (fcinfo , Pattern_Type_Regex , true));
2131
2138
}
2132
2139
2133
2140
/*
@@ -2136,11 +2143,7 @@ regexnejoinsel(PG_FUNCTION_ARGS)
2136
2143
Datum
2137
2144
icregexnejoinsel (PG_FUNCTION_ARGS )
2138
2145
{
2139
- float8 result ;
2140
-
2141
- result = DatumGetFloat8 (icregexeqjoinsel (fcinfo ));
2142
- result = 1.0 - result ;
2143
- PG_RETURN_FLOAT8 (result );
2146
+ PG_RETURN_FLOAT8 (patternjoinsel (fcinfo , Pattern_Type_Regex_IC , true));
2144
2147
}
2145
2148
2146
2149
/*
@@ -2149,11 +2152,7 @@ icregexnejoinsel(PG_FUNCTION_ARGS)
2149
2152
Datum
2150
2153
nlikejoinsel (PG_FUNCTION_ARGS )
2151
2154
{
2152
- float8 result ;
2153
-
2154
- result = DatumGetFloat8 (likejoinsel (fcinfo ));
2155
- result = 1.0 - result ;
2156
- PG_RETURN_FLOAT8 (result );
2155
+ PG_RETURN_FLOAT8 (patternjoinsel (fcinfo , Pattern_Type_Like , true));
2157
2156
}
2158
2157
2159
2158
/*
@@ -2162,11 +2161,7 @@ nlikejoinsel(PG_FUNCTION_ARGS)
2162
2161
Datum
2163
2162
icnlikejoinsel (PG_FUNCTION_ARGS )
2164
2163
{
2165
- float8 result ;
2166
-
2167
- result = DatumGetFloat8 (iclikejoinsel (fcinfo ));
2168
- result = 1.0 - result ;
2169
- PG_RETURN_FLOAT8 (result );
2164
+ PG_RETURN_FLOAT8 (patternjoinsel (fcinfo , Pattern_Type_Like_IC , true));
2170
2165
}
2171
2166
2172
2167
/*
0 commit comments