From: | "Gene Selkov Jr(dot)" <selkovjr(at)selkovjr(dot)xnet(dot)com> |
---|---|
To: | Thomas Drillich <drillich(at)uniserve(dot)de> |
Cc: | pgsql-general(at)postgreSQL(dot)org |
Subject: | Re: [GENERAL] no primary key on self designed type |
Date: | 1999-12-07 20:57:48 |
Message-ID: | 199912072049.OAA22473@mail.xnet.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
> Hello,
>
> create type inrecord (
> internallength=VARIABLE,
> input=inr_in,
> output=inr_out
> );
>
> create table test (
> data inrecord not null primary key
> );
> ... result ...
> ERROR: Can't find a default operator class for type 268128.
>
> how can I define the default operator class ??
> --
The short answer is,
INSERT INTO pg_opclass (opcname, opcdeftype)
SELECT 'inrecord_ops', oid
FROM pg_type
WHERE typname = 'inrecord';
But you won't get away with just that. You probably want a non-empty
opclass. For example, if your type, inrecord, needs a btree opclass,
you'll want to do:
SELECT o.oid AS opoid, o.oprname
INTO TABLE inrecord_ops_tmp
FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = 'inrecord';
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 1,
'btreesel'::regproc, 'btreenpage'::regproc
FROM pg_am am, pg_opclass opcl, inrecord_ops_tmp c
WHERE amname = 'btree' and opcname = 'inrecord_ops'
and c.oprname = '<';
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 2,
'btreesel'::regproc, 'btreenpage'::regproc
FROM pg_am am, pg_opclass opcl, inrecord_ops_tmp c
WHERE amname = 'btree' and opcname = 'inrecord_ops'
and c.oprname = '<=';
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 3,
'btreesel'::regproc, 'btreenpage'::regproc
FROM pg_am am, pg_opclass opcl, inrecord_ops_tmp c
WHERE amname = 'btree' and opcname = 'inrecord_ops'
and c.oprname = '=';
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 4,
'btreesel'::regproc, 'btreenpage'::regproc
FROM pg_am am, pg_opclass opcl, inrecord_ops_tmp c
WHERE amname = 'btree' and opcname = 'inrecord_ops'
and c.oprname = '>=';
INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 5,
'btreesel'::regproc, 'btreenpage'::regproc
FROM pg_am am, pg_opclass opcl, inrecord_ops_tmp c
WHERE amname = 'btree' and opcname = 'inrecord_ops'
and c.oprname = '>';
DROP table inrecord_ops_tmp;
Which isn't all yet. The code above assumes that you have defined the
operators, '=', '>=', etc.:
CREATE OPERATOR = (
leftarg = inrecord, rightarg = inrecord_code, procedure = inrecord_eq,
restrict = eqsel, join = eqjoinsel
);
If that didn't make you sick already, you also need to define the
procedures, such as inrecord_eq in this example, and possibly write
some c code for them:
CREATE FUNCTION inrecord_eq(inrecord, inrecord) RETURNS bool
AS '${LIBDIR}/inrecord.so' LANGUAGE 'c';
INSERT INTO pg_description (objoid, description)
SELECT oid, 'equals'::text
FROM pg_proc
WHERE proname = 'inrecord_eq'::name;
Thar's, in short, what is required to build a completely new type. One
might as well attempt to borrow some code or the whole opclass from
existing similar types, but I would hesitate to even consider doing that
without the thorough knowledge of the current postgres schema, which
is unfortunately not yet covered by the contemporary docs.
--Gene
From | Date | Subject | |
---|---|---|---|
Next Message | Lamar Owen | 1999-12-07 21:00:39 | Re: Postgresql in win9x |
Previous Message | ymartin | 1999-12-07 19:07:55 | help |