Thread: C function and NULL result

C function and NULL result

From
Victor Ivanov
Date:
Hi,

Sorry for the long message.

I'm using PostgreSQL 7.0.2 and I'm trying to create my own types with
input and output functions in C. Everything works fine, but when the input
is invalid and the function returns NULL, the backend crashes with SIGSEGV.

test.c:

#include <stdio.h>
#include <postgres.h>

typedef struct {
    int x, y;
} testtype;

testtype *testtype_in(char *str) {
    int x, y;
    char *ep;
    testtype *ret = NULL;

    x = strtol(str, &ep, 10);
    if (ep && *ep == ' ') {
    y = strtol(ep, &ep, 10);
    if (ep && (*ep == ' ' || *ep == 0)) {
        ret = (testtype *)palloc(sizeof(testtype));
        ret->x = x;
        ret->y = y;
    }
    }

    return ret;
}

char *testtype_out(testtype *tt) {
    char *ret;

    if (tt == NULL) return NULL;
    ret = (char *)palloc(32);
    snprintf(ret, 32, "%i %i", tt->x, tt->y);

    return ret;
}

compiled it with cc -o test.so -fPIC -shared test.c -I/usr/local/pgsql/include
(no errors)

from psql (logged as pgsql superuser):
CREATE FUNCTION testtype_in(opaque)
    RETURNS testtype
    AS '/usr/local/pgsql/test.so'
    LANGUAGE 'c';

CREATE FUNCTION testtype_out(opaque)
    RETURNS opaque
    AS '/usr/local/pgsql/test.so'
    LANGUAGE 'c';

CREATE TYPE testtype (
    internallength = 8,
    input = testtype_in,
    output = testtype_out);

(everything is ok)
CREATE TABLE test1 (test testtype);
(ok)
INSERT INTO test1 (test) values('4 5');
(ok)
SELECT * FROM test1;
returns one row, '4 5'

then I tried with invalid input:
INSERT INTO test1 (test) values('6');
pqReadData() -- backend closed the channel unexpectedly.
...
from the error log:
Server process (pid 25624) exited with status 11 at Tue Oct 17 13:17:58 2000

Actualy I'll access these tables in 'binary mode' so conversion functions
aren't needed... So I will make them return 'NULL' on error... Or is this
the right thing to do on error (according to the documentation it is not)?

Any help will be appreciated

--
Players win and Winners play
Have a lucky day

Attachment

Re: C function and NULL result

From
Tom Lane
Date:
Victor Ivanov <v0rbiz@icon.bg> writes:
> I'm using PostgreSQL 7.0.2 and I'm trying to create my own types with
> input and output functions in C. Everything works fine, but when the input
> is invalid and the function returns NULL, the backend crashes with SIGSEGV.

You can't return an SQL NULL by returning a NULL pointer.  Right now
there isn't a way for an input converter function to return NULL at all
(this is fixed for 7.1 though).  I'd recommend throwing an elog(ERROR)
if you don't like the input data.

            regards, tom lane

Re: C function and NULL result

From
Victor Ivanov
Date:
On Tue, Oct 17, 2000 at 11:58:50AM -0400, Tom Lane wrote:
> Victor Ivanov <v0rbiz@icon.bg> writes:
> > I'm using PostgreSQL 7.0.2 and I'm trying to create my own types with
> > input and output functions in C. Everything works fine, but when the input
> > is invalid and the function returns NULL, the backend crashes with SIGSEGV.
>
> You can't return an SQL NULL by returning a NULL pointer.  Right now
> there isn't a way for an input converter function to return NULL at all
> (this is fixed for 7.1 though).  I'd recommend throwing an elog(ERROR)
> if you don't like the input data.

Does elog(ERROR) stops the query? Now my functions return zero values for
illegal input. Anyway, I will use binary access to the data.. I wonder
how does an array look in binary? Is this an easy thing to find in the
source?

--
Players win and Winners play
Have a lucky day

Attachment

Re: C function and NULL result

From
Karel Zak
Date:
> On Tue, Oct 17, 2000 at 11:58:50AM -0400, Tom Lane wrote:
>
> Does elog(ERROR) stops the query? Now my functions return zero values for

 Yes, elog(ERROR) stops the query and inside transaction aborting it,
the elog(ERROR) jump out of your function to defined place (longjmp(3))
and backend wait for next query (if is not defined some other save stack).

The elog(FATAL) stops (abort) backend.

                    Karel

By the way (and a little OT), has anyone experience with using non-local
goto in multi-thread programs? I hope that here is not a problem :-)