Обсуждение: Fwd: [GENERAL] returning CHAR from C function
Joe Conway confirmed this problem and said that it seems=20 that the function definition is rewritten to return 1042 (=3D=3Dbpchar), instead of type 18 (=3D=3Dchar). The workaround is to change the SQL definition to have=20 the function return "char" instead of char (no quotes). I think it is still a bug, though not high priority since it has a workaround. elein@varlena.com ---------- Forwarded Message ---------- Subject: [GENERAL] returning CHAR from C function Date: Sat, 30 Nov 2002 14:55:43 -0800 From: elein <elein@sbcglobal.net> To: pgsql-general@postgresql.org Cc: elein@varlena.com SuSE 7.3 Postgres7.3b5 I hope this is a simple user error. I am trying to return the first character of a text type in a C function. I did the obvious thing and it crashed the server. I stole text_char out of utils/adt/char.c and it crashed the server. I suspect I have some incorrect expectations of PG_RETURN_CHAR() or PG_RETURN_CHAR() maybe should call CharGetDatum, not DatumGetChar(). Or?? fmgr.h:#define PG_GETARG_CHAR(n) DatumGetChar(PG_GETARG_DATUM(n= )) postgres.h:#define DatumGetChar(X) ((char) GET_1_BYTE(X)) postgres.h:#define GET_1_BYTE(datum) (((Datum) (datum)) & 0x000000ff) postgres.h:#define CharGetDatum(X) ((Datum) SET_1_BYTE(X)) Code follows... Thanks, Elein ----- retchar.c --------------- /* * FUNCTION: input text/cstring, return char. # */ #include "postgres.h" #include "fmgr.h" PG_FUNCTION_INFO_V1(retchar); PG_FUNCTION_INFO_V1(retchar1); /* * Fetch first character of text. * Returns char */ Datum retchar( PG_FUNCTION_ARGS ) { text *val =3D (text *) PG_GETARG_TEXT_P(0); char retdata =3D *(VARDATA(val)) ; PG_RETURN_CHAR( retdata ); } /* Verbatim from utils/adt/char.c; changed name of function only; */ Datum retchar0(PG_FUNCTION_ARGS) { text *arg1 =3D PG_GETARG_TEXT_P(0); char result; /* * An empty input string is converted to \0 (for consistency with * charin). If the input is longer than one character, the excess data * is silently discarded. */ if (VARSIZE(arg1) > VARHDRSZ) result =3D *(VARDATA(arg1)); else result =3D '\0'; PG_RETURN_CHAR(result); } ----- retchar.sql --------------- -- -- retchar function definitions -- drop function retchar(text); create function retchar(text) returns char as '$libdir/retchar.so' language 'c'; drop function retchar0(text); create function retchar0(text) returns char as '$libdir/retchar.so' language 'c'; ---------- retchar_test.sql ------------- \echo both selects crash server select retchar('abc'); select retchar1('abc'); ---------------------------------------------------------------------------= ------------- elein@varlena.com Database Consulting www.varlena.com I have always depended on the [QA] of strangers.
elein <elein@sbcglobal.net> writes: > I think it is still a bug, Not unless you can define an upward-compatible migration path to some non-spec-conflicting typename (I'd favor char1, if we were going to rename the type). regards, tom lane
I think I do not know the background on this. Could you explain why the char type is converted to bpchar when a function is defined to return a char? Are only C functions affected? Is char as a type deprecated in favor of bpchar? Should something in the fmgr interface change to support this?=20=20 I thought that char was always one character and char(n) was similar to varchar(n) but with different=20 semantics wrt spaces. char1 works for me if char is really usurped by bpchar. We can take it off line except personal mail from me to you tends to bounce. I just want to understand this. Thanks, elein elein@varlena.com On Saturday 30 November 2002 20:44, you wrote: > elein <elein@sbcglobal.net> writes: > > I think it is still a bug, > > Not unless you can define an upward-compatible migration path to some > non-spec-conflicting typename (I'd favor char1, if we were going to > rename the type). > > regards, tom lane --=20 ---------------------------------------------------------------------------= ------------- elein@varlena.com Database Consulting www.varlena.com I have always depended on the [QA] of strangers.
elein <elein@sbcglobal.net> writes: > I think I do not know the background on this. I think it's mostly historical. The one-byte "char" datatype seems to date back to Berkeley days, long before there was any concern for SQL compliance (it's there in Postgres 4.2). "bpchar" was apparently added in Postgres95 in order to provide SQL-like functionality --- but they didn't pay any attention to duplicating the SQL name for it. The keyword CHARACTER was added later, translating it to the internal name bpchar in the parser. Eventually the keyword CHAR was added too, and translated. The real question at this point is what would break if we renamed "char" to "char1". Since it's used extensively in the system catalogs, I'm sure there would be some unhappiness involved. I am dubious that merely avoiding confusion is a sufficient reason to change. regards, tom lane
Thanks. This is helpful. The only inconsistency on the postgresql side is the PG_RETURN_CHAR which does return the one character, not the bpchar. Perhaps a PG_RETURN_CHAR1 or PG_RETURN_CHAR_REALLY would help. I think the only people who would get caught with it as it is are those writing C functions to retu= rn one character chars, so obviously documentation should be able to solve the inconsistency as well. elein On Sunday 01 December 2002 16:54, Tom Lane wrote: > elein <elein@sbcglobal.net> writes: > > I think I do not know the background on this. > > I think it's mostly historical. The one-byte "char" datatype seems to > date back to Berkeley days, long before there was any concern for SQL > compliance (it's there in Postgres 4.2). "bpchar" was apparently added > in Postgres95 in order to provide SQL-like functionality --- but they > didn't pay any attention to duplicating the SQL name for it. The > keyword CHARACTER was added later, translating it to the internal name > bpchar in the parser. Eventually the keyword CHAR was added too, and > translated. > > The real question at this point is what would break if we renamed "char" > to "char1". Since it's used extensively in the system catalogs, I'm > sure there would be some unhappiness involved. I am dubious that > merely avoiding confusion is a sufficient reason to change. > > regards, tom lane > > ---------------------------(end of broadcast)--------------------------- > TIP 3: if posting/reading through Usenet, please send an appropriate > subscribe-nomail command to majordomo@postgresql.org so that your > message can get through to the mailing list cleanly --=20 ---------------------------------------------------------------------------= ------------- elein@varlena.com Database Consulting www.varlena.com I have always depended on the [QA] of strangers.