From 600c958a302a3c48b6ee1d4c472eeed4f0fcd392 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Sun, 11 Jan 1998 03:41:57 +0000
Subject: [PATCH] Add UNION, GROUP, DISTINCT to INSERT.

---
 src/backend/parser/analyze.c   | 22 ++++++++++++++++++++--
 src/backend/parser/gram.y      | 23 +++++++++++++++++------
 src/include/nodes/parsenodes.h |  7 ++++++-
 src/man/insert.l               |  4 +++-
 4 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index d806ec2059c..dcb9eecb5db 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.63 1998/01/10 04:29:47 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.64 1998/01/11 03:41:35 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -241,7 +241,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
 	/* set up a range table */
 	makeRangeTable(pstate, stmt->relname, stmt->fromClause);
 
-	qry->uniqueFlag = NULL;
+	qry->uniqueFlag = stmt->unique;
 
 	/* fix the target list */
 	icolumns = pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
@@ -315,13 +315,31 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
 	/* fix where clause */
 	qry->qual = transformWhereClause(pstate, stmt->whereClause);
 
+	/* check having clause */
+	if (stmt->havingClause)
+		elog(NOTICE, "HAVING not yet supported; ignore clause", NULL);
+
 	/* now the range table will not change */
 	qry->rtable = pstate->p_rtable;
 	qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
 
+	qry->groupClause = transformGroupClause(pstate,
+											stmt->groupClause,
+											qry->targetList);
+
+	/* fix order clause */
+	qry->sortClause = transformSortClause(pstate,
+										  NIL,
+										  NIL,
+										  qry->targetList,
+										  qry->uniqueFlag);
+
 	if (pstate->p_numAgg > 0)
 		finalizeAggregates(pstate, qry);
 
+	qry->unionall = stmt->unionall;	/* in child, so unionClause may be false */
+	qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList);
+
 	return (Query *) qry;
 }
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index d79fa91bd42..38513e4cd96 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.88 1998/01/10 04:29:50 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.89 1998/01/11 03:41:38 momjian Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -2146,16 +2146,27 @@ InsertStmt:  INSERT INTO relation_name opt_column_list insert_rest
 insert_rest:  VALUES '(' res_target_list2 ')'
 				{
 					$$ = makeNode(InsertStmt);
+					$$->unique = NULL;
 					$$->targetList = $3;
 					$$->fromClause = NIL;
-					$$->whereClause = NULL;
+					$$->whereClause = NIL;
+					$$->groupClause = NIL;
+					$$->havingClause = NIL;
+					$$->unionClause = NIL;
 				}
-		| SELECT res_target_list2 from_clause where_clause
+		| SELECT opt_unique res_target_list2
+			 from_clause where_clause
+			 group_clause having_clause
+			 union_clause
 				{
 					$$ = makeNode(InsertStmt);
-					$$->targetList = $2;
-					$$->fromClause = $3;
-					$$->whereClause = $4;
+					$$->unique = $2;
+					$$->targetList = $3;
+					$$->fromClause = $4;
+					$$->whereClause = $5;
+					$$->groupClause = $6;
+					$$->havingClause = $7;
+					$$->unionClause = $8;
 				}
 		;
 
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 9bc99568573..65718fc6e16 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.42 1998/01/10 04:30:11 momjian Exp $
+ * $Id: parsenodes.h,v 1.43 1998/01/11 03:41:49 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -574,10 +574,15 @@ typedef struct InsertStmt
 {
 	NodeTag		type;
 	char	   *relname;		/* relation to insert into */
+	char	   *unique;			/* NULL, '*', or unique attribute name */
 	List	   *cols;			/* names of the columns */
 	List	   *targetList;		/* the target list (of ResTarget) */
 	List	   *fromClause;		/* the from clause */
 	Node	   *whereClause;	/* qualifications */
+	List	   *groupClause;	/* group by clause */
+	Node	   *havingClause;	/* having conditional-expression */
+	List	   *unionClause;	/* union subselect parameters */
+	bool		unionall;		/* union without unique sort */
 } InsertStmt;
 
 /* ----------------------
diff --git a/src/man/insert.l b/src/man/insert.l
index 51624cf9786..0b1fa87f45c 100644
--- a/src/man/insert.l
+++ b/src/man/insert.l
@@ -1,6 +1,6 @@
 .\" This is -*-nroff-*-
 .\" XXX standard disclaimer belongs here....
-.\" $Header: /cvsroot/pgsql/src/man/Attic/insert.l,v 1.5 1997/09/27 03:14:19 momjian Exp $
+.\" $Header: /cvsroot/pgsql/src/man/Attic/insert.l,v 1.6 1998/01/11 03:41:57 momjian Exp $
 .TH INSERT SQL 11/05/95 PostgreSQL PostgreSQL
 .SH NAME
 insert \(em insert tuples to a relation
@@ -11,6 +11,8 @@ insert \(em insert tuples to a relation
 	{\fBvalues\fR (expression1 [,expression-i] ) |
     \fBselect\fR expression1 [,expression-i]
 	[\fBfrom\fR from-list] [\fBwhere\fR qual] 
+    [\fBgroup by\fR attr_name1 {, attr_name-i....}]
+	[\fBunion {all} select\fR ...]
 .fi
 .SH DESCRIPTION
 .BR Insert
-- 
GitLab