]> granicus.if.org Git - postgresql/blobdiff - src/backend/parser/analyze.c
Teach the system how to use hashing for UNION. (INTERSECT/EXCEPT will follow,
[postgresql] / src / backend / parser / analyze.c
index 2cc3f28d20697630f7a3ef392579090b1e49701f..3de232ba71bd18cc587641ed2bffd84eb7bea685 100644 (file)
@@ -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);
                }