* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.56 2004/11/16 22:05:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.57 2004/11/17 21:23:36 tgl Exp $
*
**********************************************************************/
Datum plperl_call_handler(PG_FUNCTION_ARGS);
void plperl_init(void);
+HV *plperl_spi_exec(char *query, int limit);
+
static Datum plperl_func_handler(PG_FUNCTION_ARGS);
static Datum plperl_trigger_handler(PG_FUNCTION_ARGS);
if (SvTRUE(ERRSV))
{
- POPs;
+ (void) POPs;
PUTBACK;
FREETMPS;
LEAVE;
if (SvTRUE(ERRSV))
{
- POPs;
+ (void) POPs;
PUTBACK;
FREETMPS;
LEAVE;
if (SvTRUE(ERRSV))
{
- POPs;
+ (void) POPs;
PUTBACK;
FREETMPS;
LEAVE;
if (!(perlret && SvOK(perlret) && SvTYPE(perlret) != SVt_NULL))
{
/* return NULL if Perl code returned undef */
- retval = (Datum) 0;
fcinfo->isnull = true;
}
if (prodesc->fn_retistuple && perlret && SvTYPE(perlret) != SVt_RV)
elog(ERROR, "plperl: composite-returning function must return a reference");
+ if (prodesc->fn_retisset && !fcinfo->resultinfo)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("set-valued function called in context that cannot accept a set")));
+
if (prodesc->fn_retistuple && fcinfo->resultinfo) /* set of tuples */
{
/* SRF support */
HV *ret_hv;
AV *ret_av;
-
FuncCallContext *funcctx;
int call_cntr;
int max_calls;
TupleDesc tupdesc;
- TupleTableSlot *slot;
AttInMetadata *attinmeta;
- bool isset = 0;
+ bool isset;
char **values = NULL;
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
- if (prodesc->fn_retisset && !rsinfo)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("returning a composite type is not allowed in this context"),
- errhint("This function is intended for use in the FROM clause.")));
-
-
isset = plperl_is_set(perlret);
if (SvTYPE(SvRV(perlret)) == SVt_PVHV)
av_store(g_column_keys, i + 1,
newSVpv(SPI_fname(tupdesc, i+1), 0));
- slot = TupleDescGetSlot(tupdesc);
- funcctx->slot = slot;
attinmeta = TupleDescGetAttInMetadata(tupdesc);
funcctx->attinmeta = attinmeta;
MemoryContextSwitchTo(oldcontext);
funcctx = SRF_PERCALL_SETUP();
call_cntr = funcctx->call_cntr;
max_calls = funcctx->max_calls;
- slot = funcctx->slot;
attinmeta = funcctx->attinmeta;
+ tupdesc = attinmeta->tupdesc;
if (call_cntr < max_calls)
{
}
}
tuple = BuildTupleFromCStrings(attinmeta, values);
- result = TupleGetDatum(slot, tuple);
+ result = HeapTupleGetDatum(tuple);
SRF_RETURN_NEXT(funcctx, result);
}
else
svp = av_fetch(array, funcctx->call_cntr, FALSE);
if (SvTYPE(*svp) != SVt_NULL)
+ {
+ fcinfo->isnull = false;
result = FunctionCall3(&prodesc->result_in_func,
PointerGetDatum(SvPV(*svp, PL_na)),
ObjectIdGetDatum(prodesc->result_typioparam),
Int32GetDatum(-1));
+ }
else
{
fcinfo->isnull = true;
result = (Datum) 0;
}
SRF_RETURN_NEXT(funcctx, result);
- fcinfo->isnull = false;
}
else
{
}
else if (!fcinfo->isnull) /* non-null singleton */
{
-
-
if (prodesc->fn_retistuple) /* singleton perl hash to Datum */
{
TupleDesc td = lookup_rowtype_tupdesc(prodesc->ret_oid, (int32) -1);
attinmeta = TupleDescGetAttInMetadata(td);
tup = BuildTupleFromCStrings(attinmeta, values);
retval = HeapTupleGetDatum(tup);
-
}
else
/* perl string to Datum */
PointerGetDatum(SvPV(perlret, PL_na)),
ObjectIdGetDatum(prodesc->result_typioparam),
Int32GetDatum(-1));
-
}
+ else /* null singleton */
+ retval = (Datum) 0;
SvREFCNT_dec(perlret);
return retval;
retval = (Datum) trigdata->tg_newtuple;
else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
retval = (Datum) trigdata->tg_trigtuple;
+ else
+ retval = (Datum) 0; /* can this happen? */
}
else
{
}
retval = PointerGetDatum(trv);
}
+ else
+ retval = (Datum) 0;
}
SvREFCNT_dec(perlret);