Joe Conway confirmed this problem and said that it seems
that the function definition is rewritten to return
1042 (==bpchar), instead of type 18 (==char).

The workaround is to change the SQL definition to have
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 = (text *) PG_GETARG_TEXT_P(0);
char retdata = *(VARDATA(val)) ;
PG_RETURN_CHAR( retdata );
}

/* Verbatim from utils/adt/char.c; changed name of function only; */
Datum
retchar0(PG_FUNCTION_ARGS)
{
text *arg1 = 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 = *(VARDATA(arg1));
else
result = '\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.

Search Discussions

  • Tom Lane at Dec 1, 2002 at 4:45 am

    elein 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
  • Elein at Dec 2, 2002 at 12:38 am
    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?

    I thought that char was always one character and
    char(n) was similar to varchar(n) but with different
    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
    --
    ----------------------------------------------------------------------------------------
    elein@varlena.com Database Consulting www.varlena.com
    I have always depended on the [QA] of strangers.
  • Tom Lane at Dec 2, 2002 at 12:54 am

    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
  • Elein at Dec 2, 2002 at 11:26 pm
    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 return
    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
    --
    ----------------------------------------------------------------------------------------
    elein@varlena.com Database Consulting www.varlena.com
    I have always depended on the [QA] of strangers.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppgsql-bugs @
categoriespostgresql
postedDec 1, '02 at 12:48a
activeDec 2, '02 at 11:26p
posts5
users2
websitepostgresql.org
irc#postgresql

2 users in discussion

Elein: 3 posts Tom Lane: 2 posts

People

Translate

site design / logo © 2022 Grokbase