diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 408418ee33a62f89204ea4cd803576e944ba5dc0..f019dbb4ae640297d83a6d17b194597046ad327a 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.311 2005/03/24 04:36:17 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.312 2005/03/29 03:01:29 tgl Exp $
 -->
 
 <chapter Id="runtime">
@@ -3774,7 +3774,7 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
        <para>
         Shows the maximum number of function arguments. It is determined by
         the value of <literal>FUNC_MAX_ARGS</> when building the server. The
-        default value is 32.
+        default value is 100.
        </para>
       </listitem>
      </varlistentry>
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 6bc5b78780c024ff8edac96d163b9915cf3dabc9..2d05f6b2777a90c95a5e669867662179eac5e0b1 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.182 2005/03/24 04:36:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.183 2005/03/29 03:01:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3120,7 +3120,7 @@ WriteControlFile(void)
 	ControlFile->xlog_seg_size = XLOG_SEG_SIZE;
 
 	ControlFile->nameDataLen = NAMEDATALEN;
-	ControlFile->funcMaxArgs = FUNC_MAX_ARGS;
+	ControlFile->indexMaxKeys = INDEX_MAX_KEYS;
 
 #ifdef HAVE_INT64_TIMESTAMP
 	ControlFile->enableIntTimes = TRUE;
@@ -3285,12 +3285,12 @@ ReadControlFile(void)
 					 " but the server was compiled with NAMEDATALEN %d.",
 						   ControlFile->nameDataLen, NAMEDATALEN),
 			 errhint("It looks like you need to recompile or initdb.")));
-	if (ControlFile->funcMaxArgs != FUNC_MAX_ARGS)
+	if (ControlFile->indexMaxKeys != INDEX_MAX_KEYS)
 		ereport(FATAL,
 				(errmsg("database files are incompatible with server"),
-				 errdetail("The database cluster was initialized with FUNC_MAX_ARGS %d,"
-				   " but the server was compiled with FUNC_MAX_ARGS %d.",
-						   ControlFile->funcMaxArgs, FUNC_MAX_ARGS),
+				 errdetail("The database cluster was initialized with INDEX_MAX_KEYS %d,"
+				   " but the server was compiled with INDEX_MAX_KEYS %d.",
+						   ControlFile->indexMaxKeys, INDEX_MAX_KEYS),
 			 errhint("It looks like you need to recompile or initdb.")));
 
 #ifdef HAVE_INT64_TIMESTAMP
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index e2783bbee0a32c0e8d3a8b704dfa022a9507aa2a..246c3a0188733c7288a5f8a240955506495392bc 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.70 2005/01/27 23:42:15 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.71 2005/03/29 03:01:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -57,7 +57,7 @@ AggregateCreate(const char *aggName,
 	Oid			finalfn = InvalidOid;	/* can be omitted */
 	Oid			rettype;
 	Oid			finaltype;
-	Oid			fnArgs[FUNC_MAX_ARGS];
+	Oid			fnArgs[2];		/* we only deal with 1- and 2-arg fns */
 	int			nargs_transfn;
 	Oid			procOid;
 	TupleDesc	tupDesc;
@@ -85,7 +85,6 @@ AggregateCreate(const char *aggName,
 			"transition type must have one of them as its base type.")));
 
 	/* handle transfn */
-	MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid));
 	fnArgs[0] = aggTransType;
 	if (aggBaseType == ANYOID)
 		nargs_transfn = 1;
@@ -139,7 +138,6 @@ AggregateCreate(const char *aggName,
 	/* handle finalfn, if supplied */
 	if (aggfinalfnName)
 	{
-		MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid));
 		fnArgs[0] = aggTransType;
 		finalfn = lookup_agg_function(aggfinalfnName, 1, fnArgs,
 									  &finaltype);
