1515 *
1616 *
1717 * 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 $
1919 *
2020 *-------------------------------------------------------------------------
2121 */
@@ -1007,10 +1007,9 @@ icnlikesel(PG_FUNCTION_ARGS)
10071007 *booltestsel- Selectivity of BooleanTest Node.
10081008 */
10091009Selectivity
1010- booltestsel (Query * root ,BooleanTest * clause ,int varRelid )
1010+ booltestsel (Query * root ,BoolTestType booltesttype , Node * arg ,int varRelid )
10111011{
10121012Var * var ;
1013- Node * arg ;
10141013Oid relid ;
10151014HeapTuple statsTuple ;
10161015Datum * values ;
@@ -1019,10 +1018,6 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
10191018int nnumbers ;
10201019double selec ;
10211020
1022- Assert (clause && IsA (clause ,BooleanTest ));
1023-
1024- arg = (Node * )clause -> arg ;
1025-
10261021/*
10271022 * Ignore any binary-compatible relabeling (probably unnecessary, but
10281023 * can't hurt)
@@ -1040,7 +1035,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
10401035 * the possibility of a NULL value when using clause_selectivity,
10411036 * and just assume the value is either TRUE or FALSE.
10421037 */
1043- switch (clause -> booltesttype )
1038+ switch (booltesttype )
10441039{
10451040case IS_UNKNOWN :
10461041selec = DEFAULT_UNK_SEL ;
@@ -1058,7 +1053,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
10581053break ;
10591054default :
10601055elog (ERROR ,"booltestsel: unexpected booltesttype %d" ,
1061- (int )clause -> booltesttype );
1056+ (int )booltesttype );
10621057selec = 0.0 ;/* Keep compiler quiet */
10631058break ;
10641059}
@@ -1107,7 +1102,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
11071102 */
11081103freq_false = 1.0 - freq_true - freq_null ;
11091104
1110- switch (clause -> booltesttype )
1105+ switch (booltesttype )
11111106{
11121107case IS_UNKNOWN :
11131108/* select only NULL values */
@@ -1135,7 +1130,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
11351130break ;
11361131default :
11371132elog (ERROR ,"booltestsel: unexpected booltesttype %d" ,
1138- (int )clause -> booltesttype );
1133+ (int )booltesttype );
11391134selec = 0.0 ;/* Keep compiler quiet */
11401135break ;
11411136}
@@ -1151,7 +1146,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
11511146 * Otherwise adjust for null fraction and assume an even split
11521147 * for boolean tests.
11531148 */
1154- switch (clause -> booltesttype )
1149+ switch (booltesttype )
11551150{
11561151case IS_UNKNOWN :
11571152
@@ -1176,7 +1171,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
11761171break ;
11771172default :
11781173elog (ERROR ,"booltestsel: unexpected booltesttype %d" ,
1179- (int )clause -> booltesttype );
1174+ (int )booltesttype );
11801175selec = 0.0 ;/* Keep compiler quiet */
11811176break ;
11821177}
@@ -1190,7 +1185,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
11901185 * No VACUUM ANALYZE stats available, so use a default value.
11911186 * (Note: not much point in recursing to clause_selectivity here.)
11921187 */
1193- switch (clause -> booltesttype )
1188+ switch (booltesttype )
11941189{
11951190case IS_UNKNOWN :
11961191selec = DEFAULT_UNK_SEL ;
@@ -1206,7 +1201,7 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
12061201break ;
12071202default :
12081203elog (ERROR ,"booltestsel: unexpected booltesttype %d" ,
1209- (int )clause -> booltesttype );
1204+ (int )booltesttype );
12101205selec = 0.0 ;/* Keep compiler quiet */
12111206break ;
12121207}
@@ -1222,19 +1217,16 @@ booltestsel(Query *root, BooleanTest *clause, int varRelid)
12221217 *nulltestsel- Selectivity of NullTest Node.
12231218 */
12241219Selectivity
1225- nulltestsel (Query * root ,NullTest * clause ,int varRelid )
1220+ nulltestsel (Query * root ,NullTestType nulltesttype , Node * arg ,int varRelid )
12261221{
12271222Var * var ;
1228- Node * arg ;
12291223Oid relid ;
12301224HeapTuple statsTuple ;
12311225double selec ;
12321226double defselec ;
12331227double freq_null ;
12341228
1235- Assert (clause && IsA (clause ,NullTest ));
1236-
1237- switch (clause -> nulltesttype )
1229+ switch (nulltesttype )
12381230{
12391231case IS_NULL :
12401232defselec = DEFAULT_UNK_SEL ;
@@ -1244,25 +1236,22 @@ nulltestsel(Query *root, NullTest *clause, int varRelid)
12441236break ;
12451237default :
12461238elog (ERROR ,"nulltestsel: unexpected nulltesttype %d" ,
1247- (int )clause -> nulltesttype );
1239+ (int )nulltesttype );
12481240return (Selectivity )0 ;/* keep compiler quiet */
12491241}
12501242
1251- arg = (Node * )clause -> arg ;
1252-
12531243/*
12541244 * Ignore any binary-compatible relabeling
12551245 */
12561246if (IsA (arg ,RelabelType ))
12571247arg = ((RelabelType * )arg )-> arg ;
12581248
1259- if (IsA (arg ,Var )&& (varRelid == 0 || varRelid == ((Var * )arg )-> varno ))
1249+ if (IsA (arg ,Var )&&
1250+ (varRelid == 0 || varRelid == ((Var * )arg )-> varno ))
12601251var = (Var * )arg ;
12611252else
12621253{
1263- /*
1264- * punt if non-Var argument
1265- */
1254+ /* punt if non-Var argument */
12661255return (Selectivity )defselec ;
12671256}
12681257
@@ -1282,7 +1271,7 @@ nulltestsel(Query *root, NullTest *clause, int varRelid)
12821271stats = (Form_pg_statistic )GETSTRUCT (statsTuple );
12831272freq_null = stats -> stanullfrac ;
12841273
1285- switch (clause -> nulltesttype )
1274+ switch (nulltesttype )
12861275{
12871276case IS_NULL :
12881277
@@ -1301,7 +1290,7 @@ nulltestsel(Query *root, NullTest *clause, int varRelid)
13011290break ;
13021291default :
13031292elog (ERROR ,"nulltestsel: unexpected nulltesttype %d" ,
1304- (int )clause -> nulltesttype );
1293+ (int )nulltesttype );
13051294return (Selectivity )0 ;/* keep compiler quiet */
13061295}
13071296
@@ -2978,6 +2967,10 @@ prefix_selectivity(Query *root, Var *var, Const *prefixcon)
29782967else
29792968prefix = DatumGetCString (DirectFunctionCall1 (byteaout ,prefixcon -> constvalue ));
29802969
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+
29812974cmpargs = makeList2 (var ,prefixcon );
29822975/* Assume scalargtsel is appropriate for all supported types */
29832976prefixsel = DatumGetFloat8 (DirectFunctionCall4 (scalargtsel ,
@@ -3014,6 +3007,9 @@ prefix_selectivity(Query *root, Var *var, Const *prefixcon)
30143007 */
30153008prefixsel = topsel + prefixsel - 1.0 ;
30163009
3010+ /* Adjust for double-exclusion of NULLs */
3011+ prefixsel += nulltestsel (root ,IS_NULL , (Node * )var ,var -> varno );
3012+
30173013/*
30183014 * A zero or slightly negative prefixsel should be converted into
30193015 * a small positive value; we probably are dealing with a very
@@ -3351,6 +3347,7 @@ make_greater_string(const Const *str_const)
33513347while (len > 0 )
33523348{
33533349unsignedchar * lastchar = (unsignedchar * ) (workstr + len - 1 );
3350+ unsignedchar savelastchar = * lastchar ;
33543351
33553352/*
33563353 * Try to generate a larger string by incrementing the last byte.
@@ -3369,6 +3366,9 @@ make_greater_string(const Const *str_const)
33693366}
33703367}
33713368
3369+ /* restore last byte so we don't confuse pg_mbcliplen */
3370+ * lastchar = savelastchar ;
3371+
33723372/*
33733373 * Truncate off the last character, which might be more than 1
33743374 * byte, depending on the character encoding.