--- plperl.c~ 2004-10-02 04:17:24.939049308 +0530 +++ plperl.c 2004-10-02 04:17:31.452742332 +0530 @@ -276,33 +276,30 @@ plperl_safe_init(void) plperl_safe_init_done = true; } -/********************************************************************** - * turn a tuple into a hash expression and add it to a list - **********************************************************************/ -static void -plperl_sv_add_tuple_value(SV *rv, HeapTuple tuple, TupleDesc tupdesc) -{ - int i; - char *value; - char *key; - - sv_catpvf(rv, "{ "); +static HV * +plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc) +{ + int i; + HV *hv = newHV(); for (i = 0; i < tupdesc->natts; i++) { - key = SPI_fname(tupdesc, i + 1); - value = SPI_getvalue(tuple, tupdesc, i + 1); - if (value) - sv_catpvf(rv, "%s => '%s'", key, value); + SV *value; + + char *key = SPI_fname(tupdesc, i+1); + char *val = SPI_getvalue(tuple, tupdesc, i + 1); + + if (val) + value = newSVpv(val, 0); else - sv_catpvf(rv, "%s => undef", key); - if (i != tupdesc->natts - 1) - sv_catpvf(rv, ", "); - } + value = newSV(0); - sv_catpvf(rv, " }"); + hv_store(hv, key, strlen(key), value, 0); + } + return hv; } + /********************************************************************** * set up arguments for a trigger call **********************************************************************/ @@ -312,76 +309,89 @@ plperl_trigger_build_args(FunctionCallIn TriggerData *tdata; TupleDesc tupdesc; int i = 0; - SV *rv; + char *level; + char *event; + char *relid; + char *when; + HV *hv; - rv = newSVpv("{ ", 0); + hv = newHV(); tdata = (TriggerData *) fcinfo->context; - tupdesc = tdata->tg_relation->rd_att; - sv_catpvf(rv, "name => '%s'", tdata->tg_trigger->tgname); - sv_catpvf(rv, ", relid => '%s'", DatumGetCString(DirectFunctionCall1(oidout, ObjectIdGetDatum(tdata->tg_relation->rd_id)))); + relid = DatumGetCString( + DirectFunctionCall1( + oidout, ObjectIdGetDatum(tdata->tg_relation->rd_id) + ) + ); + + hv_store(hv, "name", 4, newSVpv(tdata->tg_trigger->tgname, 0), 0); + hv_store(hv, "relid", 5, newSVpv(relid, 0), 0); if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) { - sv_catpvf(rv, ", event => 'INSERT'"); - sv_catpvf(rv, ", new =>"); - plperl_sv_add_tuple_value(rv, tdata->tg_trigtuple, tupdesc); + event = "INSERT"; + hv_store(hv, "new", 3, + newRV((SV *)plperl_hash_from_tuple(tdata->tg_trigtuple, + tupdesc)), + 0); } else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) { - sv_catpvf(rv, ", event => 'DELETE'"); - sv_catpvf(rv, ", old => "); - plperl_sv_add_tuple_value(rv, tdata->tg_trigtuple, tupdesc); + event = "DELETE"; + hv_store(hv, "old", 3, + newRV((SV *)plperl_hash_from_tuple(tdata->tg_trigtuple, + tupdesc)), + 0); } else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) { - sv_catpvf(rv, ", event => 'UPDATE'"); - - sv_catpvf(rv, ", new =>"); - plperl_sv_add_tuple_value(rv, tdata->tg_newtuple, tupdesc); - - sv_catpvf(rv, ", old => "); - plperl_sv_add_tuple_value(rv, tdata->tg_trigtuple, tupdesc); + event = "UPDATE"; + hv_store(hv, "old", 3, + newRV((SV *)plperl_hash_from_tuple(tdata->tg_trigtuple, + tupdesc)), + 0); + hv_store(hv, "new", 3, + newRV((SV *)plperl_hash_from_tuple(tdata->tg_newtuple, + tupdesc)), + 0); + } + else { + event = "UNKNOWN"; } - else - sv_catpvf(rv, ", event => 'UNKNOWN'"); - sv_catpvf(rv, ", argc => %d", tdata->tg_trigger->tgnargs); + hv_store(hv, "event", 5, newSVpv(event, 0), 0); + hv_store(hv, "argc", 4, newSViv(tdata->tg_trigger->tgnargs), 0); if (tdata->tg_trigger->tgnargs != 0) { - sv_catpvf(rv, ", args => [ "); - for (i = 0; i < tdata->tg_trigger->tgnargs; i++) - { - sv_catpvf(rv, "%s", tdata->tg_trigger->tgargs[i]); - if (i != tdata->tg_trigger->tgnargs - 1) - sv_catpvf(rv, ", "); - } - sv_catpvf(rv, " ]"); + AV *av = newAV(); + for (i=0; i < tdata->tg_trigger->tgnargs; i++) + av_push(av, newSVpv(tdata->tg_trigger->tgargs[i], 0)); + hv_store(hv, "args", 4, newRV((SV *)av), 0); } - sv_catpvf(rv, ", relname => '%s'", SPI_getrelname(tdata->tg_relation)); + + hv_store(hv, "relname", 7, + newSVpv(SPI_getrelname(tdata->tg_relation), 0), 0); if (TRIGGER_FIRED_BEFORE(tdata->tg_event)) - sv_catpvf(rv, ", when => 'BEFORE'"); + when = "BEFORE"; else if (TRIGGER_FIRED_AFTER(tdata->tg_event)) - sv_catpvf(rv, ", when => 'AFTER'"); + when = "AFTER"; else - sv_catpvf(rv, ", when => 'UNKNOWN'"); + when = "UNKNOWN"; + hv_store(hv, "when", 4, newSVpv(when, 0), 0); if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event)) - sv_catpvf(rv, ", level => 'ROW'"); + level = "ROW"; else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event)) - sv_catpvf(rv, ", level => 'STATEMENT'"); + level = "STATEMENT"; else - sv_catpvf(rv, ", level => 'UNKNOWN'"); - - sv_catpvf(rv, " }"); + level = "UNKNOWN"; + hv_store(hv, "level", 5, newSVpv(level, 0), 0); - rv = perl_eval_pv(SvPV(rv, PL_na), TRUE); - - return rv; + return newRV((SV*)hv); } @@ -1585,36 +1595,6 @@ plperl_spi_exec(char *query, int limit) } static HV * -plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc) -{ - int i; - char *attname; - char *attdata; - - HV *array; - - array = newHV(); - - for (i = 0; i < tupdesc->natts; i++) - { - /************************************************************ - * Get the attribute name - ************************************************************/ - attname = tupdesc->attrs[i]->attname.data; - - /************************************************************ - * Get the attributes value - ************************************************************/ - attdata = SPI_getvalue(tuple, tupdesc, i + 1); - if (attdata) - hv_store(array, attname, strlen(attname), newSVpv(attdata, 0), 0); - else - hv_store(array, attname, strlen(attname), newSV(0), 0); - } - return array; -} - -static HV * plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed, int status) { HV *result;