SPI_execute_with_args call

Started by Yuriy Rusinovalmost 13 years ago6 messagesgeneral
Jump to latest
#1Yuriy Rusinov
yrusinov@gmail.com

Hello, colleagues !

I have to write random number generator state into database table
Table structure is
table rand_state
{
id serial not null primary key,
state_rand bytea
};

In C-function I do
size_t nr_ins = strlen ("insert into rand_state (state_rand) values ($1);");
char * r_sql = (char *) palloc (nr_ins + 1);
strncpy (r_sql, "insert into rand_state (state_rand) values ($1);", nr_ins);

Oid * oids = (Oid *)palloc (sizeof (Oid));
Datum * val = PointerGetDatum (randBuf);
*oids = BYTEAOID;
const char * nulls = "NULL";
int rins = SPI_execute_with_args (r_sql, 1, oids, val, nulls, false, 1);

randBuf is a void * pointer that contains random number generator state,
when I try to execute SPI_execute_with_args (r_sql, 1, oids, val, nulls,
false, 1); I receive error
The connection to the server was lost. Attempting reset: Failed.
Could you give some work examples for SPI_execute_with_args because I
didn't find them in documentation.

Thanks a lot.

--
Best regards,
Sincerely yours,
Yuriy Rusinov.

#2Gavin Flower
GavinFlower@archidevsys.co.nz
In reply to: Yuriy Rusinov (#1)
Re: SPI_execute_with_args call

On 03/05/13 21:19, Yuriy Rusinov wrote:

Hello, colleagues !

I have to write random number generator state into database table
Table structure is
table rand_state
{
id serial not null primary key,
state_rand bytea
};

In C-function I do
size_t nr_ins = strlen ("insert into rand_state (state_rand) values
($1);");
char * r_sql = (char *) palloc (nr_ins + 1);
strncpy (r_sql, "insert into rand_state (state_rand) values ($1);",
nr_ins);

Oid * oids = (Oid *)palloc (sizeof (Oid));
Datum * val = PointerGetDatum (randBuf);
*oids = BYTEAOID;
const char * nulls = "NULL";
int rins = SPI_execute_with_args (r_sql, 1, oids, val, nulls, false, 1);

randBuf is a void * pointer that contains random number generator state,
when I try to execute SPI_execute_with_args (r_sql, 1, oids, val,
nulls, false, 1); I receive error
The connection to the server was lost. Attempting reset: Failed.
Could you give some work examples for SPI_execute_with_args because I
didn't find them in documentation.

Thanks a lot.

--
Best regards,
Sincerely yours,
Yuriy Rusinov.

I can't answer your question.

However, I can say that PRIMARY KEY implies NOT NULL (also an UNIQUE
index), so you don't need to explicitly add NOT NULL when you are
specifying PRIMARY KEY!

Cheers,
Gavin

#3Yuriy Rusinov
yrusinov@gmail.com
In reply to: Gavin Flower (#2)
Re: SPI_execute_with_args call

I'm sorry !

But if I commented SPI_execute_with_args call, then all others works
without bugs.

On Fri, May 3, 2013 at 2:31 PM, Gavin Flower
<GavinFlower@archidevsys.co.nz>wrote:

On 03/05/13 21:19, Yuriy Rusinov wrote:

Hello, colleagues !

I have to write random number generator state into database table
Table structure is
table rand_state
{
id serial not null primary key,
state_rand bytea
};

In C-function I do
size_t nr_ins = strlen ("insert into rand_state (state_rand) values
($1);");
char * r_sql = (char *) palloc (nr_ins + 1);
strncpy (r_sql, "insert into rand_state (state_rand) values ($1);",
nr_ins);

Oid * oids = (Oid *)palloc (sizeof (Oid));
Datum * val = PointerGetDatum (randBuf);
*oids = BYTEAOID;
const char * nulls = "NULL";
int rins = SPI_execute_with_args (r_sql, 1, oids, val, nulls, false, 1);

randBuf is a void * pointer that contains random number generator state,
when I try to execute SPI_execute_with_args (r_sql, 1, oids, val, nulls,
false, 1); I receive error
The connection to the server was lost. Attempting reset: Failed.
Could you give some work examples for SPI_execute_with_args because I
didn't find them in documentation.

Thanks a lot.

--
Best regards,
Sincerely yours,
Yuriy Rusinov.

I can't answer your question.

However, I can say that PRIMARY KEY implies NOT NULL (also an UNIQUE
index), so you don't need to explicitly add NOT NULL when you are specifying
PRIMARY KEY!

Cheers,
Gavin

--
Best regards,
Sincerely yours,
Yuriy Rusinov.

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Yuriy Rusinov (#1)
Re: SPI_execute_with_args call

Yuriy Rusinov <yrusinov@gmail.com> writes:

In C-function I do
size_t nr_ins = strlen ("insert into rand_state (state_rand) values ($1);");
char * r_sql = (char *) palloc (nr_ins + 1);
strncpy (r_sql, "insert into rand_state (state_rand) values ($1);", nr_ins);

This is a hard, error-prone, and ultimately incorrect way to do
pstrdup() --- you're not ensuring that the new string is
null-terminated.

Datum * val = PointerGetDatum (randBuf);

Didn't your compiler give you a warning about that? PointerGetDatum
produces a Datum, not a pointer to a Datum. You'd need something more
like

Datum val[1];
val[0] = PointerGetDatum (randBuf);

This is assuming that randBuf is even of the right format to be a bytea
value, which is unclear from your extract.

const char * nulls = "NULL";

And that's just wrong. Personally I'd just pass NULL to
SPI_execute_with_args since you don't have any null values to pass, but
if you don't want to do that you'd need something more like

char nulls[1];
nulls[0] = ' ';

(hmm, it looks like the SPI documentation leaves something to be desired
here --- the SPI_execute_with_args page, at least, isn't explaining the
convention for elements of the nulls[] array)

Could you give some work examples for SPI_execute_with_args because I
didn't find them in documentation.

A quick grep says there's a usage in src/pl/plpgsql/src/pl_exec.c

regards, tom lane

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

#5Yuriy Rusinov
yrusinov@gmail.com
In reply to: Tom Lane (#4)
Re: SPI_execute_with_args call

Thanks a lot, I have corrected and bug was fixed.

On Fri, May 3, 2013 at 6:42 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Yuriy Rusinov <yrusinov@gmail.com> writes:

In C-function I do
size_t nr_ins = strlen ("insert into rand_state (state_rand) values

($1);");

char * r_sql = (char *) palloc (nr_ins + 1);
strncpy (r_sql, "insert into rand_state (state_rand) values ($1);",

nr_ins);

This is a hard, error-prone, and ultimately incorrect way to do
pstrdup() --- you're not ensuring that the new string is
null-terminated.

Datum * val = PointerGetDatum (randBuf);

Didn't your compiler give you a warning about that? PointerGetDatum
produces a Datum, not a pointer to a Datum. You'd need something more
like

Datum val[1];
val[0] = PointerGetDatum (randBuf);

This is assuming that randBuf is even of the right format to be a bytea
value, which is unclear from your extract.

const char * nulls = "NULL";

And that's just wrong. Personally I'd just pass NULL to
SPI_execute_with_args since you don't have any null values to pass, but
if you don't want to do that you'd need something more like

char nulls[1];
nulls[0] = ' ';

(hmm, it looks like the SPI documentation leaves something to be desired
here --- the SPI_execute_with_args page, at least, isn't explaining the
convention for elements of the nulls[] array)

Could you give some work examples for SPI_execute_with_args because I
didn't find them in documentation.

A quick grep says there's a usage in src/pl/plpgsql/src/pl_exec.c

regards, tom lane

--
Best regards,
Sincerely yours,
Yuriy Rusinov.

#6Yuriy Rusinov
yrusinov@gmail.com
In reply to: Yuriy Rusinov (#5)
Re: SPI_execute_with_args call

Hello !

There is one's more question, which way I have to determine that void *
randBuf acceptable or not for bytea type ?

Thanks in advance.

On Fri, May 3, 2013 at 9:44 PM, Yuriy Rusinov <yrusinov@gmail.com> wrote:

Thanks a lot, I have corrected and bug was fixed.

On Fri, May 3, 2013 at 6:42 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Yuriy Rusinov <yrusinov@gmail.com> writes:

In C-function I do
size_t nr_ins = strlen ("insert into rand_state (state_rand) values

($1);");

char * r_sql = (char *) palloc (nr_ins + 1);
strncpy (r_sql, "insert into rand_state (state_rand) values ($1);",

nr_ins);

This is a hard, error-prone, and ultimately incorrect way to do
pstrdup() --- you're not ensuring that the new string is
null-terminated.

Datum * val = PointerGetDatum (randBuf);

Didn't your compiler give you a warning about that? PointerGetDatum
produces a Datum, not a pointer to a Datum. You'd need something more
like

Datum val[1];
val[0] = PointerGetDatum (randBuf);

This is assuming that randBuf is even of the right format to be a bytea
value, which is unclear from your extract.

const char * nulls = "NULL";

And that's just wrong. Personally I'd just pass NULL to
SPI_execute_with_args since you don't have any null values to pass, but
if you don't want to do that you'd need something more like

char nulls[1];
nulls[0] = ' ';

(hmm, it looks like the SPI documentation leaves something to be desired
here --- the SPI_execute_with_args page, at least, isn't explaining the
convention for elements of the nulls[] array)

Could you give some work examples for SPI_execute_with_args because I
didn't find them in documentation.

A quick grep says there's a usage in src/pl/plpgsql/src/pl_exec.c

regards, tom lane

--
Best regards,
Sincerely yours,
Yuriy Rusinov.

--
Best regards,
Sincerely yours,
Yuriy Rusinov.