summaryrefslogtreecommitdiff
path: root/src/pl
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl')
-rw-r--r--src/pl/plperl/plperl.c109
-rw-r--r--src/pl/plpgsql/src/pl_exec.c29
-rw-r--r--src/pl/plpython/plpython.c72
-rw-r--r--src/pl/tcl/pltcl.c50
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));