473,503 Members | 2,105 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C Programming with postgres.h - my function crashes the database backend

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 is typedef'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' LANGUAGE C;
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' LANGUAGE C;
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 <al*******@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

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/zNJdB0Yt5lXqNn4RAqXCAJoCfoEvJTLZcXss0b4acrdMkhAIAg CgqXEa
Wt8/m0Y/8vJRF3dzE9FCeM4=
=DXlV
-----END PGP SIGNATURE-----

Nov 12 '05 #1
5 4989
On Tue, Dec 02, 2003 at 05:56:45PM +0000, Alex Page wrote:
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 is typedef'd to "text" */
PG_RETURN_INT32( 0 );
}
PG_RETURN_INT32( 1 );
}


VARDATA is not 0-terminated, so you can't use strcmp on it. Maybe you
should use memcmp instead.

--
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"Nunca se desea ardientemente lo que solo se desea por razón" (F. Alexandre)

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

Nov 12 '05 #2
>
Datum enum_gender_in(PG_FUNCTION_ARGS) {
text *invalue = PG_GETARG_TEXT_P(0);

PG_FUNCTION_INFO_V1(enum_gender_out);

Datum enum_gender_out(PG_FUNCTION_ARGS) {
PG_RETURN_TEXT_P (outvalue);
}


IN function takes a C-string, not a text and
OUT functions should return C-string, not a text.
--
Teodor Sigaev E-mail: te****@sigaev.ru
---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faqs/FAQ.html

Nov 12 '05 #3
Alvaro Herrera wrote:
On Tue, Dec 02, 2003 at 05:56:45PM +0000, Alex Page wrote:
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 is typedef'd to "text" */
PG_RETURN_INT32( 0 );
}
PG_RETURN_INT32( 1 );
}


VARDATA is not 0-terminated, so you can't use strcmp on it. Maybe you
should use memcmp instead.


First of all, the argument to a type input procedure is a nul terminated
CString, not text.

Alex, why don't you look at an existing datatype in backend/utils/adt?
Jan

--
#================================================= =====================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================= = Ja******@Yahoo.com #
---------------------------(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

Nov 12 '05 #4
On Tue, Dec 02, 2003 at 01:54:06PM -0500, Jan Wieck wrote:
First of all, the argument to a type input procedure is a nul terminated
CString, not text.
Oops! Thanks for that, I'll see if I can get this working now.
Alex, why don't you look at an existing datatype in backend/utils/adt?


I don't seem to have this file in my Postgres installation. Is it
available somewhere?

Alex
--
Mail: Alex Page <al*******@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

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/zhYXB0Yt5lXqNn4RAjrfAKC7EH3cAco5AFzdMAye9M0aWWxgww CfXUP3
tyMgVkW6KlUwDylfCW9Nt+o=
=GFo5
-----END PGP SIGNATURE-----

Nov 12 '05 #5
Alex Page wrote:
On Tue, Dec 02, 2003 at 01:54:06PM -0500, Jan Wieck wrote:
First of all, the argument to a type input procedure is a nul terminated
CString, not text.


Oops! Thanks for that, I'll see if I can get this working now.
Alex, why don't you look at an existing datatype in backend/utils/adt?


I don't seem to have this file in my Postgres installation. Is it
available somewhere?


It is the directory of the PostgreSQL source tree where all the builtin
data types live and you can find it here:

http://developer.postgresql.org/cvsw...end/utils/adt/
Jan

--
#================================================= =====================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================= = Ja******@Yahoo.com #
---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

Nov 12 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
2158
by: Adam Kempa | last post by:
Hello I've been installed Postgres 7.4.2 on FreeBSD system and when load average grow up i've error in postgres like this: ERROR: permission denied for function varchar ERROR: permission...
0
1833
by: Myname | last post by:
Hello all, I was trying to write a simple function in c and include in postgres But am not able to do so I created a function with CREATE FUNCTION "lower1"(text) RETURNS text AS...
3
4165
by: N.K. | last post by:
Hi, I've just installed postgres on the Linux server. It is supposed to start automatically which I think it does since I can run an sql stmt right away. When I'm trying to connect from a remote...
0
2745
by: zerobearing2 | last post by:
Hi all- I'm migrating to postgres from the MS SQL Server land, as I can see a great potential with postgres, I was wondering if anyone has experimented or started a project with XML inside user...
3
1582
by: Alan | last post by:
I am coming from other programming tools field, and new to VB .NET. Just wondering what is the common approaching in database programming in VB .NET? 1) Are you guru always using the data aware...
17
4100
by: Josh Close | last post by:
I know this is kinda a debate, but how much ram do I give postgres? I've seen many places say around 10-15% or some say 25%....... If all this server is doing is running postgres, why can't I give...
6
3044
by: jao | last post by:
My company has a product in beta which uses Postgres 7.4.3. We expect to have a code freeze for our 1.0 product in March 2005. I'd really like to use Postgres 8.x in our 1.0 product. We're...
0
2685
by: NM | last post by:
Hello, I've got a problem inserting binary objects into the postgres database. I have binary objects (e.g. images or smth else) of any size which I want to insert into the database. Funny is it...
1
4353
by: micofarmer | last post by:
We are running a PHP web-based frontend with a Postgres 7.2 backend on a Windows 2000 Server box with automated backups of the server being handled by Legato. We are experiencing several problems...
0
7093
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7287
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
7006
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
4685
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3175
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3166
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1519
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
744
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
397
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.