Re: creating a new type in C - Mailing list pgsql-general
From | Gyorgy Molnar |
---|---|
Subject | Re: creating a new type in C |
Date | |
Msg-id | 001b01c27725$8ee98880$6e01a8c0@dell8100 Whole thread Raw |
In response to | creating a new type in C (Andrei Ivanov <andrei.ivanov@ines.ro>) |
List | pgsql-general |
Hello, I think you gave the answer for your question by yourself. In the XXX_in function you have only one args. You have to parse it and covert it into the proper format by yourself. The sample code (complex type) very good in the Postgres docs http://www.postgresql.org/idocs/index.php?xtypes.html Complex * complex_in(char *str) { double x, y; Complex *result; if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) { elog(ERROR, "complex_in: error in parsing %s", str); return NULL; } result = (Complex *)palloc(sizeof(Complex)); result->x = x; result->y = y; return (result); } It uses version 0 calling conversion in the sample, but the rest is the same. As you see the sscanf "C" library function is used to convert the argument string. In your case it is not going to work, becasue the sscanf in not good enough to make to conversion. The best way if you write a small function to make it for you. Best Regards, Yuri ----- Original Message ----- From: "Andrei Ivanov" <andrei.ivanov@ines.ro> To: <pgsql-general@postgresql.org> Sent: Friday, October 18, 2002 12:29 PM Subject: [GENERAL] creating a new type in C > > Hello, > I've been playing with a new type I want to create, but I got stuck, > therefore I ask for your assistance. > I don't know if this is the right list for this, if not please tell me > where to post my questions. > This is the source: > > #include "postgres.h" > #include "fmgr.h" > > typedef struct movie_property > { > int4 id; > char name[31]; > } movie_property; > > Datum movie_property_in(PG_FUNCTION_ARGS); > Datum movie_property_out(PG_FUNCTION_ARGS); > > PG_FUNCTION_INFO_V1(movie_property_in) > Datum movie_property_in(PG_FUNCTION_ARGS) > { > int4 id = PG_GETARG_INT32(0); > char *name = PG_GETARG_CSTRING(1); > movie_property *result; > result = (movie_property *) palloc(sizeof(movie_property)); > result->id = id; > strncpy(result->name, name, 30); > result->name[30] = 0; > PG_RETURN_POINTER(result); > } > > PG_FUNCTION_INFO_V1(movie_property_out) > Datum movie_property_out(PG_FUNCTION_ARGS) > { > movie_property *property = (movie_property *) PG_GETARG_POINTER(0); > char *result; > > if (property == NULL) > PG_RETURN_POINTER(NULL); > if ((result = (char *) palloc(40)) != NULL) > { > sprintf(result, "(%d,%s)", property->id, property->name); > } > PG_RETURN_CSTRING(result); > } > > Creating functions and type: > create function movie_property_in(opaque) > returns opaque > as '$libdir/movie_property' > language 'c'; > create function movie_property_out(opaque) > returns opaque > as '$libdir/movie_property' > language 'c'; > create type movie_property ( > internallength = 35, > input = movie_property_in, > output = movie_property_out > ); > CREATE TABLE pp (p movie_property); > INSERT INTO pp values('(1, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")'); > > The problem is with movie_property_in function. > When I try to obtain the id with PG_GETARG_INT32(0), > I don't get 1, but 138944104. > I tried and logged the result of PG_GETARG_CSTRING(0), and it seems it > returns the whole string (1, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"). > Please, tell me, how do I do this the right way ? > If you have any other comments regarding my code (I'm a C begginer), > they are welcomed. > > Postgresql version is 7.2.3 on a Gentoo Linux 1.2 > gcc version 2.95.3 20010315 > > > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/users-lounge/docs/faq.html
pgsql-general by date: