|
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