diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 35107c8af20e08c5acfcb08e8d72c4f01e0de204..1437c2e8c9c4d12561485f3f554bfc94660fa7be 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.45 1998/02/27 08:43:52 vadim Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.46 1998/05/21 03:53:50 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -521,14 +521,16 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
 	 *	  NOTE: in the future we might want to initialize the junk
 	 *	  filter for all queries.
 	 * ----------------
+	 *        SELECT added by daveh@insightdist.com  5/20/98 to allow 
+	 *        ORDER/GROUP BY have an identifier missing from the target.
 	 */
 	if (operation == CMD_UPDATE || operation == CMD_DELETE ||
-		operation == CMD_INSERT)
+		operation == CMD_INSERT || operation == CMD_SELECT)
 	{
-
 		JunkFilter *j = (JunkFilter *) ExecInitJunkFilter(targetList);
-
 		estate->es_junkFilter = j;
+
+		tupType = j->jf_cleanTupType;       /*  Added by daveh@insightdist.com  5/20/98   */
 	}
 	else
 		estate->es_junkFilter = NULL;
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 30be8335351c217dbe1b3e8272c72ec493f98697..06c7cdee5f284af25107c6a2d0ef81ec1d88b6c1 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.15 1998/03/31 04:43:53 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.16 1998/05/21 03:53:50 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -182,6 +182,37 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
 			}
 		}
 	}
+
+	/*    BEGIN add missing target entry hack.
+	 *
+	 *    Prior to this hack, this function returned NIL if no target_result.
+	 *    Thus, ORDER/GROUP BY required the attributes be in the target list.
+	 *    Now it constructs a new target entry which is appended to the end of
+	 *    the target list.   This target is set to be  resjunk = TRUE so that
+	 *    it will not be projected into the final tuple.
+	 *          daveh@insightdist.com    5/20/98
+	 */  
+	if ( ! target_result)  {  
+		List   *p_target = tlist;
+		Ident *missingTargetId = (Ident *)makeNode(Ident);
+		TargetEntry *tent = makeNode(TargetEntry);
+		
+		/*   Fill in the constructed Ident node   */
+		missingTargetId->type = T_Ident;
+		missingTargetId->name = palloc(strlen(sortgroupby->name) + 1);
+		strcpy(missingTargetId->name, sortgroupby->name);
+
+		transformTargetId(pstate, missingTargetId, tent, missingTargetId->name, TRUE);
+
+		/* Add to the end of the target list */
+		while (lnext(p_target) != NIL)  {
+			p_target = lnext(p_target);
+		}
+		lnext(p_target) = lcons(tent, NIL);
+		target_result = tent;
+	}
+	/*    END add missing target entry hack.   */
+
 	return target_result;
 }
 
@@ -203,10 +234,6 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
 		Resdom	   *resdom;
 
 		restarget = find_targetlist_entry(pstate, lfirst(grouplist), targetlist);
-
-		if (restarget == NULL)
-			elog(ERROR, "The field being grouped by must appear in the target list");
-
 		grpcl->entry = restarget;
 		resdom = restarget->resdom;
 		grpcl->grpOpoid = oprid(oper("<",
@@ -262,9 +289,6 @@ transformSortClause(ParseState *pstate,
 
 
 		restarget = find_targetlist_entry(pstate, sortby, targetlist);
-		if (restarget == NULL)
-			elog(ERROR, "The field being ordered by must appear in the target list");
-
 		sortcl->resdom = resdom = restarget->resdom;
 		sortcl->opoid = oprid(oper(sortby->useOp,
 								   resdom->restype,
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index e3d5654ec4a9ac28dd4907facbefbbb2b24c5455..e76fa1829e32437af2e5ce1d263233a2ccfd57c5 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.12 1998/05/09 23:29:54 thomas Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.13 1998/05/21 03:53:51 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -52,6 +52,51 @@ coerce_target_expr(ParseState *pstate,
 				   Oid type_id,
 				   Oid attrtype);
 
+
+/*
+ *   transformTargetId - transforms an Ident Node to a Target Entry
+ *   Created this a function to allow the ORDER/GROUP BY clause be able 
+ *   to construct a TargetEntry from an Ident.
+ *
+ *   resjunk = TRUE will hide the target entry in the final result tuple.
+ *        daveh@insightdist.com     5/20/98
+ */
+void
+transformTargetId(ParseState *pstate,
+				Ident *ident,
+				TargetEntry *tent,
+				char *resname,
+				int16 resjunk)
+{
+	Node   *expr;
+	Oid	type_id;
+	int16	type_mod;
+
+	/*
+	 * here we want to look for column names only, not
+	 * relation names (even though they can be stored in
+	 * Ident nodes, too)
+	 */
+	expr = transformIdent(pstate, (Node *) ident, EXPR_COLUMN_FIRST);
+	type_id = exprType(expr);
+	if (nodeTag(expr) == T_Var)
+		type_mod = ((Var *) expr)->vartypmod;
+	else
+		type_mod = -1;
+	tent->resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
+							  (Oid) type_id,
+							  type_mod,
+							  resname,
+							  (Index) 0,
+							  (Oid) 0,
+							  resjunk);
+
+	tent->expr = expr;
+	return;
+}
+
+
+
 /*
  * transformTargetList -
  *	  turns a list of ResTarget's into a list of TargetEntry's
@@ -71,36 +116,13 @@ transformTargetList(ParseState *pstate, List *targetlist)
 		{
 			case T_Ident:
 				{
-					Node	   *expr;
-					Oid			type_id;
-					int16		type_mod;
 					char	   *identname;
 					char	   *resname;
 
 					identname = ((Ident *) res->val)->name;
 					handleTargetColname(pstate, &res->name, NULL, identname);
-
-					/*
-					 * here we want to look for column names only, not
-					 * relation names (even though they can be stored in
-					 * Ident nodes, too)
-					 */
-					expr = transformIdent(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
-					type_id = exprType(expr);
-					if (nodeTag(expr) == T_Var)
-						type_mod = ((Var *) expr)->vartypmod;
-					else
-						type_mod = -1;
 					resname = (res->name) ? res->name : identname;
-					tent->resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
-											  (Oid) type_id,
-											  type_mod,
-											  resname,
-											  (Index) 0,
-											  (Oid) 0,
-											  0);
-
-					tent->expr = expr;
+					transformTargetId(pstate, (Ident*)res->val, tent, resname, FALSE);
 					break;
 				}
 			case T_ParamNo:
diff --git a/src/include/parser/parse_target.h b/src/include/parser/parse_target.h
index 98dd31f68c30f3a4514d456a8d29806e42107df6..cb75d61615e37e4326fb525476aae0575bccb907 100644
--- a/src/include/parser/parse_target.h
+++ b/src/include/parser/parse_target.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_target.h,v 1.4 1998/02/26 04:42:49 momjian Exp $
+ * $Id: parse_target.h,v 1.5 1998/05/21 03:53:51 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -24,5 +24,7 @@
 
 extern List *transformTargetList(ParseState *pstate, List *targetlist);
 extern List *makeTargetNames(ParseState *pstate, List *cols);
+extern void transformTargetId(ParseState *pstate, Ident *ident,
+	TargetEntry *tent, char *resname, int16 resjunk);
 
 #endif							/* PARSE_TARGET_H */