mirror of
https://github.com/pgpointcloud/pointcloud.git
synced 2025-12-08 20:36:04 +00:00
151 lines
2.5 KiB
C
151 lines
2.5 KiB
C
|
|
#include "pc_pgsql.h"
|
|
#include "executor/spi.h"
|
|
|
|
PG_MODULE_MAGIC;
|
|
|
|
|
|
static void *
|
|
pgsql_alloc(size_t size)
|
|
{
|
|
void * result;
|
|
result = palloc(size);
|
|
|
|
if ( ! result )
|
|
{
|
|
ereport(ERROR, (errmsg_internal("Out of virtual memory")));
|
|
return NULL;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static void *
|
|
pgsql_realloc(void *mem, size_t size)
|
|
{
|
|
void * result;
|
|
result = repalloc(mem, size);
|
|
return result;
|
|
}
|
|
|
|
static void
|
|
pgsql_free(void *ptr)
|
|
{
|
|
pfree(ptr);
|
|
}
|
|
|
|
static void
|
|
pgsql_msg_handler(int sig, const char *fmt, va_list ap)
|
|
{
|
|
#define MSG_MAXLEN 1024
|
|
char msg[MSG_MAXLEN] = {0};
|
|
vsnprintf(msg, MSG_MAXLEN, fmt, ap);
|
|
msg[MSG_MAXLEN-1] = '\0';
|
|
ereport(sig, (errmsg_internal("%s", msg)));
|
|
}
|
|
|
|
static void
|
|
pgsql_error(const char *fmt, va_list ap)
|
|
{
|
|
pgsql_msg_handler(ERROR, fmt, ap);
|
|
}
|
|
|
|
static void
|
|
pgsql_warn(const char *fmt, va_list ap)
|
|
{
|
|
pgsql_msg_handler(WARNING, fmt, ap);
|
|
}
|
|
|
|
static void
|
|
pgsql_info(const char *fmt, va_list ap)
|
|
{
|
|
pgsql_msg_handler(NOTICE, fmt, ap);
|
|
}
|
|
|
|
/* Module loading callback */
|
|
void _PG_init(void);
|
|
void
|
|
_PG_init(void)
|
|
{
|
|
elog(LOG, "Pointcloud (%s) module loaded", POINTCLOUD_VERSION);
|
|
pc_set_handlers(pgsql_alloc, pgsql_realloc,
|
|
pgsql_free, pgsql_error,
|
|
pgsql_info, pgsql_warn);
|
|
}
|
|
|
|
/* Module unload callback */
|
|
void _PG_fini(void);
|
|
void
|
|
_PG_fini(void)
|
|
{
|
|
elog(LOG, "Pointcloud (%s) module unloaded", POINTCLOUD_VERSION);
|
|
}
|
|
|
|
|
|
/**
|
|
* TODO: Back this routine with a statement level memory cache.
|
|
*/
|
|
PCSCHEMA *
|
|
pc_get_schema_by_id(uint32_t pcid)
|
|
{
|
|
char sql[256];
|
|
char *xml, *xml_spi;
|
|
int err;
|
|
size_t size;
|
|
PCSCHEMA *schema;
|
|
|
|
if (SPI_OK_CONNECT != SPI_connect ())
|
|
{
|
|
elog(NOTICE, "pc_get_schema_by_id: could not connect to SPI manager");
|
|
SPI_finish();
|
|
return NULL;
|
|
}
|
|
|
|
sprintf(sql, "select %s from %s where pcid = %d", POINTCLOUD_FORMATS, POINTCLOUD_FORMATS_XML, pcid);
|
|
err = SPI_exec(sql, 1);
|
|
|
|
if ( err < 0 )
|
|
{
|
|
elog(NOTICE, "pc_get_schema_by_id: error (%d) executing query: %s", err, sql);
|
|
SPI_finish();
|
|
return NULL;
|
|
}
|
|
|
|
/* No entry in POINTCLOUD_FORMATS */
|
|
if (SPI_processed <= 0)
|
|
{
|
|
SPI_finish();
|
|
return NULL;
|
|
}
|
|
|
|
/* Result */
|
|
xml_spi = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
|
|
|
|
/* NULL result */
|
|
if ( ! xml_spi )
|
|
{
|
|
SPI_finish();
|
|
return NULL;
|
|
}
|
|
|
|
/* Copy result to upper executor context */
|
|
size = strlen(xml_spi) + 1;
|
|
xml = SPI_palloc(size);
|
|
memcpy(xml, xml_spi, size);
|
|
|
|
/* Disconnect from SPI */
|
|
SPI_finish();
|
|
|
|
/* Build the schema object */
|
|
schema = pc_schema_from_xml(xml);
|
|
|
|
if ( ! schema )
|
|
{
|
|
elog(ERROR, "unable to parse XML representation of schema");
|
|
}
|
|
|
|
return schema;
|
|
}
|
|
|
|
|
|
|