|
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.77 2006/07/14 14:52:20 momjian Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.78 2006/08/17 17:02:49 tgl Exp $ |
15 | 15 | *
|
16 | 16 | *-------------------------------------------------------------------------
|
17 | 17 | */
|
@@ -1059,39 +1059,73 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
|
1059 | 1059 | {
|
1060 | 1060 | PathKeyItem*sub_item= (PathKeyItem*)lfirst(j);
|
1061 | 1061 | Node*sub_key=sub_item->key;
|
| 1062 | +Expr*rtarg; |
1062 | 1063 | ListCell*k;
|
1063 | 1064 |
|
| 1065 | +/* |
| 1066 | + * We handle two cases: the sub_pathkey key can be either an exact |
| 1067 | + * match for a targetlist entry, or a RelabelType of a targetlist |
| 1068 | + * entry. (The latter case is worth extra code because it arises |
| 1069 | + * frequently in connection with varchar fields.) |
| 1070 | + */ |
| 1071 | +if (IsA(sub_key,RelabelType)) |
| 1072 | +rtarg= ((RelabelType*)sub_key)->arg; |
| 1073 | +else |
| 1074 | +rtarg=NULL; |
| 1075 | + |
1064 | 1076 | foreach(k,sub_tlist)
|
1065 | 1077 | {
|
1066 | 1078 | TargetEntry*tle= (TargetEntry*)lfirst(k);
|
| 1079 | +Node*outer_expr; |
| 1080 | +PathKeyItem*outer_item; |
| 1081 | +intscore; |
1067 | 1082 |
|
1068 |
| -if (!tle->resjunk&& |
1069 |
| -equal(tle->expr,sub_key)) |
| 1083 | +/* resjunk items aren't visible to outer query */ |
| 1084 | +if (tle->resjunk) |
| 1085 | +continue; |
| 1086 | + |
| 1087 | +if (equal(tle->expr,sub_key)) |
1070 | 1088 | {
|
1071 |
| -/* Found a representation for this sub_key */ |
1072 |
| -Var*outer_var; |
1073 |
| -PathKeyItem*outer_item; |
1074 |
| -intscore; |
1075 |
| - |
1076 |
| -outer_var=makeVar(rel->relid, |
1077 |
| -tle->resno, |
1078 |
| -exprType((Node*)tle->expr), |
1079 |
| -exprTypmod((Node*)tle->expr), |
1080 |
| -0); |
1081 |
| -outer_item=makePathKeyItem((Node*)outer_var, |
1082 |
| -sub_item->sortop, |
1083 |
| - true); |
1084 |
| -/* score = # of mergejoin peers */ |
1085 |
| -score=count_canonical_peers(root,outer_item); |
1086 |
| -/* +1 if it matches the proper query_pathkeys item */ |
1087 |
| -if (retvallen<outer_query_keys&& |
1088 |
| -list_member(list_nth(root->query_pathkeys,retvallen),outer_item)) |
1089 |
| -score++; |
1090 |
| -if (score>best_score) |
1091 |
| -{ |
1092 |
| -best_item=outer_item; |
1093 |
| -best_score=score; |
1094 |
| -} |
| 1089 | +/* Exact match */ |
| 1090 | +outer_expr= (Node*) |
| 1091 | +makeVar(rel->relid, |
| 1092 | +tle->resno, |
| 1093 | +exprType((Node*)tle->expr), |
| 1094 | +exprTypmod((Node*)tle->expr), |
| 1095 | +0); |
| 1096 | +} |
| 1097 | +elseif (rtarg&&equal(tle->expr,rtarg)) |
| 1098 | +{ |
| 1099 | +/* Match after discarding RelabelType */ |
| 1100 | +outer_expr= (Node*) |
| 1101 | +makeVar(rel->relid, |
| 1102 | +tle->resno, |
| 1103 | +exprType((Node*)tle->expr), |
| 1104 | +exprTypmod((Node*)tle->expr), |
| 1105 | +0); |
| 1106 | +outer_expr= (Node*) |
| 1107 | +makeRelabelType((Expr*)outer_expr, |
| 1108 | +((RelabelType*)sub_key)->resulttype, |
| 1109 | +((RelabelType*)sub_key)->resulttypmod, |
| 1110 | +((RelabelType*)sub_key)->relabelformat); |
| 1111 | +} |
| 1112 | +else |
| 1113 | +continue; |
| 1114 | + |
| 1115 | +/* Found a representation for this sub_key */ |
| 1116 | +outer_item=makePathKeyItem(outer_expr, |
| 1117 | +sub_item->sortop, |
| 1118 | + true); |
| 1119 | +/* score = # of mergejoin peers */ |
| 1120 | +score=count_canonical_peers(root,outer_item); |
| 1121 | +/* +1 if it matches the proper query_pathkeys item */ |
| 1122 | +if (retvallen<outer_query_keys&& |
| 1123 | +list_member(list_nth(root->query_pathkeys,retvallen),outer_item)) |
| 1124 | +score++; |
| 1125 | +if (score>best_score) |
| 1126 | +{ |
| 1127 | +best_item=outer_item; |
| 1128 | +best_score=score; |
1095 | 1129 | }
|
1096 | 1130 | }
|
1097 | 1131 | }
|
|