15
15
*
16
16
*
17
17
* IDENTIFICATION
18
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.118 2002/09/20 03:55:40 momjian Exp $
18
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.119 2002/10/19 02:56:16 tgl Exp $
19
19
*
20
20
*-------------------------------------------------------------------------
21
21
*/
@@ -1007,10 +1007,9 @@ icnlikesel(PG_FUNCTION_ARGS)
1007
1007
* booltestsel - Selectivity of BooleanTest Node.
1008
1008
*/
1009
1009
Selectivity
1010
- booltestsel (Query * root , BooleanTest * clause , int varRelid )
1010
+ booltestsel (Query * root , BoolTestType booltesttype , Node * arg , int varRelid )
1011
1011
{
1012
1012
Var * var ;
1013
- Node * arg ;
1014
1013
Oid relid ;
1015
1014
HeapTuple statsTuple ;
1016
1015
Datum * values ;
@@ -1019,10 +1018,6 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
1019
1018
int nnumbers ;
1020
1019
double selec ;
1021
1020
1022
- Assert (clause && IsA (clause , BooleanTest ));
1023
-
1024
- arg = (Node * ) clause -> arg ;
1025
-
1026
1021
/*
1027
1022
* Ignore any binary-compatible relabeling (probably unnecessary, but
1028
1023
* can't hurt)
@@ -1040,7 +1035,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
1040
1035
* the possibility of a NULL value when using clause_selectivity,
1041
1036
* and just assume the value is either TRUE or FALSE.
1042
1037
*/
1043
- switch (clause -> booltesttype )
1038
+ switch (booltesttype )
1044
1039
{
1045
1040
case IS_UNKNOWN :
1046
1041
selec = DEFAULT_UNK_SEL ;
@@ -1058,7 +1053,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
1058
1053
break ;
1059
1054
default :
1060
1055
elog (ERROR , "booltestsel: unexpected booltesttype %d" ,
1061
- (int ) clause -> booltesttype );
1056
+ (int ) booltesttype );
1062
1057
selec = 0.0 ; /* Keep compiler quiet */
1063
1058
break ;
1064
1059
}
@@ -1107,7 +1102,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
1107
1102
*/
1108
1103
freq_false = 1.0 - freq_true - freq_null ;
1109
1104
1110
- switch (clause -> booltesttype )
1105
+ switch (booltesttype )
1111
1106
{
1112
1107
case IS_UNKNOWN :
1113
1108
/* select only NULL values */
@@ -1135,7 +1130,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
1135
1130
break ;
1136
1131
default :
1137
1132
elog (ERROR , "booltestsel: unexpected booltesttype %d" ,
1138
- (int ) clause -> booltesttype );
1133
+ (int ) booltesttype );
1139
1134
selec = 0.0 ; /* Keep compiler quiet */
1140
1135
break ;
1141
1136
}
@@ -1151,7 +1146,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
1151
1146
* Otherwise adjust for null fraction and assume an even split
1152
1147
* for boolean tests.
1153
1148
*/
1154
- switch (clause -> booltesttype )
1149
+ switch (booltesttype )
1155
1150
{
1156
1151
case IS_UNKNOWN :
1157
1152
@@ -1176,7 +1171,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
1176
1171
break ;
1177
1172
default :
1178
1173
elog (ERROR , "booltestsel: unexpected booltesttype %d" ,
1179
- (int ) clause -> booltesttype );
1174
+ (int ) booltesttype );
1180
1175
selec = 0.0 ; /* Keep compiler quiet */
1181
1176
break ;
1182
1177
}
@@ -1190,7 +1185,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
1190
1185
* No VACUUM ANALYZE stats available, so use a default value.
1191
1186
* (Note: not much point in recursing to clause_selectivity here.)
1192
1187
*/
1193
- switch (clause -> booltesttype )
1188
+ switch (booltesttype )
1194
1189
{
1195
1190
case IS_UNKNOWN :
1196
1191
selec = DEFAULT_UNK_SEL ;
@@ -1206,7 +1201,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
1206
1201
break ;
1207
1202
default :
1208
1203
elog (ERROR , "booltestsel: unexpected booltesttype %d" ,
1209
- (int ) clause -> booltesttype );
1204
+ (int ) booltesttype );
1210
1205
selec = 0.0 ; /* Keep compiler quiet */
1211
1206
break ;
1212
1207
}
@@ -1222,19 +1217,16 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
1222
1217
* nulltestsel - Selectivity of NullTest Node.
1223
1218
*/
1224
1219
Selectivity
1225
- nulltestsel (Query * root , NullTest * clause , int varRelid )
1220
+ nulltestsel (Query * root , NullTestType nulltesttype , Node * arg , int varRelid )
1226
1221
{
1227
1222
Var * var ;
1228
- Node * arg ;
1229
1223
Oid relid ;
1230
1224
HeapTuple statsTuple ;
1231
1225
double selec ;
1232
1226
double defselec ;
1233
1227
double freq_null ;
1234
1228
1235
- Assert (clause && IsA (clause , NullTest ));
1236
-
1237
- switch (clause -> nulltesttype )
1229
+ switch (nulltesttype )
1238
1230
{
1239
1231
case IS_NULL :
1240
1232
defselec = DEFAULT_UNK_SEL ;
@@ -1244,25 +1236,22 @@ nulltestsel(Query *root, NullTest *clause, int varRelid)
1244
1236
break ;
1245
1237
default :
1246
1238
elog (ERROR , "nulltestsel: unexpected nulltesttype %d" ,
1247
- (int ) clause -> nulltesttype );
1239
+ (int ) nulltesttype );
1248
1240
return (Selectivity ) 0 ; /* keep compiler quiet */
1249
1241
}
1250
1242
1251
- arg = (Node * ) clause -> arg ;
1252
-
1253
1243
/*
1254
1244
* Ignore any binary-compatible relabeling
1255
1245
*/
1256
1246
if (IsA (arg , RelabelType ))
1257
1247
arg = ((RelabelType * ) arg )-> arg ;
1258
1248
1259
- if (IsA (arg , Var ) && (varRelid == 0 || varRelid == ((Var * ) arg )-> varno ))
1249
+ if (IsA (arg , Var ) &&
1250
+ (varRelid == 0 || varRelid == ((Var * ) arg )-> varno ))
1260
1251
var = (Var * ) arg ;
1261
1252
else
1262
1253
{
1263
- /*
1264
- * punt if non-Var argument
1265
- */
1254
+ /* punt if non-Var argument */
1266
1255
return (Selectivity ) defselec ;
1267
1256
}
1268
1257
@@ -1282,7 +1271,7 @@ nulltestsel(Query *root, NullTest *clause, int varRelid)
1282
1271
stats = (Form_pg_statistic ) GETSTRUCT (statsTuple );
1283
1272
freq_null = stats -> stanullfrac ;
1284
1273
1285
- switch (clause -> nulltesttype )
1274
+ switch (nulltesttype )
1286
1275
{
1287
1276
case IS_NULL :
1288
1277
@@ -1301,7 +1290,7 @@ nulltestsel(Query *root, NullTest *clause, int varRelid)
1301
1290
break ;
1302
1291
default :
1303
1292
elog (ERROR , "nulltestsel: unexpected nulltesttype %d" ,
1304
- (int ) clause -> nulltesttype );
1293
+ (int ) nulltesttype );
1305
1294
return (Selectivity ) 0 ; /* keep compiler quiet */
1306
1295
}
1307
1296
@@ -2978,6 +2967,10 @@ prefix_selectivity(Query *root, Var *var, Const *prefixcon)
2978
2967
else
2979
2968
prefix = DatumGetCString (DirectFunctionCall1 (byteaout , prefixcon -> constvalue ));
2980
2969
2970
+ /* If var is type NAME, must adjust type of comparison constant */
2971
+ if (var -> vartype == NAMEOID )
2972
+ prefixcon = string_to_const (prefix , NAMEOID );
2973
+
2981
2974
cmpargs = makeList2 (var , prefixcon );
2982
2975
/* Assume scalargtsel is appropriate for all supported types */
2983
2976
prefixsel = DatumGetFloat8 (DirectFunctionCall4 (scalargtsel ,
@@ -3014,6 +3007,9 @@ prefix_selectivity(Query *root, Var *var, Const *prefixcon)
3014
3007
*/
3015
3008
prefixsel = topsel + prefixsel - 1.0 ;
3016
3009
3010
+ /* Adjust for double-exclusion of NULLs */
3011
+ prefixsel += nulltestsel (root , IS_NULL , (Node * ) var , var -> varno );
3012
+
3017
3013
/*
3018
3014
* A zero or slightly negative prefixsel should be converted into
3019
3015
* a small positive value; we probably are dealing with a very
@@ -3351,6 +3347,7 @@ make_greater_string(const Const *str_const)
3351
3347
while (len > 0 )
3352
3348
{
3353
3349
unsigned char * lastchar = (unsigned char * ) (workstr + len - 1 );
3350
+ unsigned char savelastchar = * lastchar ;
3354
3351
3355
3352
/*
3356
3353
* Try to generate a larger string by incrementing the last byte.
@@ -3369,6 +3366,9 @@ make_greater_string(const Const *str_const)
3369
3366
}
3370
3367
}
3371
3368
3369
+ /* restore last byte so we don't confuse pg_mbcliplen */
3370
+ * lastchar = savelastchar ;
3371
+
3372
3372
/*
3373
3373
* Truncate off the last character, which might be more than 1
3374
3374
* byte, depending on the character encoding.
0 commit comments