diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-08-07 01:11:52 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-08-07 01:11:52 +0000 |
commit | 2d1d96b1cea8f67a095e8f28372af4081605f681 (patch) | |
tree | 91be573dfa6eacbe8a4421d700af3fadc3d1bda8 /src/backend/parser/analyze.c | |
parent | 3d40d5e70ebe21b7d52467987bffad8aea16f29b (diff) | |
download | postgresql-2d1d96b1cea8f67a095e8f28372af4081605f681.tar.gz postgresql-2d1d96b1cea8f67a095e8f28372af4081605f681.zip |
Teach the system how to use hashing for UNION. (INTERSECT/EXCEPT will follow,
but seem like a separate patch since most of the remaining work is on the
executor side.) I took the opportunity to push selection of the grouping
operators for set operations into the parser where it belongs. Otherwise this
is just a small exercise in making prepunion.c consider both alternatives.
As with the recent DISTINCT patch, this means we can UNION on datatypes that
can hash but not sort, and it means that UNION without ORDER BY is no longer
certain to produce sorted output.
Diffstat (limited to 'src/backend/parser/analyze.c')
-rw-r--r-- | src/backend/parser/analyze.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 2cc3f28d206..3de232ba71b 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -17,7 +17,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.375 2008/08/02 21:32:00 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.376 2008/08/07 01:11:51 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -33,6 +33,7 @@ #include "parser/parse_clause.h" #include "parser/parse_coerce.h" #include "parser/parse_expr.h" +#include "parser/parse_oper.h" #include "parser/parse_relation.h" #include "parser/parse_target.h" #include "parser/parsetree.h" @@ -1326,6 +1327,7 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt) op->colTypes = NIL; op->colTypmods = NIL; + op->groupClauses = NIL; /* don't have a "foreach4", so chase two of the lists by hand */ lcm = list_head(lcoltypmods); rcm = list_head(rcoltypmods); @@ -1349,6 +1351,31 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt) op->colTypes = lappend_oid(op->colTypes, rescoltype); op->colTypmods = lappend_int(op->colTypmods, rescoltypmod); + /* + * For all cases except UNION ALL, identify the grouping operators + * (and, if available, sorting operators) that will be used to + * eliminate duplicates. + */ + if (op->op != SETOP_UNION || !op->all) + { + SortGroupClause *grpcl = makeNode(SortGroupClause); + Oid sortop; + Oid eqop; + + /* determine the eqop and optional sortop */ + get_sort_group_operators(rescoltype, + false, true, false, + &sortop, &eqop, NULL); + + /* we don't have a tlist yet, so can't assign sortgrouprefs */ + grpcl->tleSortGroupRef = 0; + grpcl->eqop = eqop; + grpcl->sortop = sortop; + grpcl->nulls_first = false; /* OK with or without sortop */ + + op->groupClauses = lappend(op->groupClauses, grpcl); + } + lcm = lnext(lcm); rcm = lnext(rcm); } |