From: Tom Lane Date: Sun, 23 Jan 2005 02:24:30 +0000 (+0000) Subject: The result of a FULL or RIGHT join can't be assumed to be sorted by the X-Git-Tag: REL7_3_9~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=48a1dc0d5c2c6a572d1b5e20e1985fa565f90177;p=thirdparty%2Fpostgresql.git The result of a FULL or RIGHT join can't be assumed to be sorted by the left input's sorting, because null rows may be inserted at various points. Per report from Ferenc Lutischá¸n. --- diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 8e73bd2f419..55375664fd8 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.71 2002/09/04 20:31:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.71.2.1 2005/01/23 02:24:16 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -253,7 +253,8 @@ sort_inner_and_outer(Query *root, cur_mergeclauses, innerrel); /* Build pathkeys representing output sort order. */ - merge_pathkeys = build_join_pathkeys(root, joinrel, outerkeys); + merge_pathkeys = build_join_pathkeys(root, joinrel, jointype, + outerkeys); /* * And now we can make the path. We only consider the cheapest- @@ -371,7 +372,7 @@ match_unsorted_outer(Query *root, * as a nestloop, and even if some of the mergeclauses are * implemented by qpquals rather than as true mergeclauses): */ - merge_pathkeys = build_join_pathkeys(root, joinrel, + merge_pathkeys = build_join_pathkeys(root, joinrel, jointype, outerpath->pathkeys); if (nestjoinOK) diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index 350c761165b..70f4092ed92 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -11,7 +11,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.41 2002/09/18 21:35:21 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.41.2.1 2005/01/23 02:24:16 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -623,7 +623,12 @@ find_indexkey_var(Query *root, RelOptInfo *rel, AttrNumber varattno) * vars they were joined with; furthermore, it doesn't matter what kind * of join algorithm is actually used. * + * EXCEPTION: in a FULL or RIGHT join, we cannot treat the result as + * having the outer path's path keys, because null lefthand rows may be + * inserted at random points. It must be treated as unsorted. + * * 'joinrel' is the join relation that paths are being formed for + * 'jointype' is the join type (inner, left, full, etc) * 'outer_pathkeys' is the list of the current outer path's path keys * * Returns the list of new path keys. @@ -631,8 +636,12 @@ find_indexkey_var(Query *root, RelOptInfo *rel, AttrNumber varattno) List * build_join_pathkeys(Query *root, RelOptInfo *joinrel, + JoinType jointype, List *outer_pathkeys) { + if (jointype == JOIN_FULL || jointype == JOIN_RIGHT) + return NIL; + /* * This used to be quite a complex bit of code, but now that all * pathkey sublists start out life canonicalized, we don't have to do diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index 4222c77ad97..26d9273d327 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: paths.h,v 1.60 2002/06/20 20:29:51 momjian Exp $ + * $Id: paths.h,v 1.60.2.1 2005/01/23 02:24:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -112,6 +112,7 @@ extern List *build_index_pathkeys(Query *root, RelOptInfo *rel, ScanDirection scandir); extern List *build_join_pathkeys(Query *root, RelOptInfo *joinrel, + JoinType jointype, List *outer_pathkeys); extern List *make_pathkeys_for_sortclauses(List *sortclauses, List *tlist);