Обсуждение: CAST function for user defined type

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

CAST function for user defined type

От
Ron Peterson
Дата:
I've created my own type: y_octet_16.  Now I'm trying to create a CAST
function for this type, but I'm not quite getting it.

The input function for my type takes a 32 char hex string as input.

CREATE TABLE bt (
  name
    TEXT
    NOT NULL,
  val
    y_octet_16
    NOT NULL
);

CREATE INDEX
  bt_val_ndx
ON
  bt( val );

-- this works
INSERT INTO
  bt( name, val )
VALUES
  ( 'aaa', 'abcdef1234567890abcdef1234567890' );

-- this doesn't work, with or without the cast
INSERT INTO
  bt( name, val )
VALUES
  ( 'aaa', encode( y_uuid_generate(), 'hex' )::y_byte_16 );

% INSERT INTO bt( name, val ) VALUES
  ( 'aaa', encode( y_uuid_generate(), 'hex' )::y_byte_16 );
ERROR:  type "y_byte_16" does not exist
LINE 4:   ( 'aaa', encode( y_uuid_generate(), 'hex' )::y_byte_16 )



I think my question is: where do I define y_byte_16 as a type that is
recognized by my CAST function?  What are the requirements on this
definition?  I have:



CREATE CAST
  (text AS y_octet_16)
WITH FUNCTION
  text_cast_to_y_octet_16( text );

PG_FUNCTION_INFO_V1(text_cast_to_y_octet_16);
Datum
text_cast_to_y_octet_16(PG_FUNCTION_ARGS)
{
   text *txtstr;
   char *octstr;

   if( PG_ARGISNULL(0) ) {
      PG_RETURN_NULL();
   }
   txtstr = PG_GETARG_TEXT_P(0);

   octstr = hex2bin_palloc( VARDATA(txtstr), 16 );

   PG_RETURN_POINTER( octstr );
}


TIA

--
Ron Peterson
https://www.yellowbank.com/

Re: CAST function for user defined type

От
Martijn van Oosterhout
Дата:
On Mon, Jan 22, 2007 at 09:44:52AM -0500, Ron Peterson wrote:
> I've created my own type: y_octet_16.  Now I'm trying to create a CAST
> function for this type, but I'm not quite getting it.

Quick question: do you mean:

>   val
>     y_octet_16
      ^^^^^^^^^^
> VALUES
>   ( 'aaa', encode( y_uuid_generate(), 'hex' )::y_byte_16 );
or                                               ^^^^^^^^^

I'm not sure from your example of the difference? byte vs octet.

Have a nice day,
--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.

Вложения

Re: CAST function for user defined type

От
Tom Lane
Дата:
Ron Peterson <ron.peterson@yellowbank.com> writes:
> I've created my own type: y_octet_16.  Now I'm trying to create a CAST
                            ^^^^^^^^^^

> % INSERT INTO bt( name, val ) VALUES
>   ( 'aaa', encode( y_uuid_generate(), 'hex' )::y_byte_16 );
> ERROR:  type "y_byte_16" does not exist
                ^^^^^^^^^

Are you sure this isn't just pilot error?

            regards, tom lane

Re: CAST function for user defined type

От
Ron Peterson
Дата:
On Mon, Jan 22, 2007 at 04:36:20PM +0100, Martijn van Oosterhout wrote:
> On Mon, Jan 22, 2007 at 09:44:52AM -0500, Ron Peterson wrote:
> > I've created my own type: y_octet_16.  Now I'm trying to create a CAST
> > function for this type, but I'm not quite getting it.
>
> Quick question: do you mean:
>
> >   val
> >     y_octet_16
>       ^^^^^^^^^^
> > VALUES
> >   ( 'aaa', encode( y_uuid_generate(), 'hex' )::y_byte_16 );
> or                                               ^^^^^^^^^
>
> I'm not sure from your example of the difference? byte vs octet.

Phghtht, I got tripped up by my own pedantry.  I'm using the specific
term 'octet' to refer to eight bits, rather than the colloquial 'byte',
but instinctively typed 'byte' in my cast.  So that's just a typo.

That cleared one hurdle, but I'm still not there yet.

% select encode( y_uuid_generate(), 'hex' );
              encode
----------------------------------
 fe43d07c0c624786bebfcb3357a2a13a
(1 row)

% select 'fe43d07c0c624786bebfcb3357a2a13a'::y_octet_16;
            y_octet_16
----------------------------------
 fe43d07c0c624786bebfcb3357a2a13a

That works, but if I cast the output of 'encode' directly as below, my
cast function doesn't work.  The error message indicates that it's not
seeing a hex string as input.  When things are connected up this way,
what should the cast function expect to see as input?

% select encode( y_uuid_generate(), 'hex' )::y_octet_16;
ERROR:  input string contains invalid characters

Best.

--
Ron Peterson
https://www.yellowbank.com/

Re: CAST function for user defined type

От
Tom Lane
Дата:
Ron Peterson <ron.peterson@yellowbank.com> writes:
> That cleared one hurdle, but I'm still not there yet.

> % select 'fe43d07c0c624786bebfcb3357a2a13a'::y_octet_16;
>             y_octet_16
> ----------------------------------
>  fe43d07c0c624786bebfcb3357a2a13a

That's not invoking any cast function, but the type's typinput function
(applied to a C-string).

> When things are connected up this way,
> what should the cast function expect to see as input?

> % select encode( y_uuid_generate(), 'hex' )::y_octet_16;
> ERROR:  input string contains invalid characters

If it's a cast from TEXT, it'll get the internal form of a TEXT datum,
ie, a counted (and not null-terminated) string.  You might look at
textin() and textout() to grok the difference.

            regards, tom lane

Re: CAST function for user defined type

От
Ron Peterson
Дата:
On Mon, Jan 22, 2007 at 11:40:08AM -0500, Tom Lane wrote:
> Ron Peterson <ron.peterson@yellowbank.com> writes:
> > That cleared one hurdle, but I'm still not there yet.
>
> > % select 'fe43d07c0c624786bebfcb3357a2a13a'::y_octet_16;
> >             y_octet_16
> > ----------------------------------
> >  fe43d07c0c624786bebfcb3357a2a13a
>
> That's not invoking any cast function, but the type's typinput function
> (applied to a C-string).
>
> > When things are connected up this way,
> > what should the cast function expect to see as input?
>
> > % select encode( y_uuid_generate(), 'hex' )::y_octet_16;
> > ERROR:  input string contains invalid characters
>
> If it's a cast from TEXT, it'll get the internal form of a TEXT datum,
> ie, a counted (and not null-terminated) string.  You might look at
> textin() and textout() to grok the difference.

Got it working now.  Thanks.

--
Ron Peterson
https://www.yellowbank.com/