From 584e646ad886ab53d23d268bbf62f56882f0bb4e Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 15 Jan 2000 22:43:25 +0000
Subject: [PATCH] Fix a passel of problems with incorrect calls to typinput and
 typoutput functions, which would lead to trouble with datatypes that paid
 attention to the typelem or typmod parameters to these functions.  In
 particular, incorrect code in pg_aggregate.c explains the platform-specific
 failures that have been reported in NUMERIC avg().

---
 src/backend/bootstrap/bootstrap.c  |  9 +++---
 src/backend/catalog/pg_aggregate.c | 12 ++++++--
 src/backend/commands/vacuum.c      | 14 ++++++---
 src/backend/utils/adt/arrayfuncs.c | 10 +++----
 src/backend/utils/adt/ruleutils.c  |  6 ++--
 src/backend/utils/adt/selfuncs.c   | 10 ++++---
 src/include/commands/vacuum.h      |  3 +-
 src/pl/plpgsql/src/pl_comp.c       |  8 ++++-
 src/pl/plpgsql/src/pl_exec.c       | 48 ++++++++++++++++++++++--------
 src/pl/plpgsql/src/plpgsql.h       |  6 ++--
 src/pl/tcl/pltcl.c                 | 13 +++-----
 11 files changed, 89 insertions(+), 50 deletions(-)

diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 8e9f125996d..306b983370b 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -7,7 +7,7 @@
  * Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.77 2000/01/15 02:59:27 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.78 2000/01/15 22:43:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -680,11 +680,10 @@ InsertOneValue(Oid objectid, char *value, int i)
 		values[i] = fmgr(ap->am_typ.typinput,
 						 value,
 						 ap->am_typ.typelem,
-						 -1);	/* shouldn't have char() or varchar()
-								 * types during boostrapping but just to
-								 * be safe */
+						 -1);
 		prt = fmgr(ap->am_typ.typoutput, values[i],
-				   ap->am_typ.typelem);
+				   ap->am_typ.typelem,
+				   -1);
 		if (!Quiet)
 			printf("%s ", prt);
 		pfree(prt);
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 7a5377fd033..cf338742c9c 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.27 2000/01/10 17:14:31 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.28 2000/01/15 22:43:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -262,7 +262,9 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
 	HeapTuple	tup;
 	Relation	aggRel;
 	int			initValAttno;
-	Oid			transtype;
+	Oid			transtype,
+				typinput,
+				typelem;
 	text	   *textInitVal;
 	char	   *strInitVal,
 			   *initVal;
@@ -320,7 +322,11 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
 		pfree(strInitVal);
 		elog(ERROR, "AggNameGetInitVal: cache lookup failed on aggregate transition function return type");
 	}
-	initVal = fmgr(((Form_pg_type) GETSTRUCT(tup))->typinput, strInitVal, -1);
+	typinput = ((Form_pg_type) GETSTRUCT(tup))->typinput;
+	typelem = ((Form_pg_type) GETSTRUCT(tup))->typelem;
+
+	initVal = fmgr(typinput, strInitVal, typelem, -1);
+
 	pfree(strInitVal);
 	return initVal;
 }
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 7d3a1b6f318..3af6f6b183b 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.134 2000/01/10 04:09:50 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.135 2000/01/15 22:43:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -516,9 +516,15 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
 								 ObjectIdGetDatum(stats->attr->atttypid),
 											0, 0, 0);
 			if (HeapTupleIsValid(typetuple))
+			{
 				stats->outfunc = ((Form_pg_type) GETSTRUCT(typetuple))->typoutput;
+				stats->typelem = ((Form_pg_type) GETSTRUCT(typetuple))->typelem;
+			}
 			else
+			{
 				stats->outfunc = InvalidOid;
+				stats->typelem = InvalidOid;
+			}
 		}
 		vacrelstats->va_natts = attr_cnt;
 		/* delete existing pg_statistic rows for relation */
@@ -2488,13 +2494,13 @@ vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex,
 					/* hack: this code knows float4 is pass-by-ref */
 					values[i++] = PointerGetDatum(&nullratio);	/* stanullfrac */
 					values[i++] = PointerGetDatum(&bestratio);	/* stacommonfrac */
-					out_string = (*fmgr_faddr(&out_function)) (stats->best, stats->attr->atttypid, stats->attr->atttypmod);
+					out_string = (*fmgr_faddr(&out_function)) (stats->best, stats->typelem, stats->attr->atttypmod);
 					values[i++] = PointerGetDatum(textin(out_string)); /* stacommonval */
 					pfree(out_string);
