Re: pg_dump search path issue - Mailing list pgsql-bugs
| From | Tom Lane |
|---|---|
| Subject | Re: pg_dump search path issue |
| Date | |
| Msg-id | 29492.1426039750@sss.pgh.pa.us Whole thread Raw |
| In response to | Re: pg_dump search path issue (Andrew Gierth <andrew@tao11.riddles.org.uk>) |
| List | pgsql-bugs |
Andrew Gierth <andrew@tao11.riddles.org.uk> writes:
> Just found (via a report on irc) a case that doesn't involve functions:
> create extension hstore;
> create schema foo
> create table t1 (a hstore, b integer)
> create table t2 (a hstore, c integer)
> create view v1 as select * from t1 join t2 using (a);
> dump/restore gives:
> ERROR: operator does not exist: public.hstore = public.hstore
Meh. We've discussed this case before, though I'm having a hard time
finding it in the archives tonight. I'm of the opinion that the real
problem here is that JOIN USING uses a name-based operator lookup at all.
Even disregarding the question of whether what you want is in the search
path, it's operating purely on faith that an operator named '=' will do
something appropriate. What it ought to be doing (and likewise CASE,
IS DISTINCT FROM, and anything else that's implicitly assuming that '='
is what to use) is looking for an operator associated with an appropriate
default btree opclass.
In the last go-round, I remember worrying that cross-type operators might
be a problem to identify this way, but a look in the system catalogs
doesn't find anything that seems like an issue. I'm envisioning a lookup
rule like this:
1. Find a default btree opclass that accepts the lefthand data type,
preferably exactly but if not that then binary-compatibly; fail if not
present or more than one binary-compatible candidate. (This is the same
rule used to identify how to build a btree index by default.)
2. Likewise for the righthand datatype.
3. These opclasses must belong to the same operator family, and there
must be a suitable equality operator in that opfamily, else fail.
AFAICT, the operators that would be selected by the existing rule
but not by this rule are just these:
db1=# select o.oid::regoperator, oprcode, cl.opcfamily, cr.opcfamily from pg_operator o
left join pg_opclass cl
on cl.opcintype=o.oprleft and cl.opcmethod = 403 and cl.opcdefault
left join pg_opclass cr
on cr.opcintype=o.oprright and cr.opcmethod = 403 and cr.opcdefault
where
oprname = '=' and
(cl.opcfamily is null or
cr.opcfamily is null or
cl.opcfamily != cr.opcfamily);
oid | oprcode | opcfamily | opcfamily
--------------------------+--------------+-----------+-----------
=(xid,xid) | xideq | |
=(xid,integer) | xideqint4 | | 1976
=(cid,cid) | cideq | |
=(int2vector,int2vector) | int2vectoreq | |
=(aclitem,aclitem) | aclitemeq | |
=(box,box) | box_eq | |
=(path,path) | path_n_eq | |
=(circle,circle) | circle_eq | |
=(lseg,lseg) | lseg_eq | |
=(line,line) | line_eq | |
(10 rows)
The first five of these are internal datatypes anyway; the other five are
fine examples of cases where you actively *don't want* the system silently
relying on them for JOIN/CASE/etc. Three of those aren't equality at all
by any sane definition, and the other two are fuzzy.
So I think this would be a good change and we should just bite the bullet
and do it...
regards, tom lane
pgsql-bugs by date: