[GENERAL] Fwd: SPI_palloc problem - Mailing list pgsql-general

From Aron Widforss
Subject [GENERAL] Fwd: SPI_palloc problem
Date
Msg-id 1509302424.3447951.1154724368.6B4BC75A@webmail.messagingengine.com
Whole thread Raw
Responses Re: [GENERAL] Fwd: SPI_palloc problem  (Aron Widforss <aron@antarkt.is>)
List pgsql-general
I mailed this from my main email address instead of the one I'm
subscribed to pgsql-general with. So, here goes.

----- Original message -----
From: Aron Widforss <aron@antarkt.is>
To: pgsql-general@postgresql.org
Subject: SPI_palloc problem
Date: Sun, 29 Oct 2017 19:35:30 +0100

Good evening,

I'm really new to PostgreSQL, and even C, but am trying to put together
a small pathfinding module to learn about it. Right now I'm just writing
a function to load my graph into a convenient data structure to use
later. I'm currently just loading the data of each vertice into my data
structure and then printing the loaded position out with elog(). It
works, but when I try to use SPI_palloc instead of palloc it disconnects
every time.

I suspect that my bug is really trivial, so maybe someone on this list
can just see what it is in the code and save me some time. :)

Regards,
Aron Widforss

Here is my version, example data and program:

pathfinding-hike=# SELECT version();                                                    version             

-----------------------------------------------------------------------------------------------------------------PostgreSQL
9.5.9on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609, 64-bit
 
(1 row)

----

pathfinding-hike=# SELECT * FROM toc LIMIT 10;node |       pos        | connected  |    length     |     costs     |
lines   
 
------+------------------+------------+---------------+---------------+------------   1 | {268582,6528365} | {2}
|{297}         | {297}         |   {1}   2 | {268773,6528472} | {1}        | {297}         | {297}         |   {1}   3
|{269103,6534918} | {15}       | {676}         | {676}         |   {2}   4 | {269436,6534931} | {12}       | {263}
  | {263}         |   {4}   5 | {269521,6534450} | {11}       | {373}         | {373}         |   {6}   6 |
{269535,6536629}| {28,22,7}  | {894,1508,66} | {894,1508,66} |   {7,3,8}   7 | {269542,6536693} | {6,9,9}    |
{66,657,218} | {66,657,218}  |   {8,5,9}   8 | {269585,6535610} | {14}       | {70}          | {70}          |   {10}
9| {269631,6536886} | {7,7,36}   | {657,218,584} | {657,218,584} |   {5,9,11}  10 | {269642,6534754} | {12,20,11} |
{137,140,6}  | {137,140,6}   |  {12,13,14}
 
(10 rows)

----

#include "postgres.h"
#include "utils/array.h"
#include "utils/lsyscache.h"
#include "catalog/pg_type.h"
#include "executor/spi.h"
#include "utils/builtins.h"

int check_err(int code);
int check_err(int code)
{   if(code < 0) {       elog(ERROR, "%m");   }   return code;
}

int32_t * get_int_arr(HeapTuple tuple, TupleDesc rowdesc, int fnumber);
int32_t * get_int_arr(HeapTuple tuple, TupleDesc rowdesc, int fnumber)
{   Datum     raw_arr;   ArrayType *pg_arr;   Datum     *c_arr;   bool      isnull;   /* Parameters for data alignment
*/  Oid       eltype;   int16     typlen;   bool      typbyval;   char      typalign;   /* Info about unwrapped array
*/  int32_t   *int_arr;   int       arr_len;   int       arr_dim;
 
   /* Get array raw-format */   raw_arr = SPI_getbinval(tuple, rowdesc, fnumber, &isnull);   check_err(SPI_result);
if(isnull){       elog(ERROR, "Cannot deconstruct null array");   }
 
   /* Get array db-format */   pg_arr  = DatumGetArrayTypeP(raw_arr);   arr_dim = ARR_NDIM(pg_arr);   eltype  =
ARR_ELEMTYPE(pg_arr);  //TODO: More thorough type checking has to be done in plpgsql   if(eltype != INT4OID) {
elog(ERROR,"Array not of type Integer");   }
 
   /* Get array as C-array (length prepended to 1st element) */   get_typlenbyvalalign(eltype, &typlen, &typbyval,
&typalign);  if(arr_dim != 1) {       elog(ERROR, "Cannot interpret multidimensional arrays");   }
deconstruct_array(pg_arr,eltype, typlen, typbyval, typalign,                     &c_arr, NULL, &arr_len);   int_arr =
palloc((arr_len+1)*sizeof(int32_t));  for(int i = 0; i<arr_len; i++) {       int_arr[i+1] = DatumGetInt32(c_arr[i]);
}  int_arr[0] = arr_len+1;
 
   return int_arr;
}   
uint32_t * get_uint_arr(HeapTuple tuple, TupleDesc rowdesc, int
fnumber);
uint32_t * get_uint_arr(HeapTuple tuple, TupleDesc rowdesc, int fnumber)
{   int32_t  *int_arr;   int_arr = get_int_arr(tuple, rowdesc, fnumber);
   for(int i = 1; i < int_arr[0]; i++) {       if(int_arr[i] < 0) {           elog(ERROR, "Unsigned int stored as
negativein database");       }   }
 
   return (uint32_t *)int_arr;
}                
PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(astarc);
Datum
astarc(PG_FUNCTION_ARGS)
{   int rows;
   typedef struct node node;   struct node {       int32_t *pos;       uint32_t *conn;       uint32_t *costs;
uint32_t*edges;   };
 
   struct node *graph;
   check_err(SPI_connect());   check_err(SPI_execute("SELECT * FROM toc", true, 10));   rows = SPI_processed;
   graph = palloc((rows + 1)*sizeof(node));   // Store size of array in first connected[]   graph[0].conn[0] = rows+1;
   if(rows > 0 && SPI_tuptable != NULL) {       TupleDesc tupdesc = SPI_tuptable->tupdesc;       SPITupleTable
*tuptable= SPI_tuptable;
 
       for (uint32_t i = 0; i < rows; i++) {           HeapTuple tuple = tuptable->vals[i];           graph[i].pos   =
get_int_arr(tuple,tupdesc, 2);           graph[i].conn  = get_uint_arr(tuple, tupdesc, 3);           graph[i].costs =
get_uint_arr(tuple,tupdesc, 5);           graph[i].edges = get_uint_arr(tuple, tupdesc, 6);
 
           elog(INFO, "x: %i, y: %i", graph[i].pos[1],           graph[i].pos[2]);       }   }
   if(rows == 0) {       elog(ERROR, "Graph not found");   }
   check_err(SPI_finish());
   PG_RETURN_TEXT_P(cstring_to_text("test"));
}


-- 
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

pgsql-general by date:

Previous
From: Karsten Hilbert
Date:
Subject: Re: [GENERAL] Where to find development builds of pg for windows
Next
From: Ron Johnson
Date:
Subject: [GENERAL] Old pg_clog files