Re: Retroactively adding send and recv functions to a type?

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Johann 'Myrkraverk' Oskarsson" <johann(at)myrkraverk(dot)com>
Cc: pgsql-general(at)lists(dot)postgresql(dot)org
Subject: Re: Retroactively adding send and recv functions to a type?
Date: 2019-08-21 14:25:36
Message-ID: 30696.1566397536@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

"Johann 'Myrkraverk' Oskarsson" <johann(at)myrkraverk(dot)com> writes:
> The steps I took are

> create function sha1_send( sha1 ) returns bytea immutable
> language c strict as 'hashtypes', 'sha_send1';

> update pg_type set typsend = 'sha1_send'::regproc
> where typname = 'sha1';

> create function sha1_recv( internal ) returns sha1 immutable
> language c strict as 'hashtypes', 'sha_recv1';

> update pg_type set typreceive = 'sha1_recv'::regproc
> where typname = 'sha1';

Those updates don't look very safe: for instance, what if there's
another type named sha1 in some other schema? I'd do it like

-- create the functions
update pg_type set
typsend = 'sha1_send(sha1)'::regprocedure,
typreceive = 'sha1_recv(internal)'::regprocedure
where oid = 'sha1'::regtype;

This formulation only relies on your schema being frontmost in
the search path, which it should be during CREATE/ALTER EXTENSION.

> Then for completeness sake, I added two rows into pg_depend with

> insert into pg_depend ( classid, objid, objsubid, refclassid,
> refobjid, refobjsubid, deptype )
> values ( 'pg_type'::regclass::oid, 'sha1'::regtype::oid, 0,
> 'pg_proc'::regclass::oid, 'sha1_recv'::regproc::oid, 0, 'n' );

> insert into pg_depend ( classid, objid, objsubid, refclassid,
> refobjid, refobjsubid, deptype )
> values ( 'pg_type'::regclass::oid, 'sha1'::regtype::oid, 0,
> 'pg_proc'::regclass::oid, 'sha1_send'::regproc::oid, 0, 'n' );

You could skip the explicit casts to oid, and again I think use of
regprocedure would be safer than regproc. Seems fine otherwise.

> I did not dare to try before adding to pg_depend, but here's what
> happens when I try to drop function sha1_recv;

> ERROR: cannot drop function sha1_recv(internal) because other
> objects depend on it
> DETAIL: extension hashtypes depends on function sha1_recv(internal)
> column passwd of table pwned depends on type sha1
> function sha1_send(sha1) depends on type sha1

> Does this look correct?

It looks a bit odd, but I think that just indicates that you created the
two functions manually rather than inside an extension update script,
so they're not known to be part of the extension. You could experiment
with ALTER EXTENSION ADD to see if this output changes when they are
part of the extension. (But you don't need ALTER EXTENSION ADD when
you create them in an update script.)

regards, tom lane

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Day, David 2019-08-21 14:52:40 RE: Rename a column if not already renamed.?
Previous Message Johann 'Myrkraverk' Oskarsson 2019-08-21 12:31:16 Re: Retroactively adding send and recv functions to a type?