-					out_string = (*fmgr_faddr(&out_function)) (stats->min, stats->attr->atttypid, stats->attr->atttypmod);
+					out_string = (*fmgr_faddr(&out_function)) (stats->min, stats->typelem, stats->attr->atttypmod);
 					values[i++] = PointerGetDatum(textin(out_string)); /* staloval */
 					pfree(out_string);
-					out_string = (char *) (*fmgr_faddr(&out_function)) (stats->max, stats->attr->atttypid, stats->attr->atttypmod);
+					out_string = (char *) (*fmgr_faddr(&out_function)) (stats->max, stats->typelem, stats->attr->atttypmod);
 					values[i++] = PointerGetDatum(textin(out_string)); /* stahival */
 					pfree(out_string);
 
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 9f04ca48229..ebf54e8b623 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.50 1999/12/09 15:56:16 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.51 2000/01/15 22:43:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -669,21 +669,21 @@ array_out(ArrayType *v, Oid element_type)
 			switch (typlen)
 			{
 				case 1:
-					values[i] = (*fmgr_faddr(&outputproc)) (*p, typelem);
+					values[i] = (*fmgr_faddr(&outputproc)) (*p, typelem, -1);
 					break;
 				case 2:
-					values[i] = (*fmgr_faddr(&outputproc)) (*(int16 *) p, typelem);
+					values[i] = (*fmgr_faddr(&outputproc)) (*(int16 *) p, typelem, -1);
 					break;
 				case 3:
 				case 4:
-					values[i] = (*fmgr_faddr(&outputproc)) (*(int32 *) p, typelem);
+					values[i] = (*fmgr_faddr(&outputproc)) (*(int32 *) p, typelem, -1);
 					break;
 			}
 			p += typlen;
 		}
 		else
 		{
-			values[i] = (*fmgr_faddr(&outputproc)) (p, typelem);
+			values[i] = (*fmgr_faddr(&outputproc)) (p, typelem, -1);
 			if (typlen > 0)
 				p += typlen;
 			else
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 496fb94ddc9..c4e31491604 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
  *			  out of its tuple
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.38 2000/01/15 02:59:38 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.39 2000/01/15 22:43:24 tgl Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -1604,7 +1604,6 @@ get_const_expr(Const *constval, deparse_context *context)
 	FmgrInfo	finfo_output;
 	char	   *extval;
 	char	   *valptr;
-	bool		isnull = FALSE;
 
 	typetup = SearchSysCacheTuple(TYPEOID,
 								  ObjectIdGetDatum(constval->consttype),
@@ -1629,7 +1628,8 @@ get_const_expr(Const *constval, deparse_context *context)
 
 	fmgr_info(typeStruct->typoutput, &finfo_output);
 	extval = (char *) (*fmgr_faddr(&finfo_output)) (constval->constvalue,
-													&isnull, -1);
+													typeStruct->typelem,
+													-1);
 
 	switch (constval->consttype)
 	{
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index b711d768c07..7ec3e4dc1b8 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.47 2000/01/15 02:59:38 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.48 2000/01/15 22:43:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -600,6 +600,7 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
 	HeapTuple	tuple;
 	HeapTuple	typeTuple;
 	FmgrInfo	inputproc;
+	Oid			typelem;
 
 	rel = heap_openr(StatisticRelationName, AccessShareLock);
 
@@ -630,6 +631,7 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
 		elog(ERROR, "getattstatistics: Cache lookup failed for type %u",
 			 typid);
 	fmgr_info(((Form_pg_type) GETSTRUCT(typeTuple))->typinput, &inputproc);
+	typelem = ((Form_pg_type) GETSTRUCT(typeTuple))->typelem;
 
 	/* Values are variable-length fields, so cannot access as struct fields.
 	 * Must do it the hard way with heap_getattr.
@@ -649,7 +651,7 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
 		{
 			char *strval = textout(val);
 			*commonval = (Datum)
-				(*fmgr_faddr(&inputproc)) (strval, typid, typmod);
+				(*fmgr_faddr(&inputproc)) (strval, typelem, typmod);
 			pfree(strval);
 		}
 	}
@@ -669,7 +671,7 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
 		{
 			char *strval = textout(val);
 			*loval = (Datum)
-				(*fmgr_faddr(&inputproc)) (strval, typid, typmod);
+				(*fmgr_faddr(&inputproc)) (strval, typelem, typmod);
 			pfree(strval);
 		}
 	}
@@ -689,7 +691,7 @@ getattstatistics(Oid relid, AttrNumber attnum, Oid opid, Oid typid,
 		{
 			char *strval = textout(val);
 			*hival = (Datum)
-				(*fmgr_faddr(&inputproc)) (strval, typid, typmod);
+				(*fmgr_faddr(&inputproc)) (strval, typelem, typmod);
 			pfree(strval);
 		}
 	}
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 86049179715..aca63898be6 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: vacuum.h,v 1.24 1999/08/25 12:18:31 ishii Exp $
+ * $Id: vacuum.h,v 1.25 2000/01/15 22:43:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -86,6 +86,7 @@ typedef struct
 				f_cmpgt;
 	Oid			op_cmplt;
 	regproc		outfunc;
+	Oid			typelem;
 	bool		initialized;
 } VacAttrStats;
 
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 9d509e2c389..0b880505773 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -3,7 +3,7 @@
  *			  procedural language
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.15 2000/01/10 17:14:45 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.16 2000/01/15 22:43:25 tgl Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -191,6 +191,7 @@ plpgsql_compile(Oid fn_oid, int functype)
 			{
 				function->fn_retbyval = typeStruct->typbyval;
 				function->fn_rettyplen = typeStruct->typlen;
+				function->fn_rettypelem = typeStruct->typelem;
 				fmgr_info(typeStruct->typinput, &(function->fn_retinput));
 			}
 
@@ -259,6 +260,7 @@ plpgsql_compile(Oid fn_oid, int functype)
 					var->datatype->typname = strdup(nameout(&(typeStruct->typname)));
 					var->datatype->typoid = procStruct->proargtypes[i];
 					fmgr_info(typeStruct->typinput, &(var->datatype->typinput));
+					var->datatype->typelem = typeStruct->typelem;
 					var->datatype->typbyval = typeStruct->typbyval;
 					var->datatype->atttypmod = -1;
 					var->isconst = true;
@@ -621,6 +623,7 @@ plpgsql_parse_word(char *word)
 		typ->typname = strdup(nameout(&(typeStruct->typname)));
 		typ->typoid = typeTup->t_data->t_oid;
 		fmgr_info(typeStruct->typinput, &(typ->typinput));
+		typ->typelem = typeStruct->typelem;
 		typ->typbyval = typeStruct->typbyval;
 		typ->atttypmod = -1;
 
@@ -944,6 +947,7 @@ plpgsql_parse_wordtype(char *word)
 		typ->typname = strdup(nameout(&(typeStruct->typname)));
 		typ->typoid = typeTup->t_data->t_oid;
 		fmgr_info(typeStruct->typinput, &(typ->typinput));
+		typ->typelem = typeStruct->typelem;
 		typ->typbyval = typeStruct->typbyval;
 		typ->atttypmod = -1;
 
@@ -1088,6 +1092,7 @@ plpgsql_parse_dblwordtype(char *string)
 	typ->typname = strdup(nameout(&(typeStruct->typname)));
 	typ->typoid = typetup->t_data->t_oid;
 	fmgr_info(typeStruct->typinput, &(typ->typinput));
+	typ->typelem = typeStruct->typelem;
 	typ->typbyval = typeStruct->typbyval;
 	typ->atttypmod = attrStruct->atttypmod;
 
@@ -1216,6 +1221,7 @@ plpgsql_parse_wordrowtype(char *string)
 		var->datatype->typname = strdup(NameStr(typeStruct->typname));
 		var->datatype->typoid = typetup->t_data->t_oid;
 		fmgr_info(typeStruct->typinput, &(var->datatype->typinput));
+		var->datatype->typelem = typeStruct->typelem;
 		var->datatype->typbyval = typeStruct->typbyval;
 		var->datatype->atttypmod = attrStruct->atttypmod;
 		var->isconst = false;
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 5c7405a1e40..48223ffab7b 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -3,7 +3,7 @@
  *			  procedural language
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.16 2000/01/05 18:23:53 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.17 2000/01/15 22:43:25 tgl Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -129,7 +129,8 @@ static void exec_move_row(PLpgSQL_execstate * estate,
 static Datum exec_cast_value(Datum value, Oid valtype,
 				Oid reqtype,
 				FmgrInfo *reqinput,
-				int16 reqtypmod,
+				Oid reqtypelem,
+				int32 reqtypmod,
 				bool *isnull);
 static void exec_set_found(PLpgSQL_execstate * estate, bool state);
 
@@ -388,7 +389,10 @@ plpgsql_exec_function(PLpgSQL_function * func,
 	if (!estate.retistuple)
 	{
 		estate.retval = exec_cast_value(estate.retval, estate.rettype,
-							  func->fn_rettype, &(func->fn_retinput), -1,
+										func->fn_rettype,
+										&(func->fn_retinput),
+										func->fn_rettypelem,
+										-1,
 										isNull);
 
 		/* ----------
@@ -1160,6 +1164,7 @@ exec_stmt_fori(PLpgSQL_execstate * estate, PLpgSQL_stmt_fori * stmt)
 
 	value = exec_cast_value(value, valtype, var->datatype->typoid,
 							&(var->datatype->typinput),
+							var->datatype->typelem,
 							var->datatype->atttypmod, &isnull);
 	if (isnull)
 		elog(ERROR, "lower bound of FOR loop cannot be NULL");
@@ -1173,6 +1178,7 @@ exec_stmt_fori(PLpgSQL_execstate * estate, PLpgSQL_stmt_fori * stmt)
 	value = exec_eval_expr(estate, stmt->upper, &isnull, &valtype);
 	value = exec_cast_value(value, valtype, var->datatype->typoid,
 							&(var->datatype->typinput),
+							var->datatype->typelem,
 							var->datatype->atttypmod, &isnull);
 	if (isnull)
 		elog(ERROR, "upper bound of FOR loop cannot be NULL");
@@ -1560,7 +1566,10 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt)
 						typeStruct = (Form_pg_type) GETSTRUCT(typetup);
 
 						fmgr_info(typeStruct->typoutput, &finfo_output);
-						extval = (char *) (*fmgr_faddr(&finfo_output)) (var->value, &(var->isnull), var->datatype->atttypmod);
+						extval = (char *) (*fmgr_faddr(&finfo_output))
+							(var->value,
+							 typeStruct->typelem,
+							 var->datatype->atttypmod);
 					}
 					plpgsql_dstring_append(&ds, extval);
 					break;
@@ -1697,7 +1706,8 @@ exec_prepare_plan(PLpgSQL_execstate * estate,
 				break;
 
 			default:
-				elog(ERROR, "unknown parameter dtype %d in exec_run_select()", estate->datums[expr->params[i]]);
+				elog(ERROR, "unknown parameter dtype %d in exec_run_select()",
+					 estate->datums[expr->params[i]]->dtype);
 		}
 	}
 
@@ -1873,7 +1883,7 @@ exec_assign_value(PLpgSQL_execstate * estate,
 	char	   *nulls;
 	bool		attisnull;
 	Oid			atttype;
-	int4		atttypmod;
+	int32		atttypmod;
 	HeapTuple	typetup;
 	Form_pg_type typeStruct;
 	FmgrInfo	finfo_input;
@@ -1888,7 +1898,9 @@ exec_assign_value(PLpgSQL_execstate * estate,
 			var = (PLpgSQL_var *) target;
 			var->value = exec_cast_value(value, valtype, var->datatype->typoid,
 										 &(var->datatype->typinput),
-									   var->datatype->atttypmod, isNull);
+										 var->datatype->typelem,
+										 var->datatype->atttypmod,
+										 isNull);
 
 			if (isNull && var->notnull)
 				elog(ERROR, "NULL assignment to variable '%s' declared NOT NULL", var->refname);
@@ -1967,7 +1979,9 @@ exec_assign_value(PLpgSQL_execstate * estate,
 
 				attisnull = *isNull;
 				values[i] = exec_cast_value(value, valtype,
-						   atttype, &finfo_input, atttypmod, &attisnull);
+											atttype, &finfo_input,
+											typeStruct->typelem,
+											atttypmod, &attisnull);
 				if (attisnull)
 					nulls[i] = 'n';
 				else
@@ -2138,7 +2152,8 @@ exec_run_select(PLpgSQL_execstate * estate,
 				break;
 
 			default:
-				elog(ERROR, "unknown parameter dtype %d in exec_eval_expr()", estate->datums[expr->params[i]]);
+				elog(ERROR, "unknown parameter dtype %d in exec_eval_expr()",
+					 estate->datums[expr->params[i]]->dtype);
 		}
 	}
 	nulls[i] = '\0';
@@ -2372,7 +2387,8 @@ static Datum
 exec_cast_value(Datum value, Oid valtype,
 				Oid reqtype,
 				FmgrInfo *reqinput,
-				int16 reqtypmod,
+				Oid reqtypelem,
+				int32 reqtypmod,
 				bool *isnull)
 {
 	if (!*isnull)
@@ -2382,7 +2398,7 @@ exec_cast_value(Datum value, Oid valtype,
 		 * that of the variable, convert it.
 		 * ----------
 		 */
-		if (valtype != reqtype || reqtypmod > 0)
+		if (valtype != reqtype || reqtypmod != -1)
 		{
 			HeapTuple	typetup;
 			Form_pg_type typeStruct;
@@ -2396,8 +2412,14 @@ exec_cast_value(Datum value, Oid valtype,
 			typeStruct = (Form_pg_type) GETSTRUCT(typetup);
 
 			fmgr_info(typeStruct->typoutput, &finfo_output);
-			extval = (char *) (*fmgr_faddr(&finfo_output)) (value, &isnull, -1);
-			value = (Datum) (*fmgr_faddr(reqinput)) (extval, &isnull, reqtypmod);
+			extval = (char *) (*fmgr_faddr(&finfo_output))
+				(value,
+				 typeStruct->typelem,
+				 -1);
+			value = (Datum) (*fmgr_faddr(reqinput)) (extval,
+													 reqtypelem,
+													 reqtypmod);
+			pfree(extval);
 		}
 	}
 
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index e14fd47ecd7..b698419653f 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -3,7 +3,7 @@
  *			  procedural language
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.6 2000/01/14 01:36:42 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.7 2000/01/15 22:43:25 tgl Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -123,8 +123,9 @@ typedef struct
 	char	   *typname;
 	Oid			typoid;
 	FmgrInfo	typinput;
+	Oid			typelem;
 	bool		typbyval;
-	int16		atttypmod;
+	int32		atttypmod;
 }			PLpgSQL_type;
 
 
@@ -373,6 +374,7 @@ typedef struct PLpgSQL_function
 	int			fn_rettyplen;
 	bool		fn_retbyval;
 	FmgrInfo	fn_retinput;
+	Oid			fn_rettypelem;
 	bool		fn_retistuple;
 	bool		fn_retset;
 
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index cf89817d454..f693b4f2db3 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -3,7 +3,7 @@
  *			  procedural language (PL)
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.17 2000/01/10 17:14:46 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.18 2000/01/15 22:43:23 tgl Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -65,7 +65,6 @@ typedef struct pltcl_proc_desc
 	char	   *proname;
 	FmgrInfo	result_in_func;
 	Oid			result_in_elem;
-	int			result_in_len;
 	int			nargs;
 	FmgrInfo	arg_out_func[FUNC_MAX_ARGS];
 	Oid			arg_out_elem[FUNC_MAX_ARGS];
@@ -501,8 +500,7 @@ pltcl_func_handler(FmgrInfo *proinfo,
 		}
 
 		fmgr_info(typeStruct->typinput, &(prodesc->result_in_func));
-		prodesc->result_in_elem = (Oid) (typeStruct->typelem);
-		prodesc->result_in_len = typeStruct->typlen;
+		prodesc->result_in_elem = typeStruct->typelem;
 
 		/************************************************************
 		 * Get the required information for output conversion
@@ -721,7 +719,7 @@ pltcl_func_handler(FmgrInfo *proinfo,
 	retval = (Datum) (*fmgr_faddr(&prodesc->result_in_func))
 		(pltcl_safe_interp->result,
 		 prodesc->result_in_elem,
-		 prodesc->result_in_len);
+		 -1);
 
 	memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
 	return retval;
@@ -1140,10 +1138,7 @@ pltcl_trigger_handler(FmgrInfo *proinfo)
 		modvalues[attnum - 1] = (Datum) (*fmgr_faddr(&finfo))
 			(ret_values[i++],
 			 typelem,
-			 (!VARLENA_FIXED_SIZE(tupdesc->attrs[attnum - 1]))
-			 ? tupdesc->attrs[attnum - 1]->attlen
-			 : tupdesc->attrs[attnum - 1]->atttypmod
-			);
+			 tupdesc->attrs[attnum - 1]->atttypmod);
 	}
 
 
-- 
GitLab