1515 *
1616 *
1717 * 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 $
1919 *
2020 *-------------------------------------------------------------------------
2121 */
@@ -2309,14 +2309,17 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
23092309 * constant-folding will ensure that any Const passed to the operator
23102310 * has been reduced to the correct type). However, the boundstypid is
23112311 * 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.
23162322 */
2317- if (boundstypid != valuetypid )
2318- boundstypid = getBaseType (boundstypid );
2319-
23202323 switch (valuetypid )
23212324 {
23222325 /*
@@ -2337,8 +2340,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
23372340 case REGCLASSOID :
23382341 case REGTYPEOID :
23392342 * 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 );
23422345 return true;
23432346
23442347 /*
@@ -2351,8 +2354,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
23512354 case NAMEOID :
23522355 {
23532356 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 );
23562359
23572360 convert_string_to_scalar (valstr , scaledvalue ,
23582361 lostr , scaledlobound ,
@@ -2387,8 +2390,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
23872390 case TIMEOID :
23882391 case TIMETZOID :
23892392 * 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 );
23922395 return true;
23932396
23942397 /*
@@ -2398,8 +2401,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
23982401 case CIDROID :
23992402 case MACADDROID :
24002403 * 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 );
24032406 return true;
24042407 }
24052408 /* Don't know how to convert */
@@ -2848,8 +2851,7 @@ convert_timevalue_to_scalar(Datum value, Oid typid)
28482851 *
28492852 * Outputs: (these are valid only if TRUE is returned)
28502853 * *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
28532855 * *varonleft: set TRUE if variable is on the left, FALSE if on the right
28542856 *
28552857 * Returns TRUE if a variable is identified, otherwise FALSE.
@@ -2939,7 +2941,8 @@ get_join_variables(Query *root, List *args,
29392941 * varRelid: see specs for restriction selectivity functions
29402942 *
29412943 * 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)
29432946 * rel: RelOptInfo for relation containing variable; NULL if expression
29442947 * contains no Vars (NOTE this could point to a RelOptInfo of a
29452948 * subquery, not one in the current query).
@@ -2955,27 +2958,29 @@ static void
29552958examine_variable (Query * root , Node * node , int varRelid ,
29562959 VariableStatData * vardata )
29572960{
2961+ Node * basenode ;
29582962 Relids varnos ;
29592963 RelOptInfo * onerel ;
29602964
29612965 /* Make sure we don't return dangling pointers in vardata */
29622966 MemSet (vardata , 0 , sizeof (VariableStatData ));
29632967
2964- /* Ignore any binary-compatible relabeling */
2968+ /* Look inside any binary-compatible relabeling */
29652969
29662970 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 ;
29702974
29712975 /* Fast path for a simple Var */
29722976
2973- if (IsA (node , Var ) &&
2974- (varRelid == 0 || varRelid == ((Var * ) node )-> varno ))
2977+ if (IsA (basenode , Var ) &&
2978+ (varRelid == 0 || varRelid == ((Var * ) basenode )-> varno ))
29752979 {
2976- Var * var = (Var * ) node ;
2980+ Var * var = (Var * ) basenode ;
29772981 Oid relid ;
29782982
2983+ vardata -> var = basenode ; /* return Var without relabeling */
29792984 vardata -> rel = find_base_rel (root , var -> varno );
29802985 vardata -> atttype = var -> vartype ;
29812986 vardata -> atttypmod = var -> vartypmod ;
@@ -3009,7 +3014,7 @@ examine_variable(Query *root, Node *node, int varRelid,
30093014 * membership. Note that when varRelid isn't zero, only vars of that
30103015 * relation are considered "real" vars.
30113016 */
3012- varnos = pull_varnos (node );
3017+ varnos = pull_varnos (basenode );
30133018
30143019 onerel = NULL ;
30153020
@@ -3024,6 +3029,7 @@ examine_variable(Query *root, Node *node, int varRelid,
30243029 onerel = find_base_rel (root ,
30253030 (varRelid ? varRelid : bms_singleton_member (varnos )));
30263031 vardata -> rel = onerel ;
3032+ node = basenode ; /* strip any relabeling */
30273033 }
30283034 /* else treat it as a constant */
30293035 break ;
@@ -3032,11 +3038,13 @@ examine_variable(Query *root, Node *node, int varRelid,
30323038 {
30333039 /* treat it as a variable of a join relation */
30343040 vardata -> rel = find_join_rel (root , varnos );
3041+ node = basenode ; /* strip any relabeling */
30353042 }
30363043 else if (bms_is_member (varRelid , varnos ))
30373044 {
30383045 /* ignore the vars belonging to other relations */
30393046 vardata -> rel = find_base_rel (root , varRelid );
3047+ node = basenode ; /* strip any relabeling */
30403048 /* note: no point in expressional-index search here */
30413049 }
30423050 /* else treat it as a constant */
@@ -3045,6 +3053,7 @@ examine_variable(Query *root, Node *node, int varRelid,
30453053
30463054 bms_free (varnos );
30473055
3056+ vardata -> var = node ;
30483057 vardata -> atttype = exprType (node );
30493058 vardata -> atttypmod = exprTypmod (node );
30503059
0 commit comments