return value of a version-1 C function (Solved)

From: Francesco Casadei <f_casadei(at)libero(dot)it>
To: pgsql-general(at)postgresql(dot)org
Subject: return value of a version-1 C function (Solved)
Date: 2001-06-05 13:40:25
Message-ID: 20010605154025.A410@goku.kasby
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

[This message refers to my previous post '[GENERAL] return value of a version-1
C function']

Ooops, I didn't read the docs very carefully! I solved the problem, by
declaring cod as a proper structure and then returning it with
PG_RETURN_BPCHAR_P(cod):

BpChar *cod = (BpChar *)SPI_palloc(VARHDRSZ + 8);
char c[9];
...
/* c = generated code (8 chars) + '\0' */
...
cod->vl_len = VARHDRSZ + 8;
memmove(VARDATA(cod), c, 8);

PG_RETURN_BPCHAR_P(cod);
}

Now I have three more questions!

1) SPI_connect() and SPI_finish() mark a new memory context; since I must
return cod I need to SPI_palloc() it in the upper Executor context. The
problem is: how can I free the SPI_palloc()'ed memory? I can't SPI_pfree() it
before PG_RETURN_BPCHAR_P(cod), conversely nothing after
PG_RETURN_BPCHAR_P(cod) would be executed. As stated in section 22.3 of the
PostgreSQL Programmer's Guide 'SPI has no ability to automatically free
allocations in the upper Executor context!', hence the question: how do I cope
with this situation?

2) If I use the VARSIZE(__PTR) macro (defined in postgres.h) to set the size of
cod, the compiler will complain about an invalid lvalue. This is not valid:

VARSIZE(cod) = VARHDRSZ + 8;

Can I safely use:

cod->vl_len = VARHDRSZ + 8;

or is this incorrect?

3) The following variable is an identifier (Name):

Name tablename = PG_GETARG_NAME(0);

If I want to retrieve the string contained in the union pointed to by
tablename I should use the macro NameStr(name) defined in c.h:

(void)strlcat(query, NameStr(fieldname), sizeof(query));

but again the compiler will complain with the error "request for member `data'
in something not a structure or union". Name is a pointer to NameData
union:

typedef union nameData
{
char data[NAMEDATALEN];
int alignmentDummy;
} NameData;
typedef NameData *Name;

NameStr is defined as:

#define NameStr(name) ((name).data)

but name is a pointer, so shouldn't NameStr be defined as:

#define NameStr(name) ((name)->data)

? Is it correct to use: tablename->data?

I attached the C code of the function. I'm not a C/PostgreSQL guru, so ANY
suggestion is welcome. Thanks in advance for your help.

Francesco Casadei

Attachment Content-Type Size
funland-funcs.c text/plain 2.4 KB

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Tom Lane 2001-06-05 13:57:46 Re: How to Alter tables with ARRAY? Help PLease
Previous Message Diego Naya 2001-06-05 13:37:34 Re: Re: FYI: status of native language support