diff options
Diffstat (limited to 'src/pl')
-rw-r--r-- | src/pl/plperl/plperl.c | 109 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 29 | ||||
-rw-r--r-- | src/pl/plpython/plpython.c | 72 | ||||
-rw-r--r-- | src/pl/tcl/pltcl.c | 50 |
4 files changed, 142 insertions, 118 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 0524d9ebe4e..310df025706 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -1,7 +1,7 @@ /********************************************************************** * plperl.c - perl as a procedural language for PostgreSQL * - * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.107 2006/03/19 22:22:56 neilc Exp $ + * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.108 2006/04/04 19:35:37 tgl Exp $ * **********************************************************************/ @@ -585,31 +585,35 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup) while ((val = hv_iternextsv(hvNew, &key, &klen))) { int attn = SPI_fnumber(tupdesc, key); + Oid typinput; + Oid typioparam; + int32 atttypmod; + FmgrInfo finfo; if (attn <= 0 || tupdesc->attrs[attn - 1]->attisdropped) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("Perl hash contains nonexistent column \"%s\"", key))); + /* XXX would be better to cache these lookups */ + getTypeInputInfo(tupdesc->attrs[attn - 1]->atttypid, + &typinput, &typioparam); + fmgr_info(typinput, &finfo); + atttypmod = tupdesc->attrs[attn - 1]->atttypmod; if (SvOK(val) && SvTYPE(val) != SVt_NULL) { - Oid typinput; - Oid typioparam; - FmgrInfo finfo; - - /* XXX would be better to cache these lookups */ - getTypeInputInfo(tupdesc->attrs[attn - 1]->atttypid, - &typinput, &typioparam); - fmgr_info(typinput, &finfo); - modvalues[slotsused] = FunctionCall3(&finfo, - CStringGetDatum(SvPV(val, PL_na)), - ObjectIdGetDatum(typioparam), - Int32GetDatum(tupdesc->attrs[attn - 1]->atttypmod)); + modvalues[slotsused] = InputFunctionCall(&finfo, + SvPV(val, PL_na), + typioparam, + atttypmod); modnulls[slotsused] = ' '; } else { - modvalues[slotsused] = (Datum) 0; + modvalues[slotsused] = InputFunctionCall(&finfo, + NULL, + typioparam, + atttypmod); modnulls[slotsused] = 'n'; } modattrs[slotsused] = attn; @@ -897,8 +901,8 @@ plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo) { char *tmp; - tmp = DatumGetCString(FunctionCall1(&(desc->arg_out_func[i]), - fcinfo->arg[i])); + tmp = OutputFunctionCall(&(desc->arg_out_func[i]), + fcinfo->arg[i]); sv = newSVpv(tmp, 0); #if PERL_BCDVERSION >= 0x5006000L if (GetDatabaseEncoding() == PG_UTF8) @@ -1091,8 +1095,9 @@ plperl_func_handler(PG_FUNCTION_ARGS) /* Return NULL if Perl code returned undef */ if (rsi && IsA(rsi, ReturnSetInfo)) rsi->isDone = ExprEndResult; + retval = InputFunctionCall(&prodesc->result_in_func, NULL, + prodesc->result_typioparam, -1); fcinfo->isnull = true; - retval = (Datum) 0; } else if (prodesc->fn_retistuple) { @@ -1138,10 +1143,8 @@ plperl_func_handler(PG_FUNCTION_ARGS) val = SvPV(perlret, PL_na); - retval = FunctionCall3(&prodesc->result_in_func, - CStringGetDatum(val), - ObjectIdGetDatum(prodesc->result_typioparam), - Int32GetDatum(-1)); + retval = InputFunctionCall(&prodesc->result_in_func, val, + prodesc->result_typioparam, -1); } if (array_ret == NULL) @@ -1534,7 +1537,7 @@ plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc) getTypeOutputInfo(tupdesc->attrs[i]->atttypid, &typoutput, &typisvarlena); - outputstr = DatumGetCString(OidFunctionCall1(typoutput, attr)); + outputstr = OidOutputFunctionCall(typoutput, attr); sv = newSVpv(outputstr, 0); #if PERL_BCDVERSION >= 0x5006000L @@ -1750,19 +1753,23 @@ plperl_return_next(SV *sv) } else { - Datum ret = (Datum) 0; - bool isNull = true; + Datum ret; + bool isNull; if (SvOK(sv) && SvTYPE(sv) != SVt_NULL) { char *val = SvPV(sv, PL_na); - ret = FunctionCall3(&prodesc->result_in_func, - PointerGetDatum(val), - ObjectIdGetDatum(prodesc->result_typioparam), - Int32GetDatum(-1)); + ret = InputFunctionCall(&prodesc->result_in_func, val, + prodesc->result_typioparam, -1); isNull = false; } + else + { + ret = InputFunctionCall(&prodesc->result_in_func, NULL, + prodesc->result_typioparam, -1); + isNull = true; + } tuple = heap_form_tuple(current_call_data->ret_tdesc, &ret, &isNull); } @@ -2118,9 +2125,9 @@ plperl_spi_exec_prepared(char* query, HV * attr, int argc, SV ** argv) /************************************************************ * Set up arguments ************************************************************/ - if ( argc > 0) + if (argc > 0) { - nulls = (char *)palloc( argc); + nulls = (char *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -2129,21 +2136,22 @@ plperl_spi_exec_prepared(char* query, HV * attr, int argc, SV ** argv) argvalues = NULL; } - for ( i = 0; i < argc; i++) + for (i = 0; i < argc; i++) { - if ( SvTYPE( argv[i]) != SVt_NULL) + if (SvTYPE(argv[i]) != SVt_NULL) { - argvalues[i] = - FunctionCall3( &qdesc->arginfuncs[i], - CStringGetDatum( SvPV( argv[i], PL_na)), - ObjectIdGetDatum( qdesc->argtypioparams[i]), - Int32GetDatum(-1) - ); + argvalues[i] = InputFunctionCall(&qdesc->arginfuncs[i], + SvPV(argv[i], PL_na), + qdesc->argtypioparams[i], + -1); nulls[i] = ' '; } else { - argvalues[i] = (Datum) 0; + argvalues[i] = InputFunctionCall(&qdesc->arginfuncs[i], + NULL, + qdesc->argtypioparams[i], + -1); nulls[i] = 'n'; } } @@ -2247,9 +2255,9 @@ plperl_spi_query_prepared(char* query, int argc, SV ** argv) /************************************************************ * Set up arguments ************************************************************/ - if ( argc > 0) + if (argc > 0) { - nulls = (char *)palloc( argc); + nulls = (char *) palloc(argc); argvalues = (Datum *) palloc(argc * sizeof(Datum)); } else @@ -2258,21 +2266,22 @@ plperl_spi_query_prepared(char* query, int argc, SV ** argv) argvalues = NULL; } - for ( i = 0; i < argc; i++) + for (i = 0; i < argc; i++) { - if ( SvTYPE( argv[i]) != SVt_NULL) + if (SvTYPE(argv[i]) != SVt_NULL) { - argvalues[i] = - FunctionCall3( &qdesc->arginfuncs[i], - CStringGetDatum( SvPV( argv[i], PL_na)), - ObjectIdGetDatum( qdesc->argtypioparams[i]), - Int32GetDatum(-1) - ); + argvalues[i] = InputFunctionCall(&qdesc->arginfuncs[i], + SvPV(argv[i], PL_na), + qdesc->argtypioparams[i], + -1); nulls[i] = ' '; } else { - argvalues[i] = (Datum) 0; + argvalues[i] = InputFunctionCall(&qdesc->arginfuncs[i], + NULL, + qdesc->argtypioparams[i], + -1); nulls[i] = 'n'; } } diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index e4fa7003a7c..8a82a42fbe6 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.162 2006/03/09 21:29:36 momjian Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.163 2006/04/04 19:35:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -4043,6 +4043,8 @@ make_tuple_from_row(PLpgSQL_execstate *estate, * * Note: callers generally assume that the result is a palloc'd string and * should be pfree'd. This is not all that safe an assumption ... + * + * Note: not caching the conversion function lookup is bad for performance. * ---------- */ static char * @@ -4053,7 +4055,7 @@ convert_value_to_string(Datum value, Oid valtype) getTypeOutputInfo(valtype, &typoutput, &typIsVarlena); - return DatumGetCString(OidFunctionCall1(typoutput, value)); + return OidOutputFunctionCall(typoutput, value); } /* ---------- @@ -4068,23 +4070,26 @@ exec_cast_value(Datum value, Oid valtype, int32 reqtypmod, bool isnull) { - if (!isnull) + /* + * If the type of the queries return value isn't that of the variable, + * convert it. + */ + if (valtype != reqtype || reqtypmod != -1) { - /* - * If the type of the queries return value isn't that of the variable, - * convert it. - */ - if (valtype != reqtype || reqtypmod != -1) + if (!isnull) { char *extval; extval = convert_value_to_string(value, valtype); - value = FunctionCall3(reqinput, - CStringGetDatum(extval), - ObjectIdGetDatum(reqtypioparam), - Int32GetDatum(reqtypmod)); + value = InputFunctionCall(reqinput, extval, + reqtypioparam, reqtypmod); pfree(extval); } + else + { + value = InputFunctionCall(reqinput, NULL, + reqtypioparam, reqtypmod); + } } return value; diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index d20a5f72f13..bf96db1776d 100644 --- a/src/pl/plpython/plpython.c +++ b/src/pl/plpython/plpython.c @@ -1,7 +1,7 @@ /********************************************************************** * plpython.c - python as a procedural language for PostgreSQL * - * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.76 2006/03/14 22:48:24 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.77 2006/04/04 19:35:37 tgl Exp $ * ********************************************************************* */ @@ -482,17 +482,24 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata, modattrs[i] = attn; - if (plval != Py_None && !tupdesc->attrs[atti]->attisdropped) + if (tupdesc->attrs[atti]->attisdropped) + { + modvalues[i] = (Datum) 0; + modnulls[i] = 'n'; + } + else if (plval != Py_None) { plstr = PyObject_Str(plval); if (!plstr) - PLy_elog(ERROR, "function \"%s\" could not modify tuple", proc->proname); + PLy_elog(ERROR, "function \"%s\" could not modify tuple", + proc->proname); src = PyString_AsString(plstr); - modvalues[i] = FunctionCall3(&proc->result.out.r.atts[atti].typfunc, - CStringGetDatum(src), - ObjectIdGetDatum(proc->result.out.r.atts[atti].typioparam), - Int32GetDatum(tupdesc->attrs[atti]->atttypmod)); + modvalues[i] = + InputFunctionCall(&proc->result.out.r.atts[atti].typfunc, + src, + proc->result.out.r.atts[atti].typioparam, + tupdesc->attrs[atti]->atttypmod); modnulls[i] = ' '; Py_DECREF(plstr); @@ -500,7 +507,11 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata, } else { - modvalues[i] = PointerGetDatum(NULL); + modvalues[i] = + InputFunctionCall(&proc->result.out.r.atts[atti].typfunc, + NULL, + proc->result.out.r.atts[atti].typioparam, + tupdesc->attrs[atti]->atttypmod); modnulls[i] = 'n'; } @@ -751,7 +762,10 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc) else if (plrv == Py_None) { fcinfo->isnull = true; - rv = PointerGetDatum(NULL); + rv = InputFunctionCall(&proc->result.out.d.typfunc, + NULL, + proc->result.out.d.typioparam, + -1); } else { @@ -760,10 +774,10 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc) if (!plrv_so) PLy_elog(ERROR, "function \"%s\" could not create return value", proc->proname); plrv_sc = PyString_AsString(plrv_so); - rv = FunctionCall3(&proc->result.out.d.typfunc, - PointerGetDatum(plrv_sc), - ObjectIdGetDatum(proc->result.out.d.typioparam), - Int32GetDatum(-1)); + rv = InputFunctionCall(&proc->result.out.d.typfunc, + plrv_sc, + proc->result.out.d.typioparam, + -1); } } PG_CATCH(); @@ -861,13 +875,9 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc) else { char *ct; - Datum dt; - dt = FunctionCall3(&(proc->args[i].in.d.typfunc), - fcinfo->arg[i], - ObjectIdGetDatum(proc->args[i].in.d.typioparam), - Int32GetDatum(-1)); - ct = DatumGetCString(dt); + ct = OutputFunctionCall(&(proc->args[i].in.d.typfunc), + fcinfo->arg[i]); arg = (proc->args[i].in.d.func) (ct); pfree(ct); } @@ -1454,8 +1464,7 @@ PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc) { char *key, *vsrc; - Datum vattr, - vdat; + Datum vattr; bool is_null; PyObject *value; @@ -1469,11 +1478,8 @@ PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc) PyDict_SetItemString(dict, key, Py_None); else { - vdat = FunctionCall3(&info->in.r.atts[i].typfunc, - vattr, - ObjectIdGetDatum(info->in.r.atts[i].typioparam), - Int32GetDatum(desc->attrs[i]->atttypmod)); - vsrc = DatumGetCString(vdat); + vsrc = OutputFunctionCall(&info->in.r.atts[i].typfunc, + vattr); /* * no exceptions allowed @@ -2035,10 +2041,10 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit) char *sv = PyString_AsString(so); plan->values[i] = - FunctionCall3(&(plan->args[i].out.d.typfunc), - CStringGetDatum(sv), - ObjectIdGetDatum(plan->args[i].out.d.typioparam), - Int32GetDatum(-1)); + InputFunctionCall(&(plan->args[i].out.d.typfunc), + sv, + plan->args[i].out.d.typioparam, + -1); } PG_CATCH(); { @@ -2053,7 +2059,11 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit) else { Py_DECREF(elem); - plan->values[i] = PointerGetDatum(NULL); + plan->values[i] = + InputFunctionCall(&(plan->args[i].out.d.typfunc), + NULL, + plan->args[i].out.d.typioparam, + -1); nulls[i] = 'n'; } } diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index e1f21109bc5..07cbcc2eb31 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -2,7 +2,7 @@ * pltcl.c - PostgreSQL support for Tcl as * procedural language (PL) * - * $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.101 2006/03/14 22:48:24 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.102 2006/04/04 19:35:37 tgl Exp $ * **********************************************************************/ @@ -524,8 +524,8 @@ pltcl_func_handler(PG_FUNCTION_ARGS) { char *tmp; - tmp = DatumGetCString(FunctionCall1(&prodesc->arg_out_func[i], - fcinfo->arg[i])); + tmp = OutputFunctionCall(&prodesc->arg_out_func[i], + fcinfo->arg[i]); UTF_BEGIN; Tcl_DStringAppendElement(&tcl_cmd, UTF_E2U(tmp)); UTF_END; @@ -578,14 +578,17 @@ pltcl_func_handler(PG_FUNCTION_ARGS) elog(ERROR, "SPI_finish() failed"); if (fcinfo->isnull) - retval = (Datum) 0; + retval = InputFunctionCall(&prodesc->result_in_func, + NULL, + prodesc->result_typioparam, + -1); else { UTF_BEGIN; - retval = FunctionCall3(&prodesc->result_in_func, - PointerGetDatum(UTF_U2E(interp->result)), - ObjectIdGetDatum(prodesc->result_typioparam), - Int32GetDatum(-1)); + retval = InputFunctionCall(&prodesc->result_in_func, + UTF_U2E(interp->result), + prodesc->result_typioparam, + -1); UTF_END; } @@ -805,7 +808,6 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS) /* Use a TRY to ensure ret_values will get freed */ PG_TRY(); { - if (ret_numvals % 2 != 0) elog(ERROR, "invalid return list from trigger - must have even # of elements"); @@ -871,11 +873,10 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS) modnulls[attnum - 1] = ' '; fmgr_info(typinput, &finfo); UTF_BEGIN; - modvalues[attnum - 1] = - FunctionCall3(&finfo, - CStringGetDatum(UTF_U2E(ret_value)), - ObjectIdGetDatum(typioparam), - Int32GetDatum(tupdesc->attrs[attnum - 1]->atttypmod)); + modvalues[attnum - 1] = InputFunctionCall(&finfo, + (char *) UTF_U2E(ret_value), + typioparam, + tupdesc->attrs[attnum - 1]->atttypmod); UTF_END; } @@ -2041,17 +2042,18 @@ pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp, { if (nulls && nulls[j] == 'n') { - /* don't try to convert the input for a null */ - argvalues[j] = (Datum) 0; + argvalues[j] = InputFunctionCall(&qdesc->arginfuncs[j], + NULL, + qdesc->argtypioparams[j], + -1); } else { UTF_BEGIN; - argvalues[j] = - FunctionCall3(&qdesc->arginfuncs[j], - CStringGetDatum(UTF_U2E(callargs[j])), - ObjectIdGetDatum(qdesc->argtypioparams[j]), - Int32GetDatum(-1)); + argvalues[j] = InputFunctionCall(&qdesc->arginfuncs[j], + (char *) UTF_U2E(callargs[j]), + qdesc->argtypioparams[j], + -1); UTF_END; } } @@ -2185,8 +2187,7 @@ pltcl_set_tuple_values(Tcl_Interp *interp, CONST84 char *arrayname, ************************************************************/ if (!isnull && OidIsValid(typoutput)) { - outputstr = DatumGetCString(OidFunctionCall1(typoutput, - attr)); + outputstr = OidOutputFunctionCall(typoutput, attr); UTF_BEGIN; Tcl_SetVar2(interp, *arrptr, *nameptr, UTF_E2U(outputstr), 0); UTF_END; @@ -2255,8 +2256,7 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, ************************************************************/ if (!isnull && OidIsValid(typoutput)) { - outputstr = DatumGetCString(OidFunctionCall1(typoutput, - attr)); + outputstr = OidOutputFunctionCall(typoutput, attr); Tcl_DStringAppendElement(retval, attname); UTF_BEGIN; Tcl_DStringAppendElement(retval, UTF_E2U(outputstr)); |