Re: Composite type versus Domain constraints.

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: James Robinson <jlrobins(at)socialserve(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Composite type versus Domain constraints.
Date: 2005-04-13 15:50:41
Message-ID: 7708.1113407441@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

James Robinson <jlrobins(at)socialserve(dot)com> writes:
> Thank you for the great info. If I may, here's another question. I am in
> the need of new scalar types, essentially domain'd smallints, hence
> why my composite type had but one composite member. Domain'd
> smallints would be great, but it seems when they get returned in a
> result set to the client, they come shipped with the oid of smallint
> (21 on my box), not the oid of the domain.

Yeah. IIRC that was a deliberate decision on the grounds that most
client software would probably break if we sent the domain OID.
Maybe we should reconsider, but I think the answer would be the same.

> Is there an easy path to creating (many) scalar types which piggyback
> on int2's functions. Naive experimentation fails:

> social=# create type MyType (
> INTERNALLENGTH = 2,
> INPUT = int2in,
> OUTPUT = int2out
> );
> ERROR: function int2out(mytype) does not exist

> Which is reasonable.

What you'd have to do is also create dummy I/O functions as aliases
for the internal int2in/out functions.

regression=# create function mytypein(cstring) returns mytype
regression-# as 'int2in' language internal strict immutable;
NOTICE: type "mytype" is not yet defined
DETAIL: Creating a shell type definition.
CREATE FUNCTION
regression=# create function mytypeout(mytype) returns cstring
regression-# as 'int2out' language internal strict immutable;
NOTICE: argument type mytype is only a shell
CREATE FUNCTION
regression=# create type mytype( input = mytypein, output = mytypeout,
regression(# internallength = 2, passedbyvalue, alignment = int2 );
CREATE TYPE
regression=# select '42'::mytype;
mytype
--------
42
(1 row)

regression=#

Note that it's absolutely critical that you get the size/alignment/byval
properties right ;-)

With suitable casts to/from int2 (probably implicit to int2, but not
implicit from), this would probably work fairly well.

regression=# select '42'::mytype + '42'::mytype;
ERROR: operator does not exist: mytype + mytype
HINT: No operator matches the given name and argument type(s). You may need to add explicit type casts.
regression=# create cast (mytype as int2) without function as implicit;
CREATE CAST
regression=# select '42'::mytype + '42'::mytype;
?column?
----------
84
(1 row)

regression=# create table zit(f1 mytype primary key);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "zit_pkey" for table "zit"
CREATE TABLE
regression=# \d zit
Table "public.zit"
Column | Type | Modifiers
--------+--------+-----------
f1 | mytype | not null
Indexes:
"zit_pkey" PRIMARY KEY, btree (f1 int2_ops)

regression=#

Sweet ... I wasn't actually expecting the index to work without more
hacking than that ...

regards, tom lane

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Bruno Wolff III 2005-04-13 16:00:02 Re: Foreign Keys Question
Previous Message Ying Lu 2005-04-13 15:49:56 About ERROR: could not convert UTF-8 character 0x00e9 to ISO8859-1