1111 * Portions Copyright (c) 1994, Regents of the University of California
1212 *
1313 * IDENTIFICATION
14- * $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.54 2003/11/29 19:51:50 pgsql Exp $
14+ * $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.55 2003/12/03 17:45:07 tgl Exp $
1515 *
1616 *-------------------------------------------------------------------------
1717 */
2525#include "optimizer/tlist.h"
2626#include "optimizer/var.h"
2727#include "parser/parsetree.h"
28+ #include "parser/parse_expr.h"
2829#include "parser/parse_func.h"
2930#include "utils/lsyscache.h"
3031#include "utils/memutils.h"
3132
3233
33- static PathKeyItem * makePathKeyItem (Node * key ,Oid sortop );
34+ static PathKeyItem * makePathKeyItem (Node * key ,Oid sortop , bool checkType );
3435static List * make_canonical_pathkey (Query * root ,PathKeyItem * item );
3536static Var * find_indexkey_var (Query * root ,RelOptInfo * rel ,
3637AttrNumber varattno );
@@ -41,10 +42,29 @@ static Var *find_indexkey_var(Query *root, RelOptInfo *rel,
4142 *create a PathKeyItem node
4243 */
4344static PathKeyItem *
44- makePathKeyItem (Node * key ,Oid sortop )
45+ makePathKeyItem (Node * key ,Oid sortop , bool checkType )
4546{
4647PathKeyItem * item = makeNode (PathKeyItem );
4748
49+ /*
50+ * Some callers pass expressions that are not necessarily of the same
51+ * type as the sort operator expects as input (for example when dealing
52+ * with an index that uses binary-compatible operators). We must relabel
53+ * these with the correct type so that the key expressions will be seen
54+ * as equal() to expressions that have been correctly labeled.
55+ */
56+ if (checkType )
57+ {
58+ Oid lefttype ,
59+ righttype ;
60+
61+ op_input_types (sortop ,& lefttype ,& righttype );
62+ if (exprType (key )!= lefttype )
63+ key = (Node * )makeRelabelType ((Expr * )key ,
64+ lefttype ,-1 ,
65+ COERCE_DONTCARE );
66+ }
67+
4868item -> key = key ;
4969item -> sortop = sortop ;
5070return item ;
@@ -70,9 +90,11 @@ add_equijoined_keys(Query *root, RestrictInfo *restrictinfo)
7090{
7191Expr * clause = restrictinfo -> clause ;
7292PathKeyItem * item1 = makePathKeyItem (get_leftop (clause ),
73- restrictinfo -> left_sortop );
93+ restrictinfo -> left_sortop ,
94+ false);
7495PathKeyItem * item2 = makePathKeyItem (get_rightop (clause ),
75- restrictinfo -> right_sortop );
96+ restrictinfo -> right_sortop ,
97+ false);
7698List * newset ,
7799* cursetlink ;
78100
@@ -668,7 +690,7 @@ build_index_pathkeys(Query *root,
668690}
669691
670692/* OK, make a sublist for this sort key */
671- item = makePathKeyItem (indexkey ,sortop );
693+ item = makePathKeyItem (indexkey ,sortop , true );
672694cpathkey = make_canonical_pathkey (root ,item );
673695
674696/*
@@ -785,7 +807,8 @@ build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery)
785807tle -> resdom -> restypmod ,
7868080 );
787809outer_item = makePathKeyItem ((Node * )outer_var ,
788- sub_item -> sortop );
810+ sub_item -> sortop ,
811+ true);
789812/* score = # of mergejoin peers */
790813score = count_canonical_peers (root ,outer_item );
791814/* +1 if it matches the proper query_pathkeys item */
@@ -893,7 +916,7 @@ make_pathkeys_for_sortclauses(List *sortclauses,
893916PathKeyItem * pathkey ;
894917
895918sortkey = get_sortgroupclause_expr (sortcl ,tlist );
896- pathkey = makePathKeyItem (sortkey ,sortcl -> sortop );
919+ pathkey = makePathKeyItem (sortkey ,sortcl -> sortop , true );
897920
898921/*
899922 * The pathkey becomes a one-element sublist, for now;
@@ -937,15 +960,15 @@ cache_mergeclause_pathkeys(Query *root, RestrictInfo *restrictinfo)
937960{
938961oldcontext = MemoryContextSwitchTo (GetMemoryChunkContext (restrictinfo ));
939962key = get_leftop (restrictinfo -> clause );
940- item = makePathKeyItem (key ,restrictinfo -> left_sortop );
963+ item = makePathKeyItem (key ,restrictinfo -> left_sortop , false );
941964restrictinfo -> left_pathkey = make_canonical_pathkey (root ,item );
942965MemoryContextSwitchTo (oldcontext );
943966}
944967if (restrictinfo -> right_pathkey == NIL )
945968{
946969oldcontext = MemoryContextSwitchTo (GetMemoryChunkContext (restrictinfo ));
947970key = get_rightop (restrictinfo -> clause );
948- item = makePathKeyItem (key ,restrictinfo -> right_sortop );
971+ item = makePathKeyItem (key ,restrictinfo -> right_sortop , false );
949972restrictinfo -> right_pathkey = make_canonical_pathkey (root ,item );
950973MemoryContextSwitchTo (oldcontext );
951974}