15
15
*
16
16
*
17
17
* IDENTIFICATION
18
- * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.173 2005/03/07 04:30:51 momjian Exp $
18
+ * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.174 2005/03/26 20:55:39 tgl Exp $
19
19
*
20
20
*-------------------------------------------------------------------------
21
21
*/
@@ -2309,14 +2309,17 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
2309
2309
* constant-folding will ensure that any Const passed to the operator
2310
2310
* has been reduced to the correct type). However, the boundstypid is
2311
2311
* the type of some variable that might be only binary-compatible with
2312
- * the declared type; in particular it might be a domain type. Must
2313
- * fold the variable type down to base type so we can recognize it.
2314
- * (But we can skip that lookup if the variable type matches the
2315
- * const.)
2312
+ * the declared type; for example it might be a domain type. So we
2313
+ * ignore it and work with the valuetypid only.
2314
+ *
2315
+ * XXX What's really going on here is that we assume that the scalar
2316
+ * representations of binary-compatible types are enough alike that we
2317
+ * can use a histogram generated with one type's operators to estimate
2318
+ * selectivity for the other's. This is outright wrong in some cases ---
2319
+ * in particular signed versus unsigned interpretation could trip us up.
2320
+ * But it's useful enough in the majority of cases that we do it anyway.
2321
+ * Should think about more rigorous ways to do it.
2316
2322
*/
2317
- if (boundstypid != valuetypid )
2318
- boundstypid = getBaseType (boundstypid );
2319
-
2320
2323
switch (valuetypid )
2321
2324
{
2322
2325
/*
@@ -2337,8 +2340,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
2337
2340
case REGCLASSOID :
2338
2341
case REGTYPEOID :
2339
2342
* scaledvalue = convert_numeric_to_scalar (value , valuetypid );
2340
- * scaledlobound = convert_numeric_to_scalar (lobound , boundstypid );
2341
- * scaledhibound = convert_numeric_to_scalar (hibound , boundstypid );
2343
+ * scaledlobound = convert_numeric_to_scalar (lobound , valuetypid );
2344
+ * scaledhibound = convert_numeric_to_scalar (hibound , valuetypid );
2342
2345
return true;
2343
2346
2344
2347
/*
@@ -2351,8 +2354,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
2351
2354
case NAMEOID :
2352
2355
{
2353
2356
unsigned char * valstr = convert_string_datum (value , valuetypid );
2354
- unsigned char * lostr = convert_string_datum (lobound , boundstypid );
2355
- unsigned char * histr = convert_string_datum (hibound , boundstypid );
2357
+ unsigned char * lostr = convert_string_datum (lobound , valuetypid );
2358
+ unsigned char * histr = convert_string_datum (hibound , valuetypid );
2356
2359
2357
2360
convert_string_to_scalar (valstr , scaledvalue ,
2358
2361
lostr , scaledlobound ,
@@ -2387,8 +2390,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
2387
2390
case TIMEOID :
2388
2391
case TIMETZOID :
2389
2392
* scaledvalue = convert_timevalue_to_scalar (value , valuetypid );
2390
- * scaledlobound = convert_timevalue_to_scalar (lobound , boundstypid );
2391
- * scaledhibound = convert_timevalue_to_scalar (hibound , boundstypid );
2393
+ * scaledlobound = convert_timevalue_to_scalar (lobound , valuetypid );
2394
+ * scaledhibound = convert_timevalue_to_scalar (hibound , valuetypid );
2392
2395
return true;
2393
2396
2394
2397
/*
@@ -2398,8 +2401,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
2398
2401
case CIDROID :
2399
2402
case MACADDROID :
2400
2403
* scaledvalue = convert_network_to_scalar (value , valuetypid );
2401
- * scaledlobound = convert_network_to_scalar (lobound , boundstypid );
2402
- * scaledhibound = convert_network_to_scalar (hibound , boundstypid );
2404
+ * scaledlobound = convert_network_to_scalar (lobound , valuetypid );
2405
+ * scaledhibound = convert_network_to_scalar (hibound , valuetypid );
2403
2406
return true;
2404
2407
}
2405
2408
/* Don't know how to convert */
@@ -2848,8 +2851,7 @@ convert_timevalue_to_scalar(Datum value, Oid typid)
2848
2851
*
2849
2852
* Outputs: (these are valid only if TRUE is returned)
2850
2853
* *vardata: gets information about variable (see examine_variable)
2851
- * *other: gets other clause argument, stripped of binary relabeling,
2852
- * and aggressively reduced to a constant
2854
+ * *other: gets other clause argument, aggressively reduced to a constant
2853
2855
* *varonleft: set TRUE if variable is on the left, FALSE if on the right
2854
2856
*
2855
2857
* Returns TRUE if a variable is identified, otherwise FALSE.
@@ -2939,7 +2941,8 @@ get_join_variables(Query *root, List *args,
2939
2941
* varRelid: see specs for restriction selectivity functions
2940
2942
*
2941
2943
* Outputs: *vardata is filled as follows:
2942
- * var: the input expression (with any binary relabeling stripped)
2944
+ * var: the input expression (with any binary relabeling stripped, if
2945
+ * it is or contains a variable; but otherwise the type is preserved)
2943
2946
* rel: RelOptInfo for relation containing variable; NULL if expression
2944
2947
* contains no Vars (NOTE this could point to a RelOptInfo of a
2945
2948
* subquery, not one in the current query).
@@ -2955,27 +2958,29 @@ static void
2955
2958
examine_variable (Query * root , Node * node , int varRelid ,
2956
2959
VariableStatData * vardata )
2957
2960
{
2961
+ Node * basenode ;
2958
2962
Relids varnos ;
2959
2963
RelOptInfo * onerel ;
2960
2964
2961
2965
/* Make sure we don't return dangling pointers in vardata */
2962
2966
MemSet (vardata , 0 , sizeof (VariableStatData ));
2963
2967
2964
- /* Ignore any binary-compatible relabeling */
2968
+ /* Look inside any binary-compatible relabeling */
2965
2969
2966
2970
if (IsA (node , RelabelType ))
2967
- node = (Node * ) ((RelabelType * ) node )-> arg ;
2968
-
2969
- vardata -> var = node ;
2971
+ basenode = (Node * ) ((RelabelType * ) node )-> arg ;
2972
+ else
2973
+ basenode = node ;
2970
2974
2971
2975
/* Fast path for a simple Var */
2972
2976
2973
- if (IsA (node , Var ) &&
2974
- (varRelid == 0 || varRelid == ((Var * ) node )-> varno ))
2977
+ if (IsA (basenode , Var ) &&
2978
+ (varRelid == 0 || varRelid == ((Var * ) basenode )-> varno ))
2975
2979
{
2976
- Var * var = (Var * ) node ;
2980
+ Var * var = (Var * ) basenode ;
2977
2981
Oid relid ;
2978
2982
2983
+ vardata -> var = basenode ; /* return Var without relabeling */
2979
2984
vardata -> rel = find_base_rel (root , var -> varno );
2980
2985
vardata -> atttype = var -> vartype ;
2981
2986
vardata -> atttypmod = var -> vartypmod ;
@@ -3009,7 +3014,7 @@ examine_variable(Query *root, Node *node, int varRelid,
3009
3014
* membership. Note that when varRelid isn't zero, only vars of that
3010
3015
* relation are considered "real" vars.
3011
3016
*/
3012
- varnos = pull_varnos (node );
3017
+ varnos = pull_varnos (basenode );
3013
3018
3014
3019
onerel = NULL ;
3015
3020
@@ -3024,6 +3029,7 @@ examine_variable(Query *root, Node *node, int varRelid,
3024
3029
onerel = find_base_rel (root ,
3025
3030
(varRelid ? varRelid : bms_singleton_member (varnos )));
3026
3031
vardata -> rel = onerel ;
3032
+ node = basenode ; /* strip any relabeling */
3027
3033
}
3028
3034
/* else treat it as a constant */
3029
3035
break ;
@@ -3032,11 +3038,13 @@ examine_variable(Query *root, Node *node, int varRelid,
3032
3038
{
3033
3039
/* treat it as a variable of a join relation */
3034
3040
vardata -> rel = find_join_rel (root , varnos );
3041
+ node = basenode ; /* strip any relabeling */
3035
3042
}
3036
3043
else if (bms_is_member (varRelid , varnos ))
3037
3044
{
3038
3045
/* ignore the vars belonging to other relations */
3039
3046
vardata -> rel = find_base_rel (root , varRelid );
3047
+ node = basenode ; /* strip any relabeling */
3040
3048
/* note: no point in expressional-index search here */
3041
3049
}
3042
3050
/* else treat it as a constant */
@@ -3045,6 +3053,7 @@ examine_variable(Query *root, Node *node, int varRelid,
3045
3053
3046
3054
bms_free (varnos );
3047
3055
3056
+ vardata -> var = node ;
3048
3057
vardata -> atttype = exprType (node );
3049
3058
vardata -> atttypmod = exprTypmod (node );
3050
3059
0 commit comments