Custom Domain; migration from 8.4 to 9.1 and COLLATE

Lists: pgsql-general
From: Evan Carroll <me(at)evancarroll(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 16:32:52
Message-ID: CAAiePB4n8oo3dKP8QVWKZ0o-n-xUsfYb9W5uB2b2GwYjb9GaYg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

This is a cross post from: http://dba.stackexchange.com/q/17609/2639

Just recently I upgraded from Postgresql 8.4.11 to 9.1.3. I used
pg_dump in the process. Now I'm getting an error:

> ERROR: no collation was derived for column "vin" with collatable type citext
> HINT: Use the COLLATE clause to set the collation explicitly.

This is a continuation of the [problem that I had
earlier](http://dba.stackexchange.com/q/17604/2639). It seems the fix
suggested in the Release Notes did not catch [custom
domains](http://www.postgresql.org/docs/9.1/interactive/sql-createdomain.html).
It seems as if the [CREATE
DOMAIN](http://www.postgresql.org/docs/8.3/interactive/sql-createdomain.html)
statement in 8.4 didn't even support the `COLLATE` clause.

This is how I created the `vin` type,

CREATE DOMAIN inventory.valid_vin AS citext
CHECK ( inventory.valid_vin( VALUE ) );

How do I best resolve this error?

--
Evan Carroll - me(at)evancarroll(dot)com
System Lord of the Internets
web: http://www.evancarroll.com
ph: 281.901.0011


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Evan Carroll <me(at)evancarroll(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 19:08:27
Message-ID: 22803.1336676907@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Evan Carroll <me(at)evancarroll(dot)com> writes:
> This is a cross post from: http://dba.stackexchange.com/q/17609/2639
> Just recently I upgraded from Postgresql 8.4.11 to 9.1.3. I used
> pg_dump in the process. Now I'm getting an error:

>> ERROR: no collation was derived for column "vin" with collatable type citext
>> HINT: Use the COLLATE clause to set the collation explicitly.

Could we see the complete context for this?

regards, tom lane


From: Evan Carroll <me(at)evancarroll(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 20:13:28
Message-ID: CAAiePB7HSQKi38mKSb83nzf8QgWFySFGysrM87KPcQiCiWG4Tg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

> Could we see the complete context for this?

Sure.
dealermade=# CREATE OR REPLACE TEMP VIEW chrome_vinmatch_best_match AS
dealermade-# SELECT DISTINCT ON (v.vin) v.vin, vd.*
dealermade-# FROM inventory.view_in_stock_vehicles AS v
dealermade-# JOIN chrome_vinmatch.view_vin_decode AS vd
dealermade-# ON substring(v.vin FROM 0 FOR 9) =
substring(vd.pattern FROM 0 FOR 9)
dealermade-# AND v.vin LIKE vd.pattern
dealermade-# ORDER BY vin, length(pattern) DESC
dealermade-# ;
ERROR: no collation was derived for column "vin" with collatable type citext
HINT: Use the COLLATE clause to set the collation explicitly.

v.vin is the column with the custom DOMAIN.

--
Evan Carroll - me(at)evancarroll(dot)com
System Lord of the Internets
web: http://www.evancarroll.com
ph: 281.901.0011


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Evan Carroll <me(at)evancarroll(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 20:56:07
Message-ID: 25894.1336683367@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Evan Carroll <me(at)evancarroll(dot)com> writes:
>> Could we see the complete context for this?
> Sure.
> dealermade=# CREATE OR REPLACE TEMP VIEW chrome_vinmatch_best_match AS
> dealermade-# SELECT DISTINCT ON (v.vin) v.vin, vd.*
> dealermade-# FROM inventory.view_in_stock_vehicles AS v
> dealermade-# JOIN chrome_vinmatch.view_vin_decode AS vd
> dealermade-# ON substring(v.vin FROM 0 FOR 9) =
> substring(vd.pattern FROM 0 FOR 9)
> dealermade-# AND v.vin LIKE vd.pattern
> dealermade-# ORDER BY vin, length(pattern) DESC
> dealermade-# ;
> ERROR: no collation was derived for column "vin" with collatable type citext
> HINT: Use the COLLATE clause to set the collation explicitly.

> v.vin is the column with the custom DOMAIN.

Hm, this example works fine for me in 9.1 branch tip, and I see no
relevant-looking patches in the commit logs since 9.1.3. What I suspect
is that you are being bit by the failure of 9.1.0 or 9.1.1 to set
pg_type.typcollation for the citext data type, as per this item in the
9.1.2 release notes:

Make contrib/citext's upgrade script fix collations of citext columns
and indexes (Tom Lane)

Existing citext columns and indexes aren't correctly marked as being
of a collatable data type during pg_upgrade from a pre-9.1
server. That leads to operations on them failing with errors such as
"could not determine which collation to use for string
comparison". This change allows them to be fixed by the same script
that upgrades the citext module into a proper 9.1 extension during
CREATE EXTENSION citext FROM unpackaged.

If you have a previously-upgraded database that is suffering from this
problem, and you already ran the CREATE EXTENSION command, you can
manually run (as superuser) the UPDATE commands found at the end of
SHAREDIR/extension/citext--unpackaged--1.0.sql. (Run pg_config
--sharedir if you're uncertain where SHAREDIR is.)

regards, tom lane


From: Evan Carroll <me(at)evancarroll(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 21:32:46
Message-ID: CAAiePB6Nmf9HRLD21X0M7FQuN3sXxQWDUsxZejZ1XY4DMq6ksw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

I did that, and I had to do that to get the error I pasted. I am hit
by that bug. I get this error after I fix that error. Here we my post
about the issue that you just mentioned:

* http://dba.stackexchange.com/q/17604/2639

BTW, The database version is 9.1.3. I'll try and work on a test that
generates this same error, not exactly sure why it is getting
generated though.

--
Evan Carroll - me(at)evancarroll(dot)com
System Lord of the Internets
web: http://www.evancarroll.com
ph: 281.901.0011


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Evan Carroll <me(at)evancarroll(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 22:12:14
Message-ID: 27677.1336687934@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Evan Carroll <me(at)evancarroll(dot)com> writes:
> BTW, The database version is 9.1.3. I'll try and work on a test that
> generates this same error, not exactly sure why it is getting
> generated though.

Also see whether you can reproduce the error in a fresh database.
I continue to think the problem is an incorrect collation value in
some system catalog entry; if that's it, nobody will be able to
reproduce it. You might try checking to see that there are no
un-updated rows matching those fixup queries.

regards, tom lane


From: Evan Carroll <me(at)evancarroll(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 23:03:52
Message-ID: CAAiePB6q7P9yc2Ctbvpctqy8ounTYKaoPqGBfTnxv9i1rav3rw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

> Also see whether you can reproduce the error in a fresh database.
> I continue to think the problem is an incorrect collation value in
> some system catalog entry; if that's it, nobody will be able to
> reproduce it.  You might try checking to see that there are no
> un-updated rows matching those fixup queries.

I've been able to reproduce it in a fresh database. This is a PSQL
script 2a and 2b will fail.

\echo CREATING DOMAIN footype

CREATE DOMAIN footype AS citext;

\echo [1a] CREATING TABLE tablefoo_before (contains columns bar, type footype)

CREATE TABLE tablefoo_before ( bar footype );

\echo [1b] CREATING TEMP TABLE trash AS SELECT * FROM tablefoo_before

CREATE TEMP TABLE trash AS SELECT * FROM tablefoo_before ;

\echo RUNING PATCH TO UPDATE citext

UPDATE pg_catalog.pg_type SET typcollation = 100
WHERE oid = 'citext'::pg_catalog.regtype;

UPDATE pg_catalog.pg_attribute SET attcollation = 100
WHERE atttypid = 'citext'::pg_catalog.regtype;

\echo [2a] CREATING TABLE tablefoo_after (contains columns bar, type footype)

CREATE TABLE tablefoo_after ( bar footype );

\echo [2b] CREATING TEMP TABLE trash2 AS SELECT * FROM tablefoo_before

CREATE TEMP TABLE trash2 AS SELECT * FROM tablefoo_before ;

--
Evan Carroll - me(at)evancarroll(dot)com
System Lord of the Internets
web: http://www.evancarroll.com
ph: 281.901.0011


From: Evan Carroll <me(at)evancarroll(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 23:08:19
Message-ID: CAAiePB7kddhUZyaNXqXM3kip3+uGS69ciQCE1DdRU30Dm9pkMA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

I think I can best get around this, if I issue a

> CREATE EXTENSION citext;

And, then load the database with the result of pg_dump. It seems to be
working, but there are some citext related statements from the dump
that fail because the stuff is already there in the DB when you issue
the CREATE EXTENSION.

--
Evan Carroll - me(at)evancarroll(dot)com
System Lord of the Internets
web: http://www.evancarroll.com
ph: 281.901.0011


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Evan Carroll <me(at)evancarroll(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 23:16:39
Message-ID: 12266.1336691799@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Evan Carroll <me(at)evancarroll(dot)com> writes:
> I've been able to reproduce it in a fresh database. This is a PSQL
> script 2a and 2b will fail.

Doesn't reproduce for me. I guess one question is how you are loading
citext into the "fresh" database --- maybe you are inheriting a bum copy
from template1?

But anyway, looking at this example makes me realize that there is an
oversight in the recommended update script: it does not consider the
possibility that it needs to fix domains over citext. Try doing
the updates with target type name equal to each such domain you have.

regards, tom lane


From: Evan Carroll <me(at)evancarroll(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 23:26:26
Message-ID: CAAiePB65mGuMt5=CGG4eteFPoHtmXYaQDUeVL9Qs2VPAKKdwhw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

> Doesn't reproduce for me.  I guess one question is how you are loading
> citext into the "fresh" database --- maybe you are inheriting a bum copy
> from template1?

That doesn't seem likely but it's possible. How can I tell?

Also, here is a copy of the complete script -- including the citext
creation statements from the dump, with the patch, with the bugged
statements.

https://gist.github.com/2656537

I'll reload the database the otherway and try to update the domain
with the same update statements.

--
Evan Carroll - me(at)evancarroll(dot)com
System Lord of the Internets
web: http://www.evancarroll.com
ph: 281.901.0011


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Evan Carroll <me(at)evancarroll(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Custom Domain; migration from 8.4 to 9.1 and COLLATE
Date: 2012-05-10 23:31:19
Message-ID: 15485.1336692679@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Evan Carroll <me(at)evancarroll(dot)com> writes:
> Also, here is a copy of the complete script -- including the citext
> creation statements from the dump, with the patch, with the bugged
> statements.

Well, if that's how you're creating citext, then yeah it's broken.
As of 9.1 the citext type needs to be created with the attribute
"COLLATABLE = true". The suggested UPDATE statements are a means
of correcting a failure to do that after-the-fact, but they don't
cover any domains that have already been created on top of citext.

regards, tom lane