Обсуждение: Fwd: [GENERAL] returning CHAR from C function

Поиск
Список
Период
Сортировка

Fwd: [GENERAL] returning CHAR from C function

От
elein
Дата:
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.

Re: Fwd: [GENERAL] returning CHAR from C function

От
Tom Lane
Дата:
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

Re: Fwd: [GENERAL] returning CHAR from C function

От
elein
Дата:
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.

Re: Fwd: [GENERAL] returning CHAR from C function

От
Tom Lane
Дата:
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

Re: Fwd: [GENERAL] returning CHAR from C function

От
elein
Дата:
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.