#include "postgres.h" #include "executor/spi.h" #include "utils/syscache.h" /* * This kludge is necessary because of the conflicting * definitions of 'DEBUG' between postgres and perl. * we'll live. */ #include "spi_internal.h" static HV *plperl_spi_execute_fetch_result(SPITupleTable *, int, int); int spi_DEBUG(void) { return DEBUG2; } int spi_LOG(void) { return LOG; } int spi_INFO(void) { return INFO; } int spi_NOTICE(void) { return NOTICE; } int spi_WARNING(void) { return WARNING; } int spi_ERROR(void) { return ERROR; } HV * plperl_spi_exec(char *query, int limit) { HV *ret_hv; int spi_rv; spi_rv = SPI_exec(query, limit); ret_hv = plperl_spi_execute_fetch_result(SPI_tuptable, SPI_processed, spi_rv); return ret_hv; } 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), newSVpv("undef", 0), 0); } return array; } static HV * plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed, int status) { HV *result; result = newHV(); hv_store(result, "status", strlen("status"), newSVpv((char *) SPI_result_code_string(status), 0), 0); hv_store(result, "processed", strlen("processed"), newSViv(processed), 0); if (status == SPI_OK_SELECT) { if (processed) { AV *rows; HV *row; int i; rows = newAV(); for (i = 0; i < processed; i++) { row = plperl_hash_from_tuple(tuptable->vals[i], tuptable->tupdesc); av_store(rows, i, newRV_noinc((SV *) row)); } hv_store(result, "rows", strlen("rows"), newRV_noinc((SV *) rows), 0); } } SPI_freetuptable(tuptable); return result; }