提交 584e646a 编写于 作者: T Tom Lane

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().
上级 0f4a5868
......@@ -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);
......
......@@ -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;
}
......@@ -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);
......
......@@ -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
......
......@@ -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)
{
......
......@@ -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);
}
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
}
}
......
......@@ -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;
......
......@@ -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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册