diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 9b02eb7f0e21892bff96466db3e9cca3656b4c36..7368548465de59df15386d5199b380c47445d43a 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.25 1998/01/19 02:37:33 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.26 1998/01/20 05:03:30 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -51,6 +51,7 @@
 #include "optimizer/clauses.h"
 #include "utils/palloc.h"
 #include "utils/mcxt.h"
+#include "utils/lsyscache.h"
 #include "commands/command.h"
 #include "catalog/index.h"
 #include "catalog/catname.h"
@@ -1207,15 +1208,11 @@ setAtttypmodForCreateTable(TupleDesc tupType, List *targetList,
 			{
 				Var		   *var;
 				RangeTblEntry *rtentry;
-				Relation	rd;
 
 				var = (Var *) expr;
 				rtentry = rt_fetch(var->varnoold, rangeTable);
-				rd = heap_open(rtentry->relid);
-				/* set length to that defined in relation */
 				tupType->attrs[varno]->atttypmod =
-					(*rd->rd_att->attrs[var->varoattno - 1]).atttypmod;
-				heap_close(rd);
+					get_atttypmod(rtentry->relid, var->varoattno);
 			}
 			else
 				elog(ERROR, "setAtttypmodForCreateTable: can't get atttypmod for field (for length, etc.)");
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 3f12cbd2c3a820c0639faa99c1541d2e638bc82b..d6cc4cd5470c27a0faeb0f49051b668529e5b017 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.33 1998/01/19 18:10:48 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.34 1998/01/20 05:03:40 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -908,7 +908,7 @@ _copySubLink(SubLink *from)
 	newnode->subLinkType = from->subLinkType;
 	newnode->useor = from->useor;
 	Node_Copy(from, newnode, lefthand);
-	newnode->oper = listCopy(from->oper);
+	Node_Copy(from, newnode, oper);
 	Node_Copy(from, newnode, subselect);
 
 	return newnode;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 23f6372866275b3f2736d8982279422ac43943dc..d7ede89e65c49dc49d635b45e3f9120aea46c712 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.24 1998/01/19 18:10:50 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.25 1998/01/20 05:03:49 momjian Exp $
  *
  * NOTES
  *	  Every (plan) node in POSTGRES has an associated "out" routine which
@@ -771,7 +771,7 @@ _outSubLink(StringInfo str, SubLink *node)
 	appendStringInfo(str, " :lefthand ");
 	_outNode(str, node->lefthand);
 	appendStringInfo(str, " :oper ");
-	_outIntList(str, node->oper);
+	_outNode(str, node->oper);
 	appendStringInfo(str, " :subselect ");
 	_outNode(str, node->subselect);
 }
diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c
index 861733cb36265302d853f461b8732a7a800c16af..4ac0ee06838171b243b44d00f0380fb1eafa8e6d 100644
--- a/src/backend/nodes/print.c
+++ b/src/backend/nodes/print.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.13 1998/01/07 15:32:29 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.14 1998/01/20 05:03:54 momjian Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -187,15 +187,11 @@ print_expr(Node *expr, List *rtable)
 				break;
 			default:
 				{
-					Relation	r;
-
 					rt = rt_fetch(var->varno, rtable);
 					relname = rt->relname;
-					r = heap_openr(relname);
 					if (rt->refname)
 						relname = rt->refname;	/* table renamed */
-					attname = attnumAttName(r, var->varattno);
-					heap_close(r);
+					attname = get_attname(rt->relid, var->varattno);
 				}
 				break;
 		}
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 297cdec1418ab5eb202055b87c6a41ca47fc1dea..2860bad174a6a1945d9d1cf41039f4152b9d59e4 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.20 1998/01/19 18:10:52 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.21 1998/01/20 05:03:57 momjian Exp $
  *
  * NOTES
  *	  Most of the read functions for plan nodes are tested. (In fact, they
@@ -1182,7 +1182,7 @@ _readSubLink()
 	local_node->lefthand = nodeRead(true);		/* now read it */
 
 	token = lsptok(NULL, &length);		/* eat :oper */
-	local_node->oper = toIntList(nodeRead(true));		/* now read it */
+	local_node->oper = nodeRead(true);		/* now read it */
 
 	token = lsptok(NULL, &length);		/* eat :subselect */
 	local_node->subselect = nodeRead(true);		/* now read it */
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 5fc0bb1ac3688c2b38af1ae62465f3e7b39edbc3..077215138f71e41f94f732753ae33227eea05646 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.66 1998/01/19 05:06:13 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.67 1998/01/20 05:04:05 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -67,6 +67,9 @@ parse_analyze(List *pl, ParseState *parentParseState)
 	{
 		pstate = make_parsestate(parentParseState);
 		result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
+		if (pstate->p_target_relation != NULL)
+			heap_close(pstate->p_target_relation);
+
 		if (extras != NIL)
 		{
 			result->len += length(extras);
@@ -74,13 +77,13 @@ parse_analyze(List *pl, ParseState *parentParseState)
 			while (extras != NIL)
 			{
 				result->qtrees[i++] = transformStmt(pstate, lfirst(extras));
+				if (pstate->p_target_relation != NULL)
+					heap_close(pstate->p_target_relation);
 				extras = lnext(extras);
 			}
 		}
 		extras = NIL;
 		pl = lnext(pl);
-		if (pstate->p_target_relation != NULL)
-			heap_close(pstate->p_target_relation);
 		pfree(pstate);
 	}
 
@@ -99,10 +102,10 @@ transformStmt(ParseState *pstate, Node *parseTree)
 
 	switch (nodeTag(parseTree))
 	{
-			/*------------------------
-			 *	Non-optimizable statements
-			 *------------------------
-			 */
+		/*------------------------
+		 *	Non-optimizable statements
+		 *------------------------
+		 */
 		case T_CreateStmt:
 			result = transformCreateStmt(pstate, (CreateStmt *) parseTree);
 			break;
@@ -159,10 +162,10 @@ transformStmt(ParseState *pstate, Node *parseTree)
 			}
 			break;
 
-			/*------------------------
-			 *	Optimizable statements
-			 *------------------------
-			 */
+		/*------------------------
+		 *	Optimizable statements
+		 *------------------------
+		 */
 		case T_InsertStmt:
 			result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
 			break;
@@ -186,7 +189,7 @@ transformStmt(ParseState *pstate, Node *parseTree)
 
 			/*
 			 * other statments don't require any transformation-- just
-			 * return the original parsetree
+			 * return the original parsetree, yea!
 			 */
 			result = makeNode(Query);
 			result->commandType = CMD_UTILITY;
@@ -218,7 +221,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
 	qry->rtable = pstate->p_rtable;
 	qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
 
-	/* make sure we don't have aggregates in the where clause */
+	qry->hasAggs = pstate->p_hasAggs;
 	if (pstate->p_hasAggs)
 		parseCheckAggregates(pstate, qry);
 
@@ -258,7 +261,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
 		int						ndef = pstate->p_target_relation->rd_att->constr->num_defval;
 		
 		/* 
-		 * if stmt->cols == NIL then makeTargetNames returns list of all 
+		 * if stmt->cols == NIL then makeTargetNames returns list of all
 		 * attrs: have to shorter icolumns list...
 		 */
 		if (stmt->cols == NIL)
@@ -315,10 +318,6 @@ 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);
@@ -334,21 +333,21 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
 										  qry->targetList,
 										  qry->uniqueFlag);
 
+	qry->hasAggs = pstate->p_hasAggs;
 	if (pstate->p_hasAggs)
-		finalizeAggregates(pstate, qry);
+		parseCheckAggregates(pstate, qry);
 
+	/* The INSERT INTO ... SELECT ... could have a UNION */
 	qry->unionall = stmt->unionall;	/* in child, so unionClause may be false */
 	qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList);
 
 	return (Query *) qry;
 }
 
-/* makeTableName()
- * Create a table name from a list of fields.
+/*
+ *	makeTableName()
+ *	Create a table name from a list of fields.
  */
-static char *
-makeTableName(void *elem,...);
-
 static char *
 makeTableName(void *elem,...)
 {
@@ -357,7 +356,7 @@ makeTableName(void *elem,...)
 	char   *name;
 	char	buf[NAMEDATALEN+1];
 
-	strcpy(buf,"");
+	buf[0] = '\0';
 
 	va_start(args,elem);
 
@@ -368,7 +367,8 @@ makeTableName(void *elem,...)
 		if ((strlen(buf)+strlen(name)) >= (sizeof(buf)-1))
 			return (NULL);
 
-		if (strlen(buf) > 0) strcat(buf,"_");
+		if (strlen(buf) > 0)
+			strcat(buf,"_");
 		strcat(buf,name);
 
 		name = va_arg(args,void *);
@@ -380,12 +380,9 @@ makeTableName(void *elem,...)
 	strcpy(name,buf);
 
 	return (name);
-} /* makeTableName() */
-
-char *
-CreateIndexName(char *tname, char *cname, char *label, List *indices);
+}
 
-char *
+static char *
 CreateIndexName(char *tname, char *cname, char *label, List *indices)
 {
 	int			pass = 0;
@@ -403,17 +400,10 @@ CreateIndexName(char *tname, char *cname, char *label, List *indices)
 		if (iname == NULL)
 			break;
 
-#if PARSEDEBUG
-printf("CreateNameIndex- check %s against indices\n",iname);
-#endif
-
 		ilist = indices;
 		while (ilist != NIL)
 		{
 			index = lfirst(ilist);
-#if PARSEDEBUG
-printf("CreateNameIndex- compare %s with existing index %s\n",iname,index->idxname);
-#endif
 			if (strcasecmp(iname,index->idxname) == 0)
 				break;
 
@@ -431,7 +421,7 @@ printf("CreateNameIndex- compare %s with existing index %s\n",iname,index->idxna
 	}
 
 	return (iname);
-} /* CreateIndexName() */
+}
 
 /*
  * transformCreateStmt -
@@ -475,15 +465,9 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
 		{
 			case T_ColumnDef:
 				column = (ColumnDef *) element;
-#if PARSEDEBUG
-printf("transformCreateStmt- found column %s\n",column->colname);
-#endif
 				columns = lappend(columns,column);
 				if (column->constraints != NIL)
 				{
-#if PARSEDEBUG
-printf("transformCreateStmt- found constraint(s) on column %s\n",column->colname);
-#endif
 					clist = column->constraints;
 					while (clist != NIL)
 					{
@@ -491,9 +475,6 @@ printf("transformCreateStmt- found constraint(s) on column %s\n",column->colname
 						switch (constraint->contype)
 						{
 							case CONSTR_NOTNULL:
-#if PARSEDEBUG
-printf("transformCreateStmt- found NOT NULL constraint on column %s\n",column->colname);
-#endif
 								if (column->is_not_null)
 									elog(ERROR,"CREATE TABLE/NOT NULL already specified"
 										" for %s.%s", stmt->relname, column->colname);
@@ -501,9 +482,6 @@ printf("transformCreateStmt- found NOT NULL constraint on column %s\n",column->c
 								break;
 
 							case CONSTR_DEFAULT:
-#if PARSEDEBUG
-printf("transformCreateStmt- found DEFAULT clause on column %s\n",column->colname);
-#endif
 								if (column->defval != NULL)
 									elog(ERROR,"CREATE TABLE/DEFAULT multiple values specified"
 										" for %s.%s", stmt->relname, column->colname);
@@ -511,9 +489,6 @@ printf("transformCreateStmt- found DEFAULT clause on column %s\n",column->colnam
 								break;
 
 							case CONSTR_PRIMARY:
-#if PARSEDEBUG
-printf("transformCreateStmt- found PRIMARY KEY clause on column %s\n",column->colname);
-#endif
 								if (constraint->name == NULL)
 									constraint->name = makeTableName(stmt->relname, "pkey", NULL);
 								if (constraint->keys == NIL)
@@ -522,9 +497,6 @@ printf("transformCreateStmt- found PRIMARY KEY clause on column %s\n",column->co
 								break;
 
 							case CONSTR_UNIQUE:
-#if PARSEDEBUG
-printf("transformCreateStmt- found UNIQUE clause on column %s\n",column->colname);
-#endif
 								if (constraint->name == NULL)
 									constraint->name = makeTableName(stmt->relname, column->colname, "key", NULL);
 								if (constraint->keys == NIL)
@@ -533,9 +505,6 @@ printf("transformCreateStmt- found UNIQUE clause on column %s\n",column->colname
 								break;
 
 							case CONSTR_CHECK:
-#if PARSEDEBUG
-printf("transformCreateStmt- found CHECK clause on column %s\n",column->colname);
-#endif
 								constraints = lappend(constraints, constraint);
 								if (constraint->name == NULL)
 									constraint->name = makeTableName(stmt->relname, column->colname, NULL);
@@ -552,24 +521,15 @@ printf("transformCreateStmt- found CHECK clause on column %s\n",column->colname)
 
 			case T_Constraint:
 				constraint = (Constraint *) element;
-#if PARSEDEBUG
-printf("transformCreateStmt- found constraint %s\n", ((constraint->name != NULL)? constraint->name: "(unknown)"));
-#endif
 				switch (constraint->contype)
 				{
 					case CONSTR_PRIMARY:
-#if PARSEDEBUG
-printf("transformCreateStmt- found PRIMARY KEY clause\n");
-#endif
 						if (constraint->name == NULL)
 							constraint->name = makeTableName(stmt->relname, "pkey", NULL);
 						dlist = lappend(dlist, constraint);
 						break;
 
 					case CONSTR_UNIQUE:
-#if PARSEDEBUG
-printf("transformCreateStmt- found UNIQUE clause\n");
-#endif
 #if FALSE
 						if (constraint->name == NULL)
 							constraint->name = makeTableName(stmt->relname, "key", NULL);
@@ -578,9 +538,6 @@ printf("transformCreateStmt- found UNIQUE clause\n");
 						break;
 
 					case CONSTR_CHECK:
-#if PARSEDEBUG
-printf("transformCreateStmt- found CHECK clause\n");
-#endif
 						constraints = lappend(constraints, constraint);
 						break;
 
@@ -620,11 +577,6 @@ printf("transformCreateStmt- found CHECK clause\n");
 		if (nodeTag(constraint) != T_Constraint)
 			elog(ERROR,"parser: internal error; unrecognized deferred node",NULL);
 
-#if PARSEDEBUG
-printf("transformCreateStmt- found deferred constraint %s\n",
- ((constraint->name != NULL)? constraint->name: "(unknown)"));
-#endif
-
 		if (constraint->contype == CONSTR_PRIMARY)
 			if (have_pkey)
 				elog(ERROR,"CREATE TABLE/PRIMARY KEY multiple primary keys"
@@ -634,11 +586,6 @@ printf("transformCreateStmt- found deferred constraint %s\n",
 		else if (constraint->contype != CONSTR_UNIQUE)
 			elog(ERROR,"parser: internal error; unrecognized deferred constraint",NULL);
 
-#if PARSEDEBUG
-printf("transformCreateStmt- found deferred %s clause\n",
- (constraint->contype == CONSTR_PRIMARY? "PRIMARY KEY": "UNIQUE"));
-#endif
-
 		index = makeNode(IndexStmt);
 
 		index->unique = TRUE;
@@ -665,17 +612,11 @@ printf("transformCreateStmt- found deferred %s clause\n",
 		while (keys != NIL)
 		{
 			key = lfirst(keys);
-#if PARSEDEBUG
-printf("transformCreateStmt- check key %s for column match\n", key->name);
-#endif
 			columns = stmt->tableElts;
 			column = NULL;
 			while (columns != NIL)
 			{
 				column = lfirst(columns);
-#if PARSEDEBUG
-printf("transformCreateStmt- check column %s for key match\n", column->colname);
-#endif
 				if (strcasecmp(column->colname,key->name) == 0) break;
 				else column = NULL;
 				columns = lnext(columns);
@@ -684,12 +625,7 @@ printf("transformCreateStmt- check column %s for key match\n", column->colname);
 				elog(ERROR,"parser: column '%s' in key does not exist",key->name);
 
 			if (constraint->contype == CONSTR_PRIMARY)
-			{
-#if PARSEDEBUG
-printf("transformCreateStmt- mark column %s as NOT NULL\n", column->colname);
-#endif
 				column->is_not_null = TRUE;
-			}
 			iparam = makeNode(IndexElem);
 			iparam->name = strcpy(palloc(strlen(column->colname)+1), column->colname);
 			iparam->args = NIL;
@@ -719,7 +655,7 @@ printf("transformCreateStmt- mark column %s as NOT NULL\n", column->colname);
 	extras = ilist;
 
 	return q;
-} /* transformCreateStmt() */
+}
 
 /*
  * transformIndexStmt -
@@ -830,17 +766,10 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
 	qry->into = stmt->into;
 	qry->isPortal = FALSE;
 
-	/* fix the target list */
 	qry->targetList = transformTargetList(pstate, stmt->targetList);
 
-	/* fix where clause */
 	qry->qual = transformWhereClause(pstate, stmt->whereClause);
 
-	/* check having clause */
-	if (stmt->havingClause)
-		elog(NOTICE, "HAVING not yet supported; ignore clause", NULL);
-
-	/* fix order clause */
 	qry->sortClause = transformSortClause(pstate,
 										  stmt->sortClause,
 										  NIL,
@@ -852,8 +781,9 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
 											qry->targetList);
 	qry->rtable = pstate->p_rtable;
 
+	qry->hasAggs = pstate->p_hasAggs;
 	if (pstate->p_hasAggs)
-		finalizeAggregates(pstate, qry);
+		parseCheckAggregates(pstate, qry);
 
 	qry->unionall = stmt->unionall;	/* in child, so unionClause may be false */
 	qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList);
@@ -880,19 +810,15 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
 	 */
 	makeRangeTable(pstate, stmt->relname, stmt->fromClause);
 
-	/* fix the target list */
 	qry->targetList = transformTargetList(pstate, stmt->targetList);
 
-	/* fix where clause */
 	qry->qual = transformWhereClause(pstate, stmt->whereClause);
 
 	qry->rtable = pstate->p_rtable;
-	qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
 
-	if (pstate->p_hasAggs)
-		finalizeAggregates(pstate, qry);
+	qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
 
-	/* make sure we don't have aggregates in the where clause */
+	qry->hasAggs = pstate->p_hasAggs;
 	if (pstate->p_hasAggs)
 		parseCheckAggregates(pstate, qry);
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 244c834568693184421f2f8f951d02d0ae764134..e259fbeca82bdf348e0fa4b7bf797e2a6201e558 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.94 1998/01/19 05:06:15 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.95 1998/01/20 05:04:07 momjian Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -278,7 +278,7 @@ Oid	param_type(int t); /* used in parse_expr.c */
 		INDEX, INHERITS, INSTEAD, ISNULL,
 		LANCOMPILER, LISTEN, LOAD, LOCATION, MERGE, MOVE,
 		NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
-		RECIPE, RENAME, REPLACE, RESET, RETRIEVE, RETURNS, RULE,
+		RECIPE, RENAME, REPLACE, RESET, RETURNS, RULE,
 		SEQUENCE, SETOF, SHOW, STDIN, STDOUT, TRUSTED, 
 		VACUUM, VERBOSE, VERSION
 
@@ -2446,7 +2446,11 @@ groupby:  ColId
 				}
 		;
 
-having_clause:  HAVING a_expr					{ $$ = $2; }
+having_clause:  HAVING a_expr
+				{
+					elog(NOTICE, "HAVING not yet supported; ignore clause");
+					$$ = $2;
+				}
 		| /*EMPTY*/								{ $$ = NULL; }
 		;
 
@@ -3637,7 +3641,7 @@ res_target_el:  ColId opt_indirection '=' a_expr_or_null
 
 /*
 ** target list for select.
-** should get rid of the other but is still needed by the defunct retrieve into
+** should get rid of the other but is still needed by the defunct select into
 ** and update (uses a subset)
 */
 res_target_list2:  res_target_list2 ',' res_target_el2
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index 3049689aa1ee3f854bf250c30f14cf0e21625715..904d71a43f98a770e5cb07056049ac8c6a83e137 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.30 1998/01/19 05:06:16 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.31 1998/01/20 05:04:09 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -167,7 +167,6 @@ static ScanKeyword ScanKeywords[] = {
 	{"rename", RENAME},
 	{"replace", REPLACE},
 	{"reset", RESET},
-	{"retrieve", RETRIEVE},
 	{"returns", RETURNS},
 	{"revoke", REVOKE},
 	{"right", RIGHT},
@@ -235,22 +234,3 @@ ScanKeywordLookup(char *text)
 
 	return (NULL);
 }
-
-#ifdef NOT_USED
-char	   *
-AtomValueGetString(int atomval)
-{
-	ScanKeyword *low = &ScanKeywords[0];
-	ScanKeyword *high = endof(ScanKeywords) - 1;
-	int			keyword_list_length = (high - low);
-	int			i;
-
-	for (i = 0; i < keyword_list_length; i++)
-		if (ScanKeywords[i].value == atomval)
-			return (ScanKeywords[i].name);
-
-	elog(ERROR, "AtomGetString called with bogus atom # : %d", atomval);
-	return (NULL);
-}
-
-#endif
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index 15413ecb7390873f121612d373ad0c8ebf38a0ba..8474d2be41180747612e31d4d28113adf087ab1d 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.7 1998/01/15 18:59:59 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.8 1998/01/20 05:04:11 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,19 +34,6 @@ static bool contain_agg_clause(Node *clause);
 static bool exprIsAggOrGroupCol(Node *expr, List *groupClause);
 static bool tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause);
 
-/*
- * finalizeAggregates -
- *	  fill in hasAggs from pstate. Also checks to make sure that aggregates
- *	  are used in the proper place.
- */
-void
-finalizeAggregates(ParseState *pstate, Query *qry)
-{
-	parseCheckAggregates(pstate, qry);
-
-	qry->hasAggs = pstate->p_hasAggs;
-}
-
 /*
  * contain_agg_clause--
  *	  Recursively find aggreg nodes from a clause.
@@ -247,9 +234,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
 									  ObjectIdGetDatum(basetype),
 									  0, 0);
 	if (!HeapTupleIsValid(theAggTuple))
-	{
 		elog(ERROR, "aggregate %s does not exist", aggname);
-	}
 
 	/*
 	 *	We do a major hack for count(*) here.
@@ -267,7 +252,10 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
 	 *	range table entry, and pick the first column from the table.
 	 *	We set a flag to count nulls, because we could have nulls in
 	 *	that column.
-	*/
+	 *
+	 *	It's an ugly job, but someone has to do it.
+	 *	bjm 1998/1/18
+	 */
 		
 	if (nodeTag(lfirst(target)) == T_Const)
 	{
@@ -275,7 +263,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
 		
 		if (con->consttype == UNKNOWNOID && VARSIZE(con->constvalue) == VARHDRSZ)
 		{
-			Attr *attr = makeNode(Attr);
+			Attr 		*attr = makeNode(Attr);
 			List	   *rtable, *rlist;
 			RangeTblEntry *first_valid_rte;
 
@@ -295,7 +283,7 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
 				if (!rte->inFromCl && rte != pstate->p_target_rangetblentry)
 					continue;
 
-				first_valid_rte =rte;
+				first_valid_rte = rte;
 				break;
 			}
 			if (first_valid_rte == NULL)
@@ -314,7 +302,6 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
 	fintype = aggform->aggfinaltype;
 	xfn1 = aggform->aggtransfn1;
 
-	
 	/* only aggregates with transfn1 need a base type */
 	if (OidIsValid(xfn1))
 	{
@@ -374,4 +361,3 @@ agg_error(char *caller, char *aggname, Oid basetypeID)
 			 typeidTypeName(basetypeID));
 	}
 }
-
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 71aaf24423886d49d552c266a41436c20d7e0f00..115b8c153d79c27b409ebde7f9031e5799937844 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.9 1998/01/19 05:06:17 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.10 1998/01/20 05:04:12 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,7 +53,6 @@ makeRangeTable(ParseState *pstate, char *relname, List *frmList)
 	pstate->p_target_rangetblentry = rte;
 	Assert(pstate->p_target_relation == NULL);
 	pstate->p_target_relation = heap_open(rte->relid);
-	Assert(pstate->p_target_relation != NULL);
 	/* will close relation later */
 }
 
@@ -68,11 +67,12 @@ transformWhereClause(ParseState *pstate, Node *a_expr)
 	Node	   *qual;
 
 	if (a_expr == NULL)
-		return (Node *) NULL;	/* no qualifiers */
+		return NULL;	/* no qualifiers */
 
 	pstate->p_in_where_clause = true;
 	qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST);
 	pstate->p_in_where_clause = false;