@@ -174,7 +172,6 @@ AggregateCreate(const char *aggName,
 	 * aggregate.  (This could fail if there's already a conflicting
 	 * entry.)
 	 */
-	MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid));
 	fnArgs[0] = aggBaseType;
 
 	procOid = ProcedureCreate(aggName,
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 4ec68f39f0a23c2c3bb75a9468f28b7b629ee201..2052418422098da8c7289f44ce292ec775d20e08 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.88 2005/01/27 23:23:51 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.89 2005/03/29 03:01:30 tgl Exp $
  *
  * NOTES
  *	  these routines moved here from commands/define.c and somewhat cleaned up.
@@ -391,7 +391,7 @@ OperatorCreate(const char *operatorName,
 				restOid,
 				joinOid;
 	bool		selfCommutator = false;
-	Oid			typeId[FUNC_MAX_ARGS];
+	Oid			typeId[4];		/* only need up to 4 args here */
 	int			nargs;
 	NameData	oname;
 	TupleDesc	tupDesc;
@@ -454,7 +454,6 @@ OperatorCreate(const char *operatorName,
 	 * procedureName to place in "result" field. Do this before shells are
 	 * created so we don't have to worry about deleting them later.
 	 */
-	MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
 	if (!OidIsValid(leftTypeId))
 	{
 		typeId[0] = rightTypeId;
@@ -479,7 +478,6 @@ OperatorCreate(const char *operatorName,
 	 */
 	if (restrictionName)
 	{
-		MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
 		typeId[0] = INTERNALOID;	/* Query */
 		typeId[1] = OIDOID;		/* operator OID */
 		typeId[2] = INTERNALOID;	/* args list */
@@ -495,7 +493,6 @@ OperatorCreate(const char *operatorName,
 	 */
 	if (joinName)
 	{
-		MemSet(typeId, 0, FUNC_MAX_ARGS * sizeof(Oid));
 		typeId[0] = INTERNALOID;	/* Query */
 		typeId[1] = OIDOID;		/* operator OID */
 		typeId[2] = INTERNALOID;	/* args list */
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index c440fc38208428b4012732e2f43844e10f8d0992..f50e0936c809a2394cdf5905854ab6f545260eb0 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.57 2005/02/14 06:17:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.58 2005/03/29 03:01:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,7 +44,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 	Oid			procOid,
 				valProcOid;
 	Oid			funcrettype;
-	Oid			typev[FUNC_MAX_ARGS];
+	Oid			funcargtypes[1];
 	NameData	langname;
 	char		nulls[Natts_pg_language];
 	Datum		values[Natts_pg_language];
@@ -80,8 +80,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 	 * Lookup the PL handler function and check that it is of the expected
 	 * return type
 	 */
-	MemSet(typev, 0, sizeof(typev));
-	procOid = LookupFuncName(stmt->plhandler, 0, typev, false);
+	procOid = LookupFuncName(stmt->plhandler, 0, funcargtypes, false);
 	funcrettype = get_func_rettype(procOid);
 	if (funcrettype != LANGUAGE_HANDLEROID)
 	{
@@ -108,8 +107,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 	/* validate the validator function */
 	if (stmt->plvalidator)
 	{
-		typev[0] = OIDOID;
-		valProcOid = LookupFuncName(stmt->plvalidator, 1, typev, false);
+		funcargtypes[0] = OIDOID;
+		valProcOid = LookupFuncName(stmt->plvalidator, 1, funcargtypes, false);
 		/* return value is ignored, so we don't check the type */
 	}
 	else
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index a9e8bc9e7f1bf8001e5676b872af353ead041674..ef00943055fadfffc6ad939efd52af059c56170e 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.182 2005/03/29 00:16:57 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.183 2005/03/29 03:01:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1179,10 +1179,7 @@ ExecCallTriggerFunc(TriggerData *trigdata,
 	/*
 	 * Call the function, passing no arguments but setting a context.
 	 */
-	MemSet(&fcinfo, 0, sizeof(fcinfo));
-
-	fcinfo.flinfo = finfo;
-	fcinfo.context = (Node *) trigdata;
+	InitFunctionCallInfoData(fcinfo, finfo, 0, (Node *) trigdata, NULL);
 
 	result = FunctionCallInvoke(&fcinfo);
 
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index b68d3264dc5039a5d81cab936d3ba9f46dbf0571..5fd01c6f5987caf37f63ac017374ee8271409522 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.67 2005/01/27 23:23:56 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.68 2005/03/29 03:01:30 tgl Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -854,7 +854,7 @@ RemoveDomain(List *names, DropBehavior behavior)
 static Oid
 findTypeInputFunction(List *procname, Oid typeOid)
 {
-	Oid			argList[FUNC_MAX_ARGS];
+	Oid			argList[3];
 	Oid			procOid;
 
 	/*
@@ -864,8 +864,6 @@ findTypeInputFunction(List *procname, Oid typeOid)
 	 * For backwards compatibility we allow OPAQUE in place of CSTRING; if we
 	 * see this, we issue a warning and fix up the pg_proc entry.
 	 */
-	MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
-
 	argList[0] = CSTRINGOID;
 
 	procOid = LookupFuncName(procname, 1, argList, true);
@@ -880,8 +878,6 @@ findTypeInputFunction(List *procname, Oid typeOid)
 		return procOid;
 
 	/* No luck, try it with OPAQUE */
-	MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
-
 	argList[0] = OPAQUEOID;
 
 	procOid = LookupFuncName(procname, 1, argList, true);
@@ -925,7 +921,7 @@ findTypeInputFunction(List *procname, Oid typeOid)
 static Oid
 findTypeOutputFunction(List *procname, Oid typeOid)
 {
-	Oid			argList[FUNC_MAX_ARGS];
+	Oid			argList[2];
 	Oid			procOid;
 
 	/*
@@ -936,8 +932,6 @@ findTypeOutputFunction(List *procname, Oid typeOid)
 	 * type name; if we see this, we issue a warning and fix up the
 	 * pg_proc entry.
 	 */
-	MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
-
 	argList[0] = typeOid;
 
 	procOid = LookupFuncName(procname, 1, argList, true);
@@ -951,8 +945,6 @@ findTypeOutputFunction(List *procname, Oid typeOid)
 		return procOid;
 
 	/* No luck, try it with OPAQUE */
-	MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
-
 	argList[0] = OPAQUEOID;
 
 	procOid = LookupFuncName(procname, 1, argList, true);
@@ -995,15 +987,13 @@ findTypeOutputFunction(List *procname, Oid typeOid)
 static Oid
 findTypeReceiveFunction(List *procname, Oid typeOid)
 {
-	Oid			argList[FUNC_MAX_ARGS];
+	Oid			argList[2];
 	Oid			procOid;
 
 	/*
 	 * Receive functions can take a single argument of type INTERNAL, or
 	 * two arguments (internal, oid).
 	 */
-	MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
-
 	argList[0] = INTERNALOID;
 
 	procOid = LookupFuncName(procname, 1, argList, true);
@@ -1027,15 +1017,13 @@ findTypeReceiveFunction(List *procname, Oid typeOid)
 static Oid
 findTypeSendFunction(List *procname, Oid typeOid)
 {
-	Oid			argList[FUNC_MAX_ARGS];
+	Oid			argList[2];
 	Oid			procOid;
 
 	/*
 	 * Send functions can take a single argument of the type, or two
 	 * arguments (data value, element OID).
 	 */
-	MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
-
 	argList[0] = typeOid;
 
 	procOid = LookupFuncName(procname, 1, argList, true);
@@ -1059,15 +1047,13 @@ findTypeSendFunction(List *procname, Oid typeOid)
 static Oid
 findTypeAnalyzeFunction(List *procname, Oid typeOid)
 {
-	Oid			argList[FUNC_MAX_ARGS];
+	Oid			argList[1];
 	Oid			procOid;
 
 	/*
 	 * Analyze functions always take one INTERNAL argument and return
 	 * bool.
 	 */
-	MemSet(argList, 0, FUNC_MAX_ARGS * sizeof(Oid));
-
 	argList[0] = INTERNALOID;
 
 	procOid = LookupFuncName(procname, 1, argList, true);
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 2a72a660fa39aa5279c0d1e3b7a045250945223c..07d52ef5441e0b813b87b9099e86f519f5554444 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.175 2004/12/31 22:00:27 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.176 2005/03/29 03:01:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -85,8 +85,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
 	if (nargs > FUNC_MAX_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
-			   errmsg("cannot pass more than %d arguments to a function",
-					  FUNC_MAX_ARGS)));
+				 errmsg("cannot pass more than %d arguments to a function",
+						FUNC_MAX_ARGS)));
 
 	if (fargs)
 	{
@@ -123,8 +123,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
 	 * Okay, it's not a column projection, so it must really be a
 	 * function. Extract arg type info in preparation for function lookup.
 	 */
-	MemSet(actual_arg_types, 0, FUNC_MAX_ARGS * sizeof(Oid));
-
 	argn = 0;
 	foreach(l, fargs)
 	{
@@ -376,6 +374,13 @@ func_select_candidate(int nargs,
 	bool		slot_has_preferred_type[FUNC_MAX_ARGS];
 	bool		resolved_unknowns;
 
+	/* protect local fixed-size arrays */
+	if (nargs > FUNC_MAX_ARGS)
+		ereport(ERROR,
+				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
+				 errmsg("cannot pass more than %d arguments to a function",
+						FUNC_MAX_ARGS)));
+
 	/*
 	 * If any input types are domains, reduce them to their base types.
 	 * This ensures that we will consider functions on the base type to be
@@ -866,9 +871,13 @@ func_get_detail(List *funcname,
 static Oid **
 argtype_inherit(int nargs, Oid *argtypes)
 {
+	Oid		  **result;
 	Oid			relid;
 	int			i;
-	InhPaths	arginh[FUNC_MAX_ARGS];
+	InhPaths   *arginh;
+
+	/* Set up the vector of superclass information */
+	arginh = (InhPaths *) palloc(nargs * sizeof(InhPaths));
 
 	for (i = 0; i < nargs; i++)
 	{
@@ -882,8 +891,12 @@ argtype_inherit(int nargs, Oid *argtypes)
 		}
 	}
 
-	/* return an ordered cross-product of the classes involved */
-	return gen_cross_product(arginh, nargs);
+	/* Compute an ordered cross-product of the classes involved */
+	result = gen_cross_product(arginh, nargs);
+
+	pfree(arginh);
+
+	return result;
 }
 
 /*
@@ -993,7 +1006,7 @@ gen_cross_product(InhPaths *arginh, int nargs)
 	Oid		   *oneres;
 	int			i,
 				j;
-	int			cur[FUNC_MAX_ARGS];
+	int		   *cur;
 
 	/*
 	 * At each position we want to try the original datatype, plus each
@@ -1016,7 +1029,7 @@ gen_cross_product(InhPaths *arginh, int nargs)
 	 * generate the original input type at position i.	When cur[i] == k
 	 * for k > 0, generate its k'th supertype.
 	 */
-	MemSet(cur, 0, sizeof(cur));
+	cur = (int *) palloc0(nargs * sizeof(int));
 
 	for (;;)
 	{
@@ -1036,7 +1049,7 @@ gen_cross_product(InhPaths *arginh, int nargs)
 		cur[i] += 1;
 
 		/* Generate the proper output type-OID vector */
-		oneres = (Oid *) palloc0(FUNC_MAX_ARGS * sizeof(Oid));
+		oneres = (Oid *) palloc(nargs * sizeof(Oid));
 
 		for (i = 0; i < nargs; i++)
 		{
@@ -1054,6 +1067,8 @@ gen_cross_product(InhPaths *arginh, int nargs)
 
 	Assert(j == nanswers);
 
+	pfree(cur);
+
 	return result;
 }
 
@@ -1380,7 +1395,6 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
 	int			i;
 	ListCell   *args_item;
 
-	MemSet(argoids, 0, FUNC_MAX_ARGS * sizeof(Oid));
 	argcount = list_length(argtypes);
 	if (argcount > FUNC_MAX_ARGS)
 		ereport(ERROR,
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index f123e2f0cbfbb6382f95fcc77411e2da85902914..42b73d49c0c757bdc5fcc3863cd908cfe603e29c 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/fastpath.c,v 1.78 2005/03/29 00:17:05 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/fastpath.c,v 1.79 2005/03/29 03:01:31 tgl Exp $
  *
  * NOTES
  *	  This cruft is the server side of PQfn.
@@ -216,7 +216,7 @@ fetch_fp_info(Oid func_id, struct fp_info * fip)
 	 * the struct fp_info across transactions anymore, but keep it
 	 * anyway.]
 	 */
-	MemSet((char *) fip, 0, sizeof(struct fp_info));
+	MemSet(fip, 0, sizeof(struct fp_info));
 	fip->funcid = InvalidOid;
 
 	fmgr_info(func_id, &fip->flinfo);
@@ -341,8 +341,7 @@ HandleFunctionRequest(StringInfo msgBuf)
 	/*
 	 * Prepare function call info block and insert arguments.
 	 */
-	MemSet(&fcinfo, 0, sizeof(fcinfo));
-	fcinfo.flinfo = &fip->flinfo;
+	InitFunctionCallInfoData(fcinfo, &fip->flinfo, 0, NULL, NULL);
 
 	if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
 		rformat = parse_fcall_arguments(msgBuf, fip, &fcinfo);
@@ -443,6 +442,7 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info * fip,
 			fcinfo->argnull[i] = true;
 			continue;
 		}
+		fcinfo->argnull[i] = false;
 		if (argsize < 0)
 			ereport(ERROR,
 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
@@ -566,6 +566,7 @@ parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info * fip,
 			fcinfo->argnull[i] = true;
 			continue;
 		}
+		fcinfo->argnull[i] = false;
 		if (argsize < 0)
 			ereport(ERROR,
 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 47edcc5a5737327b3f3b1d9ddc866ed22373613c..ec21eac9c031fe3d9cbe4894a1a6da7b12b5a6fb 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.118 2005/03/29 00:17:08 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.119 2005/03/29 03:01:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2577,9 +2577,8 @@ array_eq(PG_FUNCTION_ARGS)
 		/*
 		 * apply the operator to each pair of array elements.
 		 */
-		MemSet(&locfcinfo, 0, sizeof(locfcinfo));
-		locfcinfo.flinfo = &typentry->eq_opr_finfo;
-		locfcinfo.nargs = 2;
+		InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
+								 NULL, NULL);
 
 		/* Loop over source data */
 		for (i = 0; i < nitems1; i++)
@@ -2727,9 +2726,8 @@ array_cmp(FunctionCallInfo fcinfo)
 	/*
 	 * apply the operator to each pair of array elements.
 	 */
-	MemSet(&locfcinfo, 0, sizeof(locfcinfo));
-	locfcinfo.flinfo = &typentry->cmp_proc_finfo;
-	locfcinfo.nargs = 2;
+	InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
+							 NULL, NULL);
 
 	/* Loop over source data */
 	min_nitems = Min(nitems1, nitems2);
@@ -3172,12 +3170,14 @@ array_type_length_coerce_internal(ArrayType *src,
 	 * We pass on the desttypmod and isExplicit flags whether or not the
 	 * function wants them.
 	 */
-	MemSet(&locfcinfo, 0, sizeof(locfcinfo));
-	locfcinfo.flinfo = &my_extra->coerce_finfo;
-	locfcinfo.nargs = 3;
+	InitFunctionCallInfoData(locfcinfo, &my_extra->coerce_finfo, 3,
+							 NULL, NULL);
 	locfcinfo.arg[0] = PointerGetDatum(src);
 	locfcinfo.arg[1] = Int32GetDatum(desttypmod);
 	locfcinfo.arg[2] = BoolGetDatum(isExplicit);
+	locfcinfo.argnull[0] = false;
+	locfcinfo.argnull[1] = false;
+	locfcinfo.argnull[2] = false;
 
 	return array_map(&locfcinfo, my_extra->srctype, my_extra->desttype,
 					 &my_extra->amstate);
@@ -3246,12 +3246,14 @@ array_length_coerce(PG_FUNCTION_ARGS)
 	 *
 	 * Note: we pass isExplicit whether or not the function wants it ...
 	 */
-	MemSet(&locfcinfo, 0, sizeof(locfcinfo));
-	locfcinfo.flinfo = &my_extra->coerce_finfo;
-	locfcinfo.nargs = 3;
+	InitFunctionCallInfoData(locfcinfo, &my_extra->coerce_finfo, 3,
+							 NULL, NULL);
 	locfcinfo.arg[0] = PointerGetDatum(v);
 	locfcinfo.arg[1] = Int32GetDatum(desttypmod);
 	locfcinfo.arg[2] = BoolGetDatum(isExplicit);
+	locfcinfo.argnull[0] = false;
+	locfcinfo.argnull[1] = false;
+	locfcinfo.argnull[2] = false;
 
 	return array_map(&locfcinfo, ARR_ELEMTYPE(v), ARR_ELEMTYPE(v),
 					 &my_extra->amstate);
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 430cfeffc707b15a7e095db38eba2632c61f22b5..a8bb5fc0ac5a8e5135b7e08f24581e21504af36f 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.91 2005/03/29 00:17:15 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.92 2005/03/29 03:01:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -337,9 +337,9 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
 			/* Old style: need to use a handler */
 			finfo->fn_addr = fmgr_oldstyle;
 			fnextra = (Oldstyle_fnextra *)
-				MemoryContextAlloc(finfo->fn_mcxt, sizeof(Oldstyle_fnextra));
+				MemoryContextAllocZero(finfo->fn_mcxt,
+									   sizeof(Oldstyle_fnextra));
 			finfo->fn_extra = (void *) fnextra;
-			MemSet(fnextra, 0, sizeof(Oldstyle_fnextra));
 			fnextra->func = (func_ptr) user_fn;
 			for (i = 0; i < procedureStruct->pronargs; i++)
 			{
@@ -795,8 +795,8 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
 
 	if (!fcinfo->flinfo->fn_extra)
 	{
-		fcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(*fcache));
-		memset(fcache, 0, sizeof(*fcache));
+		fcache = MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt,
+										sizeof(*fcache));
 
 		fmgr_info_cxt_security(fcinfo->flinfo->fn_oid, &fcache->flinfo,
 							   fcinfo->flinfo->fn_mcxt, true);
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 3615655dc42147b1d169d841a00af933ed361078..bfe7da2ad5053292a682d24438edbf4aa215d640 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -6,7 +6,7 @@
  * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
  * licence: BSD
  *
- * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.21 2005/02/22 04:39:00 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.22 2005/03/29 03:01:32 tgl Exp $
  */
 #include "postgres.h"
 
@@ -170,7 +170,7 @@ main(int argc, char *argv[])
 	printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size);
 	printf(_("Bytes per WAL segment:                %u\n"), ControlFile.xlog_seg_size);
 	printf(_("Maximum length of identifiers:        %u\n"), ControlFile.nameDataLen);
-	printf(_("Maximum number of function arguments: %u\n"), ControlFile.funcMaxArgs);
+	printf(_("Maximum columns in an index:          %u\n"), ControlFile.indexMaxKeys);
 	printf(_("Date/time type storage:               %s\n"),
 		   (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers")));
 	printf(_("Maximum length of locale name:        %u\n"), ControlFile.localeBuflen);
diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c
index 31e1442984fa728784739c53bc19bc29d85fae4b..242b27b9a01417f33ac7c1f2e7ebc8a6951702a0 100644
--- a/src/bin/pg_resetxlog/pg_resetxlog.c
+++ b/src/bin/pg_resetxlog/pg_resetxlog.c
@@ -23,7 +23,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.29 2005/02/22 04:40:20 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.30 2005/03/29 03:01:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -417,7 +417,7 @@ GuessControlValues(void)
 	ControlFile.relseg_size = RELSEG_SIZE;
 	ControlFile.xlog_seg_size = XLOG_SEG_SIZE;
 	ControlFile.nameDataLen = NAMEDATALEN;
-	ControlFile.funcMaxArgs = FUNC_MAX_ARGS;
+	ControlFile.indexMaxKeys = INDEX_MAX_KEYS;
 #ifdef HAVE_INT64_TIMESTAMP
 	ControlFile.enableIntTimes = TRUE;
 #else
@@ -481,7 +481,7 @@ PrintControlValues(bool guessed)
 	printf(_("Database block size:                  %u\n"), ControlFile.blcksz);
 	printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size);
 	printf(_("Maximum length of identifiers:        %u\n"), ControlFile.nameDataLen);
-	printf(_("Maximum number of function arguments: %u\n"), ControlFile.funcMaxArgs);
+	printf(_("Maximum columns in an index:          %u\n"), ControlFile.indexMaxKeys);
 	printf(_("Date/time type storage:               %s\n"),
 		   (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers")));
 	printf(_("Maximum length of locale name:        %u\n"), ControlFile.localeBuflen);
diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h
index 1335546fe0e86b2ef152385ea0e38534593143ea..83573334fc58c3e78cec61d499f8d23eff9b7268 100644
--- a/src/include/catalog/pg_control.h
+++ b/src/include/catalog/pg_control.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.19 2004/12/31 22:03:24 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.20 2005/03/29 03:01:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -116,7 +116,7 @@ typedef struct ControlFileData
 	uint32		xlog_seg_size;	/* size of each WAL segment */
 
 	uint32		nameDataLen;	/* catalog name field width */
-	uint32		funcMaxArgs;	/* maximum number of function arguments */
+	uint32		indexMaxKeys;	/* max number of columns in an index */
 
 	/* flag indicating internal format of timestamp, interval, time */
 	uint32		enableIntTimes; /* int64 storage enabled? */
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index 040651fcb174a8280abbd3324388d759dfa84db5..b36714b87bd2e03b5e3011e6b492aff36f977b35 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -6,7 +6,7 @@
  * for developers.	If you edit any of these, be sure to do a *full*
  * rebuild (and an initdb if noted).
  *
- * $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.15 2004/09/10 14:27:37 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.16 2005/03/29 03:01:32 tgl Exp $
  *------------------------------------------------------------------------
  */
 
@@ -52,17 +52,27 @@
 #define XLOG_SEG_SIZE	(16*1024*1024)
 
 /*
- * Maximum number of columns in an index and maximum number of
- * arguments to a function. They must be the same value.
+ * Maximum number of arguments to a function.
  *
  * The minimum value is 8 (index creation uses 8-argument functions).
- * There is no specific upper limit, although large values will waste
- * system-table space and processing time.
+ * The maximum possible value is around 600 (limited by index tuple size in
+ * pg_proc's index; BLCKSZ larger than 8K would allow more).  Values larger
+ * than needed will waste memory and processing time, but do not directly
+ * cost disk space.
  *
- * Changing these requires an initdb.
+ * Changing this does not require an initdb, but it does require a full
+ * backend recompile (including any user-defined C functions).
+ */
+#define FUNC_MAX_ARGS		100
+
+/*
+ * Maximum number of columns in an index.  There is little point in making
+ * this anything but a multiple of 32, because the main cost is associated
+ * with index tuple header size (see access/itup.h).
+ *
+ * Changing this requires an initdb.
  */
 #define INDEX_MAX_KEYS		32
-#define FUNC_MAX_ARGS		INDEX_MAX_KEYS
 
 /*
  * Define this to make libpgtcl's "pg_result -assign" command process