|
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.86 2007/10/27 05:45:43 tgl Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.87 2007/11/02 18:54:15 tgl Exp $ |
15 | 15 | * |
16 | 16 | *------------------------------------------------------------------------- |
17 | 17 | */ |
@@ -277,6 +277,30 @@ make_pathkey_from_sortinfo(PlannerInfo *root, |
277 | 277 | elog(ERROR, "could not find opfamilies for ordering operator %u", |
278 | 278 | ordering_op); |
279 | 279 |
|
| 280 | + /* |
| 281 | + * When dealing with binary-compatible opclasses, we have to ensure that |
| 282 | + * the exposed type of the expression tree matches the declared input |
| 283 | + * type of the opclass, except when that is a polymorphic type |
| 284 | + * (compare the behavior of parse_coerce.c). This ensures that we can |
| 285 | + * correctly match the indexkey or sortclause expression to other |
| 286 | + * expressions we find in the query, because arguments of ordinary |
| 287 | + * operator expressions will be cast that way. (We have to do this |
| 288 | + * for indexkeys because they are represented without any explicit |
| 289 | + * relabel in pg_index, and for sort clauses because the parser is |
| 290 | + * likewise cavalier about putting relabels on them.) |
| 291 | + */ |
| 292 | + if (exprType((Node *) expr) != opcintype && |
| 293 | + !IsPolymorphicType(opcintype)) |
| 294 | + { |
| 295 | + /* Strip any existing RelabelType, and add a new one */ |
| 296 | + while (expr && IsA(expr, RelabelType)) |
| 297 | + expr = (Expr *) ((RelabelType *) expr)->arg; |
| 298 | + expr = (Expr *) makeRelabelType(expr, |
| 299 | + opcintype, |
| 300 | + -1, |
| 301 | + COERCE_DONTCARE); |
| 302 | + } |
| 303 | + |
280 | 304 | /* Now find or create a matching EquivalenceClass */ |
281 | 305 | eclass = get_eclass_for_sort_expr(root, expr, opcintype, opfamilies); |
282 | 306 |
|
@@ -495,27 +519,6 @@ build_index_pathkeys(PlannerInfo *root, |
495 | 519 | indexprs_item = lnext(indexprs_item); |
496 | 520 | } |
497 | 521 |
|
498 | | - /* |
499 | | - * When dealing with binary-compatible indexes, we have to ensure that |
500 | | - * the exposed type of the expression tree matches the declared input |
501 | | - * type of the opclass, except when that is a polymorphic type |
502 | | - * (compare the behavior of parse_coerce.c). This ensures that we can |
503 | | - * correctly match the indexkey expression to expressions we find in |
504 | | - * the query, because arguments of operators that could match the |
505 | | - * index will be cast likewise. |
506 | | - */ |
507 | | - if (exprType((Node *) indexkey) != index->opcintype[i] && |
508 | | - !IsPolymorphicType(index->opcintype[i])) |
509 | | - { |
510 | | - /* Strip any existing RelabelType, and add a new one */ |
511 | | - while (indexkey && IsA(indexkey, RelabelType)) |
512 | | - indexkey = (Expr *) ((RelabelType *) indexkey)->arg; |
513 | | - indexkey = (Expr *) makeRelabelType(indexkey, |
514 | | - index->opcintype[i], |
515 | | - -1, |
516 | | - COERCE_DONTCARE); |
517 | | - } |
518 | | - |
519 | 522 | /* OK, make a canonical pathkey for this sort key */ |
520 | 523 | cpathkey = make_pathkey_from_sortinfo(root, |
521 | 524 | indexkey, |
|
0 commit comments