Weird quirk with pg_dump of complex types

Started by Josh Berkusabout 17 years ago12 messagesbugs
Jump to latest
#1Josh Berkus
josh@agliodbs.com

All,

This is not so much a bug as a weird inconsistency, which ought to go on
a list somewhere so that it gets cleaned up the next time someone
overhauls pg_dump:

Summary: CREATE TYPE uses explicit schemas
Versions Tested: 8.2.9, 8.3.5
Platform: Linux
Description of Issue:

When doing pg_dump in text mode, complext types will be dumped like this:

CREATE TYPE complex_foo (
var INT,
gar TEXT,
natch public.foo_type
);

That is, a custom type in a complex type declaration is explicitly
schema-qualified, even when the schema in question is in the default
schema_path. This is inconsistent with all other database objects,
which use "SET search_path" to qualify the correct schemas.

This is only a real problem in that it may interfere with backup and/or
schema comparison automation (like I'm trying to write right now).

--Josh Berkus

#2Jeff Davis
pgsql@j-davis.com
In reply to: Josh Berkus (#1)
Re: Weird quirk with pg_dump of complex types

On Thu, 2009-02-26 at 15:25 -0800, Josh Berkus wrote:

That is, a custom type in a complex type declaration is explicitly
schema-qualified, even when the schema in question is in the default
schema_path. This is inconsistent with all other database objects,
which use "SET search_path" to qualify the correct schemas.

Strange. However, I don't think setting the search path will suffice,
because the different types could come from different schemas in a way
that makes it impossible.

Functions are similar, actually. The argument list needs to specify
schema paths as well, if it's not in some expected place (I think it
does so for all schemas other than pg_catalog).

Regards,
Jeff Davis

#3Josh Berkus
josh@agliodbs.com
In reply to: Jeff Davis (#2)
Re: Weird quirk with pg_dump of complex types

Jeff,

Functions are similar, actually. The argument list needs to specify
schema paths as well, if it's not in some expected place (I think it
does so for all schemas other than pg_catalog).

Except that they don't appear to do so.

--Josh

#4Jeff Davis
pgsql@j-davis.com
In reply to: Josh Berkus (#3)
Re: Weird quirk with pg_dump of complex types

On Thu, 2009-02-26 at 15:52 -0800, Josh Berkus wrote:

Jeff,

Functions are similar, actually. The argument list needs to specify
schema paths as well, if it's not in some expected place (I think it
does so for all schemas other than pg_catalog).

Except that they don't appear to do so.

Here is the case I'm talking about:

postgres=# create schema a;
CREATE SCHEMA
postgres=# create type a.int4 as (i pg_catalog.int4);
CREATE TYPE
postgres=# create function f1(x a.int4, y pg_catalog.int4) returns
pg_catalog.int4 language sql as $$ select 1; $$;
CREATE FUNCTION

-- pg_dump output:

SET search_path = public, pg_catalog;

...

CREATE FUNCTION f1(x a.int4, y integer) RETURNS integer
LANGUAGE sql
AS $$ select 1; $$;

So, there are some special cases somewhere so that the pg_dump output
isn't littered with unreadable "pg_catalog.int4" everywhere.

In the general case though, for any object that refers to multiple other
objects, I don't see any way around explicit schema qualification. I
suppose it could be smart and say "foo_type is unique in my search path,
so I don't need to schema-qualify it".

Have you considered working from the "custom" format rather than text?
I'm not sure whether it solves your problem, but I think it provides the
most information.

Regards,
Jeff Davis

#5Josh Berkus
josh@agliodbs.com
In reply to: Jeff Davis (#4)
Re: Weird quirk with pg_dump of complex types

Jeff,

In the general case though, for any object that refers to multiple other
objects, I don't see any way around explicit schema qualification. I
suppose it could be smart and say "foo_type is unique in my search path,
so I don't need to schema-qualify it".

Yeah, but for most other objects "public" is also excluded as well as
pg_catalog. For CREATE TYPE, "public" is explicit.

Have you considered working from the "custom" format rather than text?
I'm not sure whether it solves your problem, but I think it provides the
most information.

--Josh Berkus

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Josh Berkus (#1)
Re: Weird quirk with pg_dump of complex types

Josh Berkus <josh@agliodbs.com> writes:

When doing pg_dump in text mode, complext types will be dumped like this:

CREATE TYPE complex_foo (
var INT,
gar TEXT,
natch public.foo_type
);

You didn't say which schema "complex_foo" is in?

That is, a custom type in a complex type declaration is explicitly
schema-qualified, even when the schema in question is in the default
schema_path.

There is no such thing as a default search path for pg_dump's purposes.

regards, tom lane

#7Jeff Davis
pgsql@j-davis.com
In reply to: Josh Berkus (#5)
Re: Weird quirk with pg_dump of complex types

On Thu, 2009-02-26 at 21:42 -0800, Josh Berkus wrote:

Jeff,

In the general case though, for any object that refers to multiple other
objects, I don't see any way around explicit schema qualification. I
suppose it could be smart and say "foo_type is unique in my search path,
so I don't need to schema-qualify it".

Yeah, but for most other objects "public" is also excluded as well as
pg_catalog. For CREATE TYPE, "public" is explicit.

Ah, I see what you mean. Here's what I get when the type is named
public.integer (pg_dump output):

CREATE FUNCTION f1(x "integer", y integer) RETURNS integer
LANGUAGE sql
AS $$ select 1; $$;

and here's what I get when I try to be creative, and I define a
public.tsvector type (pg_dump output):

CREATE FUNCTION f1(x tsvector, y pg_catalog.tsvector) RETURNS integer
LANGUAGE sql
AS $$ select 1; $$;

It seems like pg_dump tries fairly hard to make the output readable in
the typical case. It does seem a little inconsistent that the list of
types that make up another type don't follow the exact same rules; I
don't know the reason for that.

Is using the custom format a possibility?

Regards,
Jeff Davis

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jeff Davis (#7)
Re: Weird quirk with pg_dump of complex types

Jeff Davis <pgsql@j-davis.com> writes:

It seems like pg_dump tries fairly hard to make the output readable in
the typical case. It does seem a little inconsistent that the list of
types that make up another type don't follow the exact same rules;

Are you entirely sure that they don't? Josh didn't provide enough
context to be sure, but I didn't see any clear proof in his example
that the type references were working any differently than they do
elsewhere in pg_dump.

The normal deal in pg_dump is that when dumping any given object,
the search path is set to that object's schema followed by pg_catalog.
So you will get a schema qualification for any reference to an object in
a different schema. Also, there are certain standard data types that
are spelled in special ways because The SQL Standard Says So.

regards, tom lane

#9Jeff Davis
pgsql@j-davis.com
In reply to: Tom Lane (#8)
Re: Weird quirk with pg_dump of complex types

On Fri, 2009-02-27 at 01:24 -0500, Tom Lane wrote:

Are you entirely sure that they don't?

Oh, you're right, of course:

postgres=# create type public.mytype as (i int);
CREATE TYPE
postgres=# create type public.mytype2 as (j mytype);
CREATE TYPE

-- pg_dump output:
CREATE TYPE mytype2 AS (
j mytype
);

Regards,
Jeff Davis

#10Josh Berkus
josh@agliodbs.com
In reply to: Tom Lane (#6)
Re: Weird quirk with pg_dump of complex types

Tom Lane wrote:

Josh Berkus <josh@agliodbs.com> writes:

When doing pg_dump in text mode, complext types will be dumped like this:

CREATE TYPE complex_foo (
var INT,
gar TEXT,
natch public.foo_type
);

You didn't say which schema "complex_foo" is in?

Public.

--Josh

#11Josh Berkus
josh@agliodbs.com
In reply to: Jeff Davis (#9)
Re: Weird quirk with pg_dump of complex types

Jeff Davis wrote:

On Fri, 2009-02-27 at 01:24 -0500, Tom Lane wrote:

Are you entirely sure that they don't?

Oh, you're right, of course:

postgres=# create type public.mytype as (i int);
CREATE TYPE
postgres=# create type public.mytype2 as (j mytype);
CREATE TYPE

-- pg_dump output:
CREATE TYPE mytype2 AS (
j mytype
);

Really?

Ok, I'll have to work up a reproduceable case, because I'm definitely
getting the "public" qualification in the create type.

--Josh

#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Josh Berkus (#11)
Re: Weird quirk with pg_dump of complex types

Josh Berkus <josh@agliodbs.com> writes:

Ok, I'll have to work up a reproduceable case, because I'm definitely
getting the "public" qualification in the create type.

Hmm, that shouldn't happen if the containing type is in "public",
so yeah, let's see the test case.

regards, tom lane