The attached patch (and 2 new files incorporating previous eloglvl.[ch] as before) has the following changes over previously sent patch (fixes all by me):
- fix null <-> undef mappings - fix GNUmakefile to honor rpath configuration, and remove ugly compile arnings due to inappropriate use of rpath in CFLAGS - very minor code comment cleanup The feature set is as previously advised. There are no outstanding issues I am aware of. The previously advised limitation on representation of arrays and embedded composites remains, at least for now. We have started work on a doc set. cheers andrew
plperl.patch
Description: Binary data
#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 char* plperl_spi_status_string(int);
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);
hv_store(array, attname, strlen(attname), newSVpv(attdata,0), 0);
}
return array;
}
static HV*
plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
{
HV *result;
int i;
result = newHV();
if (status == SPI_OK_UTILITY)
{
hv_store(result, "status", strlen("status"), newSVpv("SPI_OK_UTILITY",0), 0);
hv_store(result, "rows", strlen("rows"), newSViv(rows), 0);
}
else if (status != SPI_OK_SELECT)
{
hv_store(result, "status", strlen("status"), newSVpv((char*)plperl_spi_status_string(status),0), 0);
hv_store(result, "rows", strlen("rows"), newSViv(rows), 0);
}
else
{
if (rows)
{
char* key=palloc(sizeof(int));
HV *row;
for (i = 0; i < rows; i++)
{
row = plperl_hash_from_tuple(tuptable->vals[i], tuptable->tupdesc);
sprintf(key, "%i", i);
hv_store(result, key, strlen(key), newRV_noinc((SV*)row), 0);
}
SPI_freetuptable(tuptable);
}
}
return result;
}
static char*
plperl_spi_status_string(int status)
{
switch(status){
/*errors*/
case SPI_ERROR_TYPUNKNOWN:
return "SPI_ERROR_TYPUNKNOWN";
case SPI_ERROR_NOOUTFUNC:
return "SPI_ERROR_NOOUTFUNC";
case SPI_ERROR_NOATTRIBUTE:
return "SPI_ERROR_NOATTRIBUTE";
case SPI_ERROR_TRANSACTION:
return "SPI_ERROR_TRANSACTION";
case SPI_ERROR_PARAM:
return "SPI_ERROR_PARAM";
case SPI_ERROR_ARGUMENT:
return "SPI_ERROR_ARGUMENT";
case SPI_ERROR_CURSOR:
return "SPI_ERROR_CURSOR";
case SPI_ERROR_UNCONNECTED:
return "SPI_ERROR_UNCONNECTED";
case SPI_ERROR_OPUNKNOWN:
return "SPI_ERROR_OPUNKNOWN";
case SPI_ERROR_COPY:
return "SPI_ERROR_COPY";
case SPI_ERROR_CONNECT:
return "SPI_ERROR_CONNECT";
/*ok*/
case SPI_OK_CONNECT:
return "SPI_OK_CONNECT";
case SPI_OK_FINISH:
return "SPI_OK_FINISH";
case SPI_OK_FETCH:
return "SPI_OK_FETCH";
case SPI_OK_UTILITY:
return "SPI_OK_UTILITY";
case SPI_OK_SELECT:
return "SPI_OK_SELECT";
case SPI_OK_SELINTO:
return "SPI_OK_SELINTO";
case SPI_OK_INSERT:
return "SPI_OK_INSERT";
case SPI_OK_DELETE:
return "SPI_OK_DELETE";
case SPI_OK_UPDATE:
return "SPI_OK_UPDATE";
case SPI_OK_CURSOR:
return "SPI_OK_CURSOR";
}
return "Unknown or Invalid code";
}#include "EXTERN.h" #include "perl.h" #include "XSUB.h" int spi_DEBUG(void); int spi_LOG(void); int spi_INFO(void); int spi_NOTICE(void); int spi_WARNING(void); int spi_ERROR(void); HV* plperl_spi_exec(char*, int);
---------------------------(end of broadcast)--------------------------- TIP 4: Don't 'kill -9' the postmaster
