C Programming with postgres.h - my function crashes the database backend - Mailing list pgsql-general

From Alex Page
Subject C Programming with postgres.h - my function crashes the database backend
Date
Msg-id 20031202175645.GW22296@halcyon.ox.icnet.uk
Whole thread Raw
Responses Re: C Programming with postgres.h - my function crashes the database backend
Re: C Programming with postgres.h - my function crashes
List pgsql-general
I've been trying to extend Postgres and create an enumerated type to
represent gender, as a precursor to more complex enumerated types. I've
created the C functions for input and output with the following code:

- ---- gender.c -----
  #include "server/postgres.h"
  #include <string.h>
  #include "server/fmgr.h"

  PG_FUNCTION_INFO_V1(enum_gender_in);

  Datum enum_gender_in(PG_FUNCTION_ARGS) {
      text    *invalue = PG_GETARG_TEXT_P(0);

      if ( strcmp ( VARDATA(invalue), "Male" ) ) {        /* VARDATA gets the data portion of a "varlena" struct, which
istypedef'd to "text" */ 
          PG_RETURN_INT32( 0 );
      }
      PG_RETURN_INT32( 1 );
  }

  PG_FUNCTION_INFO_V1(enum_gender_out);

  Datum enum_gender_out(PG_FUNCTION_ARGS) {
      int32    internal = PG_GETARG_INT32(0);
      text    *outvalue;

      if ( internal == 0 ) {
          int32 male_struct_size = 5 * sizeof(char) + VARHDRSZ;    /* Five characters ('Male\0') plus int32 */
          outvalue = (text *) palloc ( male_struct_size );
          VARATT_SIZEP(outvalue) = male_struct_size;
          memcpy(VARDATA(outvalue), "Male\0", 5);
      } else {
          int32 female_struct_size = 7 * sizeof(char) + VARHDRSZ;    /* Five characters ('Female\0') plus int32 */
          outvalue = (text *) palloc ( female_struct_size );
          VARATT_SIZEP(outvalue) = female_struct_size;
          memcpy(VARDATA(outvalue), "Female\0", 5);
      }
      PG_RETURN_TEXT_P (outvalue);
  }
- ---- end of gender.c -----

Once I've compiled this to a shared library file with no errors or
warnings (even with -Wall), I can load these functions in psql
without error, and create a table with the appropriate type:

  test=# CREATE FUNCTION enum_gender_in (cstring) RETURNS enum_gender IMMUTABLE STRICT AS '/home/alex/epic/gender.so'
LANGUAGEC; 
  NOTICE:  ProcedureCreate: type enum_gender is not yet defined
  CREATE FUNCTION

  test=# CREATE FUNCTION enum_gender_out (enum_gender) RETURNS cstring IMMUTABLE STRICT AS '/home/alex/epic/gender.so'
LANGUAGEC;  
  NOTICE:  Argument type "enum_gender" is only a shell
  CREATE FUNCTION

  test=# CREATE TYPE enum_gender (
  test(#         INPUT = enum_gender_in,
  test(#         OUTPUT = enum_gender_out,
  test(#         INTERNALLENGTH = 2,
  test(#         PASSEDBYVALUE
  test(# );
  CREATE TYPE

  test=# CREATE TABLE people (
  test(#         id      serial,
  test(#         name    text,
  test(#         gender  enum_gender
  test(# );
  NOTICE:  CREATE TABLE will create implicit sequence 'people_id_seq' for SERIAL column 'people.id'
  CREATE TABLE

So far so good. However, the real problem comes when I try to insert
something into the table I've just created:

  test=# INSERT INTO people (name, gender) VALUES ('Alex', 'Male');
  server closed the connection unexpectedly
          This probably means the server terminated abnormally
      before or while processing the request.
  The connection to the server was lost. Attempting reset: Failed.
  !#

I'm fairly sure there's a bug in my C code somewhere, but I can't spot
it. Admittedly, my C is pretty rusty, and I've not been able to find any
useful documentation for the internal C structures in postgres, other
than the source code itself. Any links to HOWTOs or similar would also
be appreciated.

Can I request a feature enhancement of built-in enumerated types for Postgres? ;)

Alex
--
Mail: Alex Page <alex.page@cancer.org.uk>
Real: Systems/Network Assistant, Epidemiology Unit, Oxford
Tel:  01865 302 223 (external) / 223 (internal)
PGP:  8868 21D7 3D35 DD77 9D06  BF0A 0746 2DE6 55EA 367E

Attachment

pgsql-general by date:

Previous
From: Franco Bruno Borghesi
Date:
Subject: Re: how many quotes?
Next
From: Alvaro Herrera
Date:
Subject: Re: C Programming with postgres.h - my function crashes the database backend