11
11
* Portions Copyright (c) 1994, Regents of the University of California
12
12
*
13
13
* 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 $
15
15
*
16
16
*-------------------------------------------------------------------------
17
17
*/
25
25
#include "optimizer/tlist.h"
26
26
#include "optimizer/var.h"
27
27
#include "parser/parsetree.h"
28
+ #include "parser/parse_expr.h"
28
29
#include "parser/parse_func.h"
29
30
#include "utils/lsyscache.h"
30
31
#include "utils/memutils.h"
31
32
32
33
33
- static PathKeyItem * makePathKeyItem (Node * key , Oid sortop );
34
+ static PathKeyItem * makePathKeyItem (Node * key , Oid sortop , bool checkType );
34
35
static List * make_canonical_pathkey (Query * root , PathKeyItem * item );
35
36
static Var * find_indexkey_var (Query * root , RelOptInfo * rel ,
36
37
AttrNumber varattno );
@@ -41,10 +42,29 @@ static Var *find_indexkey_var(Query *root, RelOptInfo *rel,
41
42
* create a PathKeyItem node
42
43
*/
43
44
static PathKeyItem *
44
- makePathKeyItem (Node * key , Oid sortop )
45
+ makePathKeyItem (Node * key , Oid sortop , bool checkType )
45
46
{
46
47
PathKeyItem * item = makeNode (PathKeyItem );
47
48
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
+
48
68
item -> key = key ;
49
69
item -> sortop = sortop ;
50
70
return item ;
@@ -70,9 +90,11 @@ add_equijoined_keys(Query *root, RestrictInfo *restrictinfo)
70
90
{
71
91
Expr * clause = restrictinfo -> clause ;
72
92
PathKeyItem * item1 = makePathKeyItem (get_leftop (clause ),
73
- restrictinfo -> left_sortop );
93
+ restrictinfo -> left_sortop ,
94
+ false);
74
95
PathKeyItem * item2 = makePathKeyItem (get_rightop (clause ),
75
- restrictinfo -> right_sortop );
96
+ restrictinfo -> right_sortop ,
97
+ false);
76
98
List * newset ,
77
99
* cursetlink ;
78
100
@@ -668,7 +690,7 @@ build_index_pathkeys(Query *root,
668
690
}
669
691
670
692
/* OK, make a sublist for this sort key */
671
- item = makePathKeyItem (indexkey , sortop );
693
+ item = makePathKeyItem (indexkey , sortop , true );
672
694
cpathkey = make_canonical_pathkey (root , item );
673
695
674
696
/*
@@ -785,7 +807,8 @@ build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery)
785
807
tle -> resdom -> restypmod ,
786
808
0 );
787
809
outer_item = makePathKeyItem ((Node * ) outer_var ,
788
- sub_item -> sortop );
810
+ sub_item -> sortop ,
811
+ true);
789
812
/* score = # of mergejoin peers */
790
813
score = count_canonical_peers (root , outer_item );
791
814
/* +1 if it matches the proper query_pathkeys item */
@@ -893,7 +916,7 @@ make_pathkeys_for_sortclauses(List *sortclauses,
893
916
PathKeyItem * pathkey ;
894
917
895
918
sortkey = get_sortgroupclause_expr (sortcl , tlist );
896
- pathkey = makePathKeyItem (sortkey , sortcl -> sortop );
919
+ pathkey = makePathKeyItem (sortkey , sortcl -> sortop , true );
897
920
898
921
/*
899
922
* The pathkey becomes a one-element sublist, for now;
@@ -937,15 +960,15 @@ cache_mergeclause_pathkeys(Query *root, RestrictInfo *restrictinfo)
937
960
{
938
961
oldcontext = MemoryContextSwitchTo (GetMemoryChunkContext (restrictinfo ));
939
962
key = get_leftop (restrictinfo -> clause );
940
- item = makePathKeyItem (key , restrictinfo -> left_sortop );
963
+ item = makePathKeyItem (key , restrictinfo -> left_sortop , false );
941
964
restrictinfo -> left_pathkey = make_canonical_pathkey (root , item );
942
965
MemoryContextSwitchTo (oldcontext );
943
966
}
944
967
if (restrictinfo -> right_pathkey == NIL )
945
968
{
946
969
oldcontext = MemoryContextSwitchTo (GetMemoryChunkContext (restrictinfo ));
947
970
key = get_rightop (restrictinfo -> clause );
948
- item = makePathKeyItem (key , restrictinfo -> right_sortop );
971
+ item = makePathKeyItem (key , restrictinfo -> right_sortop , false );
949
972
restrictinfo -> right_pathkey = make_canonical_pathkey (root , item );
950
973
MemoryContextSwitchTo (oldcontext );
951
974
}
0 commit comments