Home > Archive > PostgreSQL Discussion > May 2005 > Exception Handling in C-Language Functions?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Exception Handling in C-Language Functions?
Felix E. Klee

2005-05-21, 7:23 am

I have the created a C-Language function (code is below). Now, I
wonder: How do I handle exceptions, for example if malloc cannot assign
the necessary memory? Do "palloc" and "pfree" handle such a case
cleanly? Should I simply use an "assert"?

#include "postgres.h"
#include <string.h>
#include <stdlib.h>
#include "fmgr.h"
#include "libinn.h"

PG_FUNCTION_INFO_V1(
ffiinews_uwildmat);

/* Wrapper for INN's function uwildmat. Needs parameters in UTF-8. */
Datum ffiinews_uwildmat(PG
_FUNCTION_ARGS) {
VarChar *text = PG_GETARG_VARCHAR_P(
0);
VarChar *pattern = PG_GETARG_VARCHAR_P(
1);
int text_len = VARSIZE(text)-VARHDRSZ;
int pattern_len = VARSIZE(pattern)-VARHDRSZ;
char *tmp_text = (char *)malloc(text_len+1)
;
if (tmp_text == NULL)
; /* What now? */
char *tmp_pattern = (char *)malloc(pattern_len
+1);
if (tmp_pattern == NULL)
; /* What now? */
strncpy(tmp_text, VARDATA(text), text_len);
tmp_text[text_len] = '\0';
strncpy(tmp_pattern,
VARDATA(pattern), pattern_len);
tmp_pattern[pattern_len] = '\0';
bool matches = uwildmat(tmp_text, tmp_pattern);
free(tmp_pattern);
free(tmp_text);
PG_RETURN_BOOL(match
es);
}

--
Felix E. Klee

---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Neil Conway

2005-05-21, 7:23 am

Felix E. Klee wrote:
> I have the created a C-Language function (code is below). Now, I
> wonder: How do I handle exceptions, for example if malloc cannot assign
> the necessary memory? Do "palloc" and "pfree" handle such a case
> cleanly?


Yes -- they will roll back the current transaction on if there is no
memory available. You can catch the error via PG_TRY() in 8.0, although
in the case of OOM there isn't probably a lot your exception handler
could do...

-Neil

---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Felix E. Klee

2005-05-21, 7:23 am

At Sat, 21 May 2005 20:13:13 +1000,
Neil Conway wrote:
>
> Yes -- they will roll back the current transaction on if there is no
> memory available.


Great. So I just use those.

> You can catch the error via PG_TRY() in 8.0 [...]


Nice, but we're not deploying 8.0. However, at the moment, out of
memory exceptions seem to be the only ones that I've to deal with.

--
Felix E. Klee

---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faq

Tom Lane

2005-05-21, 9:23 am

"Felix E. Klee" <felix.klee@inka.de> writes:
> I have the created a C-Language function (code is below). Now, I
> wonder: How do I handle exceptions, for example if malloc cannot assign
> the necessary memory? Do "palloc" and "pfree" handle such a case
> cleanly? Should I simply use an "assert"?


As a general rule, never ever use malloc in backend code --- there's way
too much risk of causing a memory leak. (If your function for some
reason errors out before reaching the free(), that memory is gone.
Lather, rinse, repeat a few million times, as is not unlikely to happen
in a database server, and you've got a big problem.)

Use palloc instead. You don't have to check it for a failure return,
as Neil already noted, and you can be sloppy about remembering to free
the result ... in fact, there's no real reason to free it at all, since
anything palloc gives you inside a function will be short-term memory.
See src/backend/utils/mmgr/README for details.

If you want to report your own errors, use elog/ereport.

BTW, a more future-proof way of doing what you want:

> VarChar *text = PG_GETARG_VARCHAR_P(
0);
> int text_len = VARSIZE(text)-VARHDRSZ;
> char *tmp_text = (char *)malloc(text_len+1)
;
> if (tmp_text == NULL)
> ; /* What now? */
> strncpy(tmp_text, VARDATA(text), text_len);
> tmp_text[text_len] = '\0';


is to let the varchar output routine do it:

Datum text_datum = PG_GETARG_DATUM(0);
char *text;

text = DatumGetCString(Dire
ctFunctionCall1(varc
harout, text_datum));

This avoids assuming that you know the internal representation of
varchar (and if you think that's frozen for eternity, you haven't
been reading the discussions of ramping up our locale support...)

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match

Felix E. Klee

2005-05-22, 3:23 am

At Sat, 21 May 2005 10:30:47 -0400,
Tom Lane wrote:
> BTW, a more future-proof way of doing what you want:
>
>
> is to let the varchar output routine do it:
>
> Datum text_datum = PG_GETARG_DATUM(0);
> char *text;
>
> text = DatumGetCString(Dire
ctFunctionCall1(varc
harout, text_datum));
>
> This avoids assuming that you know the internal representation of
> varchar (and if you think that's frozen for eternity, you haven't been
> reading the discussions of ramping up our locale support...)


Thanks for all those hints! I've now adapted my code as you recommended
and it works fine, although I'm not certain what DirectFunctionCall1 and
DatumGetCString actually do (it seems that the only documentation of
these functions is in the source code, and I'm too lazy to sift through
it at the moment).

--
Felix E. Klee

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql
.org

greg landrum

2005-05-23, 11:23 am

Tom Lane wrote:
> "Felix E. Klee" <felix.klee@inka.de> writes:
>
> BTW, a more future-proof way of doing what you want:
>
>
>
>
> is to let the varchar output routine do it:
>
> Datum text_datum = PG_GETARG_DATUM(0);
> char *text;
>
> text = DatumGetCString(Dire
ctFunctionCall1(varc
harout, text_datum));
>
> This avoids assuming that you know the internal representation of
> varchar (and if you think that's frozen for eternity, you haven't
> been reading the discussions of ramping up our locale support...)


This form of dealing with arguments is interesting to learn about. Is
there any documentation of this stuff or do I need to dive into the source?

-greg
Tom Lane

2005-05-23, 11:23 am

greg landrum <greg.landrum@gmail.com> writes:
> Tom Lane wrote:
[color=darkred]
> This form of dealing with arguments is interesting to learn about. Is
> there any documentation of this stuff or do I need to dive into the source?


The original motivation for this notation is discussed in
src/backend/utils/fmgr/README, and there's some basic docs in the
main SGML documentation. Beyond that, looking at code that does
something close to what you want has always been the best guide ...

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org

Sponsored Links





Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive | Programming forum archive

Copyright 2008 droptable.com