Comment 2 for bug 1671150

Revision history for this message
Jeff Godin (jgodin) wrote :

At implied in the bug summary/title, and in the context of the pg_restore error output, the problem lies in the evergreen.unaccent_and_squash() function:

RETURN evergreen.lowercase(unaccent(regexp_replace(arg, '\s','','g')));

The call to unaccent() is unqualified, and relies on being executed in an environment where search_path contains a schema which contains unaccent().

In this scenario, pg_restore is not such an environment. At the point where these indexes are created, search_path has been explicitly set by pg_restore to contain only the actor and pg_catalog schemas.

In an Evergreen database, the unaccent extension is created in the public schema, so we would qualify the function call as public.unaccent():

RETURN evergreen.lowercase(public.unaccent(regexp_replace(arg, '\s','','g')));

This then reveals another unqualified reference issue: the default tsearch dictionary used by unaccent():

pg_restore: [archiver (db)] could not execute query: ERROR: text search dictionary "unaccent" does not exist
CONTEXT: PL/pgSQL function evergreen.unaccent_and_squash(text) line 3 at RETURN
    Command was: CREATE INDEX actor_usr_family_name_unaccent_idx ON usr USING btree (evergreen.unaccent_and_squash(family_name));

Thankfully, we can pass the fully qualified dictionary as an argument, which gives us:

RETURN evergreen.lowercase(public.unaccent('public.unaccent', regexp_replace(arg, '\s','','g')));

I think that the upgrade script for this will look like:

 - redefine the evergreen.unaccent_and_squash function to use fully qualified references to the unaccent function and unaccent dictionary

 - ensure that the four relevant indexes on actor.usr exist (because they may have been lost in a previous pg_dump/pg_restore)

The last bit can be done either by attempting to blindly create the indexes in a way that's tolerant of failures, or by dropping and re-creating them. There are a few ways to test for their existence beforehand, but doing so in a simple IF NOT EXISTS doesn't come along until Postgres 9.5.