+
 	if (exprType(qual) != BOOLOID)
 	{
 		elog(ERROR,
@@ -88,7 +88,7 @@ transformWhereClause(ParseState *pstate, Node *a_expr)
  *	  range table. The range table may grow as we transform the expressions
  *	  in the target list. (Note that this happens because in POSTQUEL, we
  *	  allow references to relations not specified in the from-clause. We
- *	  also allow that in our POST-SQL)
+ *	  also allow now as an extension.)
  *
  */
 static void
@@ -148,11 +148,6 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
 		char	   *resname = resnode->resname;
 		int			test_rtable_pos = var->varno;
 
-#ifdef PARSEDEBUG
-		printf("find_targetlist_entry- target name is %s, position %d, resno %d\n",
-			   (sortgroupby->name ? sortgroupby->name : "(null)"), target_pos + 1, sortgroupby->resno);
-#endif
-
 		if (!sortgroupby->name)
 		{
 			if (sortgroupby->resno == ++target_pos)
@@ -345,10 +340,8 @@ transformSortClause(ParseState *pstate,
 					break;
 			}
 			if (i == NIL)
-			{
 				elog(ERROR, "The field specified in the UNIQUE ON clause is not in the targetlist");
-			}
-			s = sortlist;
+				
 			foreach(s, sortlist)
 			{
 				SortClause *sortcl = lfirst(s);
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index e321a8517e5c401b29c0660299a0905555a554b0..ef42a61fe29867c10f9d6e01b900ad2709f3be81 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.10 1998/01/19 18:10:56 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.11 1998/01/20 05:04:14 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -55,8 +55,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 				Attr	   *att = (Attr *) expr;
 				Node	   *temp;
 
-				/* what if att.attrs == "*"?? */
-				temp = handleNestedDots(pstate, att, &pstate->p_last_resno,
+				/* what if att.attrs == "*"? */
+				temp = ParseNestedFuncOrColumn(pstate, att, &pstate->p_last_resno,
 										precedence);
 				if (att->indirection != NIL)
 				{
@@ -77,11 +77,6 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 							if (exprType(lexpr) != INT4OID)
 								elog(ERROR, "array index expressions must be int4's");
 						}
-#if 0
-						pfree(ai->uidx);
-						if (ai->lidx != NULL)
-							pfree(ai->lidx);
-#endif
 						ai->lidx = lexpr;
 						ai->uidx = uexpr;
 
@@ -106,13 +101,9 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 				Value	   *val = &con->val;
 
 				if (con->typename != NULL)
-				{
-					result = parser_typecast(val, con->typename, -1);
-				}
+					result = parser_typecast(val, con->typename, 0);
 				else
-				{
 					result = (Node *) make_const(val);
-				}
 				break;
 			}
 		case T_ParamNo:
@@ -125,9 +116,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 				paramno = pno->number;
 				toid = param_type(paramno);
 				if (!OidIsValid(toid))
-				{
 					elog(ERROR, "Parameter '$%d' is out of range", paramno);
-				}
 				param = makeNode(Param);
 				param->paramkind = PARAM_NUM;
 				param->paramid = (AttrNumber) paramno;
@@ -156,7 +145,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 						{
 							Node	   *lexpr = transformExpr(pstate, a->lexpr, precedence);
 
-							result = ParseFunc(pstate,
+							result = ParseFuncOrColumn(pstate,
 										  "nullvalue", lcons(lexpr, NIL),
 											   &pstate->p_last_resno,
 											   precedence);
@@ -166,7 +155,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 						{
 							Node	   *lexpr = transformExpr(pstate, a->lexpr, precedence);
 
-							result = ParseFunc(pstate,
+							result = ParseFuncOrColumn(pstate,
 									   "nonnullvalue", lcons(lexpr, NIL),
 											   &pstate->p_last_resno,
 											   precedence);
@@ -229,7 +218,6 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 			}
 		case T_Ident:
 			{
-
 				/*
 				 * look for a column name or a relation name (the default
 				 * behavior)
@@ -245,7 +233,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 				/* transform the list of arguments */
 				foreach(args, fn->args)
 					lfirst(args) = transformExpr(pstate, (Node *) lfirst(args), precedence);
-				result = ParseFunc(pstate,
+				result = ParseFuncOrColumn(pstate,
 						  fn->funcname, fn->args, &pstate->p_last_resno,
 						  precedence);
 				break;
@@ -272,22 +260,21 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 				{
 					char *op = lfirst(sublink->oper);
 					List *left_expr = sublink->lefthand;
-  					List *right_expr = subselect->targetList;
-  					List *elist;
-  
+					List *right_expr = subselect->targetList;
+					List *elist;
+
 					sublink->oper = NIL;
-  					foreach(elist, left_expr)
-  					{
+					foreach(elist, left_expr)
+					{
 						Node	   *lexpr = lfirst(elist);
-  						Node	   *rexpr = lfirst(right_expr);
-  						TargetEntry *tent = (TargetEntry *)rexpr;
-  						Expr	   *op_expr;						
-  
-  						op_expr = make_op(op, lexpr, tent->expr);
-						sublink->oper = lappendi(sublink->oper,
-								((Oper *)op_expr->oper)->opno);
-  						right_expr = lnext(right_expr);
-  					}
+						Node	   *rexpr = lfirst(right_expr);
+					TargetEntry *tent = (TargetEntry *)rexpr;
+						Expr	   *op_expr;						
+
+						op_expr = make_op(op, lexpr, tent->expr);
+						sublink->oper = lappend(sublink->oper, op_expr->oper);
+						right_expr = lnext(right_expr);
+					}
 					result = (Node *) expr;
 				}
 				break;
@@ -320,7 +307,7 @@ transformIdent(ParseState *pstate, Node *expr, int precedence)
 		att->relname = rte->refname;
 		att->attrs = lcons(makeString(ident->name), NIL);
 		column_result =
-			(Node *) handleNestedDots(pstate, att, &pstate->p_last_resno,
+			(Node *) ParseNestedFuncOrColumn(pstate, att, &pstate->p_last_resno,
 								precedence);
 	}
 
@@ -403,51 +390,6 @@ exprType(Node *expr)
 	return type;
 }
 
-/*
- ** HandleNestedDots --
- **    Given a nested dot expression (i.e. (relation func ... attr), build up
- ** a tree with of Iter and Func nodes.
- */
-Node *
-handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno, int precedence)
-{
-	List	   *mutator_iter;
-	Node	   *retval = NULL;
-
-	if (attr->paramNo != NULL)
-	{
-		Param	   *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST);
-
-		retval =
-			ParseFunc(pstate, strVal(lfirst(attr->attrs)),
-					  lcons(param, NIL),
-					  curr_resno,
-					  precedence);
-	}
-	else
-	{
-		Ident	   *ident = makeNode(Ident);
-
-		ident->name = attr->relname;
-		ident->isRel = TRUE;
-		retval =
-			ParseFunc(pstate, strVal(lfirst(attr->attrs)),
-					  lcons(ident, NIL),
-					  curr_resno,
-					  precedence);
-	}
-
-	foreach(mutator_iter, lnext(attr->attrs))
-	{
-		retval = ParseFunc(pstate, strVal(lfirst(mutator_iter)),
-						   lcons(retval, NIL),
-						   curr_resno,
-						   precedence);
-	}
-
-	return (retval);
-}
-
 static Node	   *
 parser_typecast(Value *expr, TypeName *typename, int atttypmod)
 {
@@ -489,69 +431,10 @@ parser_typecast(Value *expr, TypeName *typename, int atttypmod)
 
 	len = typeLen(tp);
 
-#if 0							/* fix me */
-	switch (CInteger(lfirst(expr)))
-	{
-		case INT4OID:			/* int4 */
-			const_string = (char *) palloc(256);
-			string_palloced = true;
-			sprintf(const_string, "%d", ((Const *) lnext(expr))->constvalue);
-			break;
-
-		case NAMEOID:			/* char16 */
-			const_string = (char *) palloc(256);
-			string_palloced = true;
-			sprintf(const_string, "%s", ((Const *) lnext(expr))->constvalue);
-			break;
-
-		case CHAROID:			/* char */
-			const_string = (char *) palloc(256);
-			string_palloced = true;
-			sprintf(const_string, "%c", ((Const) lnext(expr))->constvalue);
-			break;
-
-		case FLOAT8OID: /* float8 */
-			const_string = (char *) palloc(256);
-			string_palloced = true;
-			sprintf(const_string, "%f", ((Const) lnext(expr))->constvalue);
-			break;
-
-		case CASHOID:			/* money */
-			const_string = (char *) palloc(256);
-			string_palloced = true;
-			sprintf(const_string, "%d",
-					(int) ((Const *) expr)->constvalue);
-			break;
-
-		case TEXTOID:			/* text */
-			const_string = DatumGetPointer(((Const) lnext(expr))->constvalue);
-			const_string = (char *) textout((struct varlena *) const_string);
-			break;
-
-		case UNKNOWNOID:		/* unknown */
-			const_string = DatumGetPointer(((Const) lnext(expr))->constvalue);
-			const_string = (char *) textout((struct varlena *) const_string);
-			break;
-
-		default:
-			elog(ERROR, "unknown type %d", CInteger(lfirst(expr)));
-	}
-#endif
-
 	cp = stringTypeString(tp, const_string, atttypmod);
 
 	if (!typeByVal(tp))
-	{
-/*
-		if (len >= 0 && len != PSIZE(cp)) {
-			char *pp;
-			pp = (char *) palloc(len);
-			memmove(pp, cp, len);
-			cp = pp;
-		}
-*/
 		lcp = PointerGetDatum(cp);
-	}
 	else
 	{
 		switch (len)
@@ -676,17 +559,7 @@ parser_typecast2(Node *expr, Oid exprType, Type tp, int atttypmod)
 	cp = stringTypeString(tp, const_string, atttypmod);
 
 	if (!typeByVal(tp))
-	{
-/*
-		if (len >= 0 && len != PSIZE(cp)) {
-			char *pp;
-			pp = (char *) palloc(len);
-			memmove(pp, cp, len);
-			cp = pp;
-		}
-*/
 		lcp = PointerGetDatum(cp);
-	}
 	else
 	{
 		switch (len)
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 76782fc7ad90f406b7b278bc813b089a8db4de61..e8466fa62640a92700c9d9281e5219960a032530 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.6 1998/01/15 19:00:02 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.7 1998/01/20 05:04:16 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,6 +34,7 @@
 #include "parser/parse_func.h"
 #include "parser/parse_node.h"
 #include "parser/parse_relation.h"
+#include "parser/parse_target.h"
 #include "parser/parse_type.h"
 #include "storage/bufmgr.h"
 #include "storage/lmgr.h"
@@ -83,11 +84,54 @@ typedef struct _SuperQE
 } SuperQE;
 
 /*
- * parse function
+ ** ParseNestedFuncOrColumn --
+ **    Given a nested dot expression (i.e. (relation func ... attr), build up
+ ** a tree with of Iter and Func nodes.
  */
+Node *
+ParseNestedFuncOrColumn(ParseState *pstate, Attr *attr, int *curr_resno, int precedence)
+{
+	List	   *mutator_iter;
+	Node	   *retval = NULL;
+
+	if (attr->paramNo != NULL)
+	{
+		Param	   *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST);
+
+		retval = ParseFuncOrColumn(pstate, strVal(lfirst(attr->attrs)),
+					  lcons(param, NIL),
+					  curr_resno,
+					  precedence);
+	}
+	else
+	{
+		Ident	   *ident = makeNode(Ident);
+
+		ident->name = attr->relname;
+		ident->isRel = TRUE;
+		retval = ParseFuncOrColumn(pstate, strVal(lfirst(attr->attrs)),
+					  lcons(ident, NIL),
+					  curr_resno,
+					  precedence);
+	}
 
+	/* Do more attributes follow this one? */
+	foreach(mutator_iter, lnext(attr->attrs))
+	{
+		retval = ParseFuncOrColumn(pstate, strVal(lfirst(mutator_iter)),
+						   lcons(retval, NIL),
+						   curr_resno,
+						   precedence);
+	}
+
+	return (retval);
+}
+
+/*
+ * parse function
+ */
 Node *
-ParseFunc(ParseState *pstate, char *funcname, List *fargs,
+ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
 		int *curr_resno, int precedence)
 {
 	Oid			rettype = (Oid) 0;
@@ -122,9 +166,10 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs,
 	 * that argument is a relation, param, or PQ function returning a
 	 * complex * type, then the function could be a projection.
 	 */
+	/* We only have one parameter */
 	if (length(fargs) == 1)
 	{
-
+		/* Is is a plain Relation name from the parser? */
 		if (nodeTag(first_arg) == T_Ident && ((Ident *) first_arg)->isRel)
 		{
 			RangeTblEntry *rte;
@@ -150,8 +195,7 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs,
 			{
 				Oid			dummyTypeId;
 
-				return
-					((Node *) make_var(pstate,
+				return ((Node *) make_var(pstate,
 									   refname,
 									   funcname,
 									   &dummyTypeId));
@@ -210,7 +254,7 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs,
 			Oid			basetype;
 
 			/*
-			 * the aggregate count is a special case, ignore its base
+			 * the aggregate COUNT is a special case, ignore its base
 			 * type.  Treat it as zero
 			 */
 			if (strcmp(funcname, "count") == 0)
@@ -280,9 +324,7 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs,
 			 */
 			if (exprType(pair) == UNKNOWNOID &&
 				!IsA(pair, Const))
-			{
-				elog(ERROR, "ParseFunc: no function named '%s' that takes in an unknown type as argument #%d", funcname, nargs);
-			}
+				elog(ERROR, "ParseFuncOrColumn: no function named '%s' that takes in an unknown type as argument #%d", funcname, nargs);
 			else
 				toid = exprType(pair);
 		}
@@ -504,10 +546,8 @@ func_get_candidates(char *funcname, int nargs)
 						palloc(8 * sizeof(Oid));
 					MemSet(current_candidate->args, 0, 8 * sizeof(Oid));
 					for (i = 0; i < nargs; i++)
-					{
 						current_candidate->args[i] =
 							pgProcP->proargtypes[i];
-					}
 
 					current_candidate->next = candidates;
 					candidates = current_candidate;
@@ -1009,7 +1049,7 @@ make_arguments(int nargs,
 /*
  ** setup_tlist --
  **		Build a tlist that says which attribute to project to.
- **		This routine is called by ParseFunc() to set up a target list
+ **		This routine is called by ParseFuncOrColumn() to set up a target list
  **		on a tuple parameter or return value.  Due to a bug in 4.0,
  **		it's not possible to refer to system attributes in this case.
  */
@@ -1264,6 +1304,3 @@ func_error(char *caller, char *funcname, int nargs, Oid *argtypes)
 
 	elog(ERROR, "%s: function %s(%s) does not exist", caller, funcname, p);
 }
-
-
-
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index 03bc54d531ff5b6024f8a2876f3e4dc57c11d1ed..ffcafcedb11fd00622be340c0272912d9510bf57 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.8 1998/01/19 05:06:19 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.9 1998/01/20 05:04:21 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,6 +27,7 @@
 #include "parser/parse_type.h"
 #include "utils/builtins.h"
 #include "utils/syscache.h"
+#include "utils/lsyscache.h"
 
 static void disallow_setop(char *op, Type optype, Node *operand);
 static Node *make_operand(char *opname,
@@ -228,17 +229,11 @@ make_op(char *opname, Node *ltree, Node *rtree)
 	result->oper = (Node *) newop;
 
 	if (!left)
-	{
 		result->args = lcons(right, NIL);
-	}
 	else if (!right)
-	{
 		result->args = lcons(left, NIL);
-	}
 	else
-	{
 		result->args = lcons(left, lcons(right, NIL));
-	}
 
 	return result;
 }
@@ -250,7 +245,6 @@ make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id)
 	int			vnum,
 				attid;
 	Oid			vartypeid;
-	Relation	rd;
 	RangeTblEntry *rte;
 
 	rte = refnameRangeTableEntry(pstate->p_rtable, refname);
@@ -259,16 +253,15 @@ make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id)
 
 	vnum = refnameRangeTablePosn(pstate->p_rtable, refname);
 
-	rd = heap_open(rte->relid);
-
-	attid = attnameAttNum(rd, attrname); /* could elog(ERROR) */
-	vartypeid = attnumTypeId(rd, attid);
+	attid = get_attnum(rte->relid, attrname);
+	if (attid == InvalidAttrNumber)
+		elog(ERROR, "Relation %s does not have attribute %s",
+			 rte->relname, attrname);
+	vartypeid = get_atttype(rte->relid, attid);
 
 	varnode = makeVar(vnum, attid, vartypeid, vnum, attid);
-
-	heap_close(rd);
-
 	*type_id = vartypeid;
+
 	return varnode;
 }
 
@@ -311,10 +304,8 @@ make_array_ref(Node *expr,
 	type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
 
 	if (type_struct_array->typelem == InvalidOid)
-	{
 		elog(ERROR, "make_array_ref: type %s is not an array",
 			 (Name) &(type_struct_array->typname.data[0]));
-	}
 
 	/* get the type tuple for the element type */
 	type_tuple = SearchSysCacheTuple(TYPOID,
@@ -331,13 +322,11 @@ make_array_ref(Node *expr,
 		A_Indices  *ind = lfirst(indirection);
 
 		if (ind->lidx)
-		{
-
 			/*
 			 * XXX assumes all lower indices non null in this case
 			 */
 			lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
-		}
+
 		upperIndexpr = lappend(upperIndexpr, ind->uidx);
 		indirection = lnext(indirection);
 	}
@@ -393,10 +382,8 @@ make_array_set(Expr *target_expr,
 	type_struct_array = (TypeTupleForm) GETSTRUCT(type_tuple);
 
 	if (type_struct_array->typelem == InvalidOid)
-	{
 		elog(ERROR, "make_array_ref: type %s is not an array",
 			 (Name) &(type_struct_array->typname.data[0]));
-	}
 	/* get the type tuple for the element type */
 	type_tuple = SearchSysCacheTuple(TYPOID,
 							ObjectIdGetDatum(type_struct_array->typelem),
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 253fed7ced4af44a7365ef26bc41c672e4220421..ded519a72b8448b2552491bbdb347ca9541ddcdb 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.7 1998/01/16 23:20:20 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.8 1998/01/20 05:04:23 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -540,23 +540,6 @@ left_oper(char *op, Oid arg)
 	return ((Operator) tup);
 }
 
-/* Given a typename and value, returns the ascii form of the value */
-
-#ifdef NOT_USED
-char	   *
-outstr(char *typename,			/* Name of type of value */
-	   char *value)				/* Could be of any type */
-{
-	TypeTupleForm tp;
-	Oid			op;
-
-	tp = (TypeTupleForm) GETSTRUCT(type(typename));
-	op = tp->typoutput;
-	return ((char *) fmgr(op, value));
-}
-
-#endif
-
 /*
  * Give a somewhat useful error message when the operator for two types
  * is not found.
@@ -598,4 +581,3 @@ op_error(char *op, Oid arg1, Oid arg2)
 		"\n\tor you will have to define the operator using CREATE OPERATOR",
 		op, typeTypeName(tp1), typeTypeName(tp2));
 }
-
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 692b1eb116ee4febef9d0748415575d68062a056..5009b0326bdadffcd96ca01eecd3c609c30d877a 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.6 1998/01/16 23:20:21 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.7 1998/01/20 05:04:24 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -97,7 +97,7 @@ refnameRangeTablePosn(List *rtable, char *refname)
 			return index;
 		index++;
 	}
-	return (0);
+	return 0;
 }
 
 /*
@@ -162,10 +162,12 @@ addRangeTableEntry(ParseState *pstate,
 
 	relation = heap_openr(relname);
 	if (relation == NULL)
-	{
 		elog(ERROR, "%s: %s",
-			 relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]);
-	}
+				relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]);
+
+	rte->relid = RelationGetRelationId(relation);
+
+	heap_close(relation);
 
 	/*
 	 * Flags - zero or more from inheritance,union,version or
@@ -175,8 +177,6 @@ addRangeTableEntry(ParseState *pstate,
 	rte->inh = inh;
 
 	/* RelOID */
-	rte->relid = RelationGetRelationId(relation);
-
 	rte->inFromCl = inFromCl;
 
 	/*
@@ -185,8 +185,6 @@ addRangeTableEntry(ParseState *pstate,
 	if (pstate != NULL)
 		pstate->p_rtable = lappend(pstate->p_rtable, rte);
 
-	heap_close(relation);
-
 	return rte;
 }
 
@@ -215,11 +213,9 @@ expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno)
 	rdesc = heap_open(rte->relid);
 
 	if (rdesc == NULL)
-	{
 		elog(ERROR, "Unable to expand all -- heap_open failed on %s",
 			 rte->refname);
-		return NIL;
-	}
+
 	maxattrs = RelationGetNumberOfAttributes(rdesc);
 
 	for (varattno = 0; varattno <= maxattrs - 1; varattno++)
@@ -256,10 +252,17 @@ expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno)
 	}
 
 	heap_close(rdesc);
+
 	return (te_head);
 }
 
-/* given relation and att name, return id of variable */
+/*
+ *	given relation and att name, return id of variable
+ *
+ *	This should only be used if the relation is already
+ *	heap_open()'ed.  Use the cache version get_attnum()
+ *	for access to non-opened relations.
+ */
 int
 attnameAttNum(Relation rd, char *a)
 {
@@ -279,10 +282,15 @@ attnameAttNum(Relation rd, char *a)
 	return 0;  /* lint */
 }
 
-/* Given range variable, return whether attribute of this name
+/*
+ * Given range variable, return whether attribute of this name
  * is a set.
  * NOTE the ASSUMPTION here that no system attributes are, or ever
  * will be, sets.
+ *
+ *	This should only be used if the relation is already
+ *	heap_open()'ed.  Use the cache version get_attisset()
+ *	for access to non-opened relations.
  */
 bool
 attnameIsSet(Relation rd, char *name)
@@ -300,46 +308,11 @@ attnameIsSet(Relation rd, char *name)
 	return (get_attisset(rd->rd_id, name));
 }
 
-/*-------------
- * given an attribute number and a relation, return its relation name
+/*
+ *	This should only be used if the relation is already
+ *	heap_open()'ed.  Use the cache version
+ *	for access to non-opened relations.
  */
-char	   *
-attnumAttName(Relation rd, int attrno)
-{
-	char	   *name;
-	int			i;
-
-	if (attrno < 0)
-	{
-		for (i = 0; i < SPECIALS; i++)
-		{
-			if (special_attr[i].code == attrno)
-			{
-				name = special_attr[i].field;
-				return (name);
-			}
-		}
-		elog(ERROR, "Illegal attr no %d for relation %s",
-			 attrno, RelationGetRelationName(rd));
-	}
-	else if (attrno >= 1 && attrno <= RelationGetNumberOfAttributes(rd))
-	{
-		name = (rd->rd_att->attrs[attrno - 1]->attname).data;
-		return (name);
-	}
-	else
-	{
-		elog(ERROR, "Illegal attr no %d for relation %s",
-			 attrno, RelationGetRelationName(rd));
-	}
-
-	/*
-	 * Shouldn't get here, but we want lint to be happy...
-	 */
-
-	return (NULL);
-}
-
 int
 attnumAttNelems(Relation rd, int attid)
 {
@@ -347,7 +320,11 @@ attnumAttNelems(Relation rd, int attid)
 }
 
 /* given attribute id, return type of that attribute */
-/* XXX Special case for pseudo-attributes is a hack */
+/*
+ *	This should only be used if the relation is already
+ *	heap_open()'ed.  Use the cache version get_atttype()
+ *	for access to non-opened relations.
+ */
 Oid
 attnumTypeId(Relation rd, int attid)
 {
@@ -398,7 +375,6 @@ checkTargetTypes(ParseState *pstate, char *target_colname,
 				attrtype_target;
 	int			resdomno_id,
 				resdomno_target;
-	Relation	rd;
 	RangeTblEntry *rte;
 
 	if (target_colname == NULL || colname == NULL)
@@ -418,10 +394,8 @@ checkTargetTypes(ParseState *pstate, char *target_colname,
 	if (pstate->p_is_insert && rte == pstate->p_target_rangetblentry)
 		elog(ERROR, "%s not available in this context", colname);
 */
-	rd = heap_open(rte->relid);
-
-	resdomno_id = attnameAttNum(rd, colname);
-	attrtype_id = attnumTypeId(rd, resdomno_id);
+	resdomno_id = get_attnum(rte->relid, colname);
+	attrtype_id = get_atttype(rte->relid, resdomno_id);
 
 	resdomno_target = attnameAttNum(pstate->p_target_relation, target_colname);
 	attrtype_target = attnumTypeId(pstate->p_target_relation, resdomno_target);
@@ -431,15 +405,14 @@ checkTargetTypes(ParseState *pstate, char *target_colname,
 			 colname, target_colname);
 
 	if (attrtype_id == BPCHAROID &&
-		rd->rd_att->attrs[resdomno_id - 1]->atttypmod !=
-	pstate->p_target_relation->rd_att->attrs[resdomno_target - 1]->atttypmod)
+		get_atttypmod(rte->relid, resdomno_id) !=
+		get_atttype(pstate->p_target_relation->rd_id, resdomno_target))
 		elog(ERROR, "Length of %s is longer than length of target column %s",
 			 colname, target_colname);
 	if (attrtype_id == VARCHAROID &&
-		rd->rd_att->attrs[resdomno_id - 1]->atttypmod >
-	pstate->p_target_relation->rd_att->attrs[resdomno_target - 1]->atttypmod)
+		get_atttypmod(rte->relid, resdomno_id) >
+		get_atttype(pstate->p_target_relation->rd_id, resdomno_target))
 		elog(ERROR, "Length of %s is longer than length of target column %s",
 			 colname, target_colname);
 
-	heap_close(rd);
 }
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 895411aa1da3edb677a8ef83df10d0a15cb06658..4aa961ed45611cddabb7097dd891fa147afb9ffe 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.6 1998/01/16 23:20:22 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.7 1998/01/20 05:04:26 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,6 +20,7 @@
 #include "nodes/makefuncs.h"
 #include "nodes/primnodes.h"
 #include "parser/parse_expr.h"
+#include "parser/parse_func.h"
 #include "parser/parse_node.h"
 #include "parser/parse_relation.h"
 #include "parser/parse_target.h"
@@ -255,7 +256,7 @@ transformTargetList(ParseState *pstate, List *targetlist)
 					 * Target item is fully specified: ie.
 					 * relation.attribute
 					 */
-					result = handleNestedDots(pstate, att, &pstate->p_last_resno,EXPR_COLUMN_FIRST);
+					result = ParseNestedFuncOrColumn(pstate, att, &pstate->p_last_resno,EXPR_COLUMN_FIRST);
 					handleTargetColname(pstate, &res->name, att->relname, attrname);
 					if (att->indirection != NIL)
 					{
@@ -345,13 +346,12 @@ make_targetlist_expr(ParseState *pstate,
 	else
 		type_len = typeLen(typeidType(type_id));
 
-	/* I have no idea what the following does! */
-	/* It appears to process target columns that will be receiving results */
+	/* Processes target columns that will be receiving results */
 	if (pstate->p_is_insert || pstate->p_is_update)
 	{
 
 		/*
-		 * append or replace query -- append, replace work only on one
+		 * insert or update query -- insert, update work only on one
 		 * relation, so multiple occurence of same resdomno is bogus
 		 */
 		rd = pstate->p_target_relation;
@@ -461,7 +461,7 @@ make_targetlist_expr(ParseState *pstate,
 
 			att->relname = pstrdup(RelationGetRelationName(rd)->data);
 			att->attrs = lcons(makeString(colname), NIL);
-			target_expr = (Expr *) handleNestedDots(pstate, att,
+			target_expr = (Expr *) ParseNestedFuncOrColumn(pstate, att,
 												  &pstate->p_last_resno,
 												  EXPR_COLUMN_FIRST);
 			while (ar != NIL)
@@ -641,9 +641,8 @@ figureColname(Node *expr, Node *resval)
 {
 	switch (nodeTag(expr))
 	{
-			case T_Aggreg:
-			return (char *)		/* XXX */
-			((Aggreg *) expr)->aggname;
+		case T_Aggreg:
+			return (char *)	((Aggreg *) expr)->aggname;
 		case T_Expr:
 			if (((Expr *) expr)->opType == FUNC_EXPR)
 			{
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index c67371d308045b0efef36b9d7954fa3265ca48e2..2a37ad0fe7b842e963712c3582bfec20bb52c41e 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.9 1998/01/07 21:06:12 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.10 1998/01/20 05:04:32 momjian Exp $
  *
  * NOTES
  *	  Eventually, the index information should go through here, too.
@@ -53,9 +53,9 @@ op_class(Oid opno, int32 opclass, Oid amopid)
 							 ObjectIdGetDatum(opno),
 							 ObjectIdGetDatum(amopid),
 							 0))
-		return (true);
+		return true;
 	else
-		return (false);
+		return false;
 }
 
 /*				---------- ATTRIBUTE CACHES ----------					 */
@@ -71,20 +71,15 @@ char	   *
 get_attname(Oid relid, AttrNumber attnum)
 {
 	FormData_pg_attribute att_tup;
-	char	   *retval;
 
 	if (SearchSysCacheStruct(ATTNUM,
 							 (char *) &att_tup,
 							 ObjectIdGetDatum(relid),
 							 UInt16GetDatum(attnum),
 							 0, 0))
-	{
-		retval = pstrdup(att_tup.attname.data);
-
-		return (retval);
-	}
+		return pstrdup(att_tup.attname.data);
 	else
-		return (NULL);
+		return NULL;
 }
 
 /*
@@ -103,9 +98,9 @@ get_attnum(Oid relid, char *attname)
 							 ObjectIdGetDatum(relid),
 							 PointerGetDatum(attname),
 							 0, 0))
-		return (att_tup.attnum);
+		return att_tup.attnum;
 	else
-		return (InvalidAttrNumber);
+		return InvalidAttrNumber;
 }
 
 /*
@@ -125,9 +120,9 @@ get_atttype(Oid relid, AttrNumber attnum)
 							 ObjectIdGetDatum(relid),
 							 UInt16GetDatum(attnum),
 							 0, 0))
-		return (att_tup->atttypid);
+		return att_tup->atttypid;
 	else
-		return ((Oid) NULL);
+		return (Oid) NULL;
 }
 
 /* This routine uses the attname instead of the attnum because it
@@ -151,14 +146,36 @@ get_attisset(Oid relid, char *attname)
 		elog(ERROR, "get_attisset: no attribute %s in relation %d",
 			 attname, relid);
 	if (heap_attisnull(htup, attno))
-		return (false);
+		return false;
 	else
 	{
 		att_tup = (AttributeTupleForm) GETSTRUCT(htup);
-		return (att_tup->attisset);
+		return att_tup->attisset;
 	}
 }
 
+/*
+ * get_atttypmod -
+ *
+ *		Given the relation id and the attribute number,
+ *		return the "atttypmod" field from the attribute relation.
+ *
+ */
+int
+get_atttypmod(Oid relid, AttrNumber attnum)
+{
+	FormData_pg_attribute att_tup;
+
+	if (SearchSysCacheStruct(ATTNUM,
+							 (char *) &att_tup,
+							 ObjectIdGetDatum(relid),
+							 UInt16GetDatum(attnum),
+							 0, 0))
+		return att_tup.atttypmod;
+	else
+		return NULL;
+}
+
 /*				---------- INDEX CACHE ----------						 */
 
 /*		watch this space...
@@ -181,9 +198,9 @@ get_opcode(Oid opno)
 	if (SearchSysCacheStruct(OPROID, (char *) &optup,
 							 ObjectIdGetDatum(opno),
 							 0, 0, 0))
-		return (optup.oprcode);
+		return optup.oprcode;
 	else
-		return ((RegProcedure) NULL);
+		return (RegProcedure) NULL;
 }
 
 /*
@@ -200,7 +217,7 @@ get_opname(Oid opno)
 	if (SearchSysCacheStruct(OPROID, (char *) &optup,
 							 ObjectIdGetDatum(opno),
 							 0, 0, 0))
-		return (pstrdup(optup.oprname.data));
+		return pstrdup(optup.oprname.data);
 	else
 	{
 		elog(ERROR, "can't look up operator %d\n", opno);
@@ -257,9 +274,9 @@ op_hashjoinable(Oid opno, Oid ltype, Oid rtype)
 		optup.oprcanhash &&
 		optup.oprleft == ltype &&
 		optup.oprright == rtype)
-		return (opno);
+		return opno;
 	else
-		return (InvalidOid);
+		return InvalidOid;
 }
 
 /*
@@ -276,9 +293,9 @@ get_commutator(Oid opno)
 	if (SearchSysCacheStruct(OPROID, (char *) &optup,
 							 ObjectIdGetDatum(opno),
 							 0, 0, 0))
-		return (optup.oprcom);
+		return optup.oprcom;
 	else
-		return ((Oid) NULL);
+		return (Oid) NULL;
 }
 
 HeapTuple
@@ -289,9 +306,9 @@ get_operator_tuple(Oid opno)
 	if ((optup = SearchSysCacheTuple(OPROID,
 									 ObjectIdGetDatum(opno),
 									 0, 0, 0)))
-		return (optup);
+		return optup;
 	else
-		return ((HeapTuple) NULL);
+		return (HeapTuple) NULL;
 }
 
 /*
@@ -308,9 +325,9 @@ get_negator(Oid opno)
 	if (SearchSysCacheStruct(OPROID, (char *) &optup,
 							 ObjectIdGetDatum(opno),
 							 0, 0, 0))
-		return (optup.oprnegate);
+		return optup.oprnegate;
 	else
-		return ((Oid) NULL);
+		return (Oid) NULL;
 }
 
 /*
@@ -327,9 +344,9 @@ get_oprrest(Oid opno)
 	if (SearchSysCacheStruct(OPROID, (char *) &optup,
 							 ObjectIdGetDatum(opno),
 							 0, 0, 0))
-		return (optup.oprrest);
+		return optup.oprrest;
 	else
-		return ((RegProcedure) NULL);
+		return (RegProcedure) NULL;
 }
 
 /*
@@ -346,9 +363,9 @@ get_oprjoin(Oid opno)
 	if (SearchSysCacheStruct(OPROID, (char *) &optup,
 							 ObjectIdGetDatum(opno),
 							 0, 0, 0))
-		return (optup.oprjoin);
+		return optup.oprjoin;
 	else
-		return ((RegProcedure) NULL);
+		return (RegProcedure) NULL;
 }
 
 /*				---------- RELATION CACHE ----------					 */
@@ -367,9 +384,9 @@ get_relnatts(Oid relid)
 	if (SearchSysCacheStruct(RELOID, (char *) &reltup,
 							 ObjectIdGetDatum(relid),
 							 0, 0, 0))
-		return (reltup.relnatts);
+		return reltup.relnatts;
 	else
-		return (InvalidAttrNumber);
+		return InvalidAttrNumber;
 }
 
 /*
@@ -387,11 +404,9 @@ get_rel_name(Oid relid)
 							  (char *) &reltup,
 							  ObjectIdGetDatum(relid),
 							  0, 0, 0)))
-	{
-		return (pstrdup(reltup.relname.data));
-	}
+		return pstrdup(reltup.relname.data);
 	else
-		return (NULL);
+		return NULL;
 }
 
 /*				---------- TYPE CACHE ----------						 */
@@ -410,9 +425,9 @@ get_typlen(Oid typid)
 	if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
 							 ObjectIdGetDatum(typid),
 							 0, 0, 0))
-		return (typtup.typlen);
+		return typtup.typlen;
 	else
-		return ((int16) NULL);
+		return (int16) NULL;
 }
 
 /*
@@ -430,9 +445,9 @@ get_typbyval(Oid typid)
 	if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
 							 ObjectIdGetDatum(typid),
 							 0, 0, 0))
-		return ((bool) typtup.typbyval);
+		return (bool) typtup.typbyval;
 	else
-		return (false);
+		return false;
 }
 
 /*
@@ -451,9 +466,9 @@ get_typalign(Oid typid)
 	if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
 							 ObjectIdGetDatum(typid),
 							 0, 0, 0))
-		return (typtup.typalign);
+		return typtup.typalign;
 	else
-		return ('i');
+		return 'i';
 }
 
 #endif
@@ -470,7 +485,7 @@ get_typdefault(Oid typid)
 	struct varlena *typdefault =
 	(struct varlena *) TypeDefaultRetrieve(typid);
 
-	return (typdefault);
+	return typdefault;
 }
 
 /*
@@ -490,13 +505,9 @@ get_typtype(Oid typid)
 	if (SearchSysCacheStruct(TYPOID, (char *) &typtup,
 							 ObjectIdGetDatum(typid),
 							 0, 0, 0))
-	{
-		return (typtup.typtype);
-	}
+		return typtup.typtype;
 	else
-	{
-		return ('\0');
-	}
+		return '\0';
 }
 
 #endif
diff --git a/src/include/parser/parse_agg.h b/src/include/parser/parse_agg.h
index 8d1e0fb31fd426731430b8b6765a3df5f93c38f8..1381f14f8c491ff1c94f4ab508e2d3be53c8d674 100644
--- a/src/include/parser/parse_agg.h
+++ b/src/include/parser/parse_agg.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_agg.h,v 1.4 1998/01/04 04:31:39 momjian Exp $
+ * $Id: parse_agg.h,v 1.5 1998/01/20 05:04:41 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,7 +19,6 @@
 #include <parser/parse_node.h>
 
 extern void AddAggToParseState(ParseState *pstate, Aggreg *aggreg);
-extern void finalizeAggregates(ParseState *pstate, Query *qry);
 extern void parseCheckAggregates(ParseState *pstate, Query *qry);
 extern Aggreg *ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
 			List *target, int precedence);
diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h
index 42cbe9c46161ad759048962528cfc126f454ce48..b328cc5e5cafa25cbfcfc894cb986a6297a04ffe 100644
--- a/src/include/parser/parse_expr.h
+++ b/src/include/parser/parse_expr.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_expr.h,v 1.5 1998/01/16 23:21:01 momjian Exp $
+ * $Id: parse_expr.h,v 1.6 1998/01/20 05:04:47 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,8 +21,6 @@
 extern Node *transformExpr(ParseState *pstate, Node *expr, int precedence);
 extern Node *transformIdent(ParseState *pstate, Node *expr, int precedence);
 extern Oid exprType(Node *expr);
-extern Node *handleNestedDots(ParseState *pstate, Attr *attr,
-		int *curr_resno, int precedence);
 extern Node *parser_typecast2(Node *expr, Oid exprType, Type tp, int attypmod);
 
 #endif							/* PARSE_EXPR_H */
diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h
index 12d6ba16b88c097c02d0434d64a6279822a3592b..0a360df86ae3e2b1642b3acbbb8d0e8635c41a55 100644
--- a/src/include/parser/parse_func.h
+++ b/src/include/parser/parse_func.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_func.h,v 1.4 1998/01/04 04:31:42 momjian Exp $
+ * $Id: parse_func.h,v 1.5 1998/01/20 05:04:51 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,7 +42,9 @@ typedef struct _CandidateList
 	struct _CandidateList *next;
 }		   *CandidateList;
 
-extern Node *ParseFunc(ParseState *pstate, char *funcname, List *fargs,
+extern Node *ParseNestedFuncOrColumn(ParseState *pstate, Attr *attr,
+		int *curr_resno, int precedence);
+extern Node *ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
 	int *curr_resno, int precedence);
 
 extern void func_error(char *caller, char *funcname, int nargs, Oid *argtypes);
diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h
index e379b92932f5fd9e6f746ba0585a285140b5656e..eab72589ff57de996303c2fb90a9cf5296badc69 100644
--- a/src/include/parser/parse_relation.h
+++ b/src/include/parser/parse_relation.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_relation.h,v 1.4 1998/01/04 04:31:43 momjian Exp $
+ * $Id: parse_relation.h,v 1.5 1998/01/20 05:04:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -32,7 +32,6 @@ extern List *expandAll(ParseState *pstate, char *relname, char *refname,
 						int *this_resno);
 extern int attnameAttNum(Relation rd, char *a);
 extern bool attnameIsSet(Relation rd, char *name);
-extern char *attnumAttName(Relation rd, int attrno);
 extern int attnumAttNelems(Relation rd, int attid);
 extern Oid attnumTypeId(Relation rd, int attid);
 extern void handleTargetColname(ParseState *pstate, char **resname,
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 611073823233bd149dfc67ca4f84fb8ec3ea3814..aa30c755bd857788ba48408fc5083f0175b65585 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/include/storage/s_lock.h,v 1.18 1998/01/19 05:48:55 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/include/storage/s_lock.h,v 1.19 1998/01/20 05:05:02 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -315,7 +315,7 @@ again:
 							slock_t		_res; \
 							do \
 							{ \
-				__asm__("xchgb %0,%1": "=q"(_res), "=m"(*lock):"0"(0x1)); \
+				__asm__("lock; xchgb %0,%1": "=q"(_res), "=m"(*lock):"0"(0x1)); \
 							} while (_res != 0); \
 						} while (0)
 #endif
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index ca07a4a25cce5cf94fcbe6b83510f419f83a13b6..205e9cf4372155ef1f572538c90a58e762a1b857 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: lsyscache.h,v 1.6 1997/09/08 21:55:11 momjian Exp $
+ * $Id: lsyscache.h,v 1.7 1998/01/20 05:05:08 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,6 +21,7 @@ extern char *get_attname(Oid relid, AttrNumber attnum);
 extern AttrNumber get_attnum(Oid relid, char *attname);
 extern Oid	get_atttype(Oid relid, AttrNumber attnum);
 extern bool get_attisset(Oid relid, char *attname);
+extern int get_atttypmod(Oid relid, AttrNumber attnum);
 extern RegProcedure get_opcode(Oid opid);
 extern char *get_opname(Oid opid);
 extern bool