aws / pg_tle

Framework for building trusted language extensions for PostgreSQL
Apache License 2.0
337 stars 31 forks source link

`pg_dump`/`pg_restore` default version dependency issue/interaction #245

Closed olirice closed 1 year ago

olirice commented 1 year ago

Description

pg_dump/pg_restore fails with

pg_restore: error: could not execute query: ERROR:  extension "<extension name>" has no installation script nor update path for version "<default version>"
Command was: CREATE EXTENSION IF NOT EXISTS "<extension name>" WITH SCHEMA public;

when the version of the extension that was installed is not the default version for the extension.

It appears that the dependency between the create extension <extension name> and the pgtle.<extension name>--<version>.sql link is tracked for the version that is installed, but not any of the alternate versions.

Since pg_dump files do not include a target version to install e.g.

create extension pg_foo;
-- vs: create extension pg_foo version '0.2';

it will attempt to install the default version, which may not have been defined via the pg_dump file.

Steps to reproduce

  1. Create an extension with multiple versions, installing non-default version
create extension if not exists pg_tle;

select pgtle.install_extension
(
 'pg_foo',
 '0.1',
 'foo',
$tle$ create function foo () returns int language sql as $$ select 1 $$; $tle$
);

select pgtle.install_extension_version_sql
(
 'pg_foo',
 '0.2',
$tle$ create function foo () returns int language sql as $$ select 1 $$; $tle$
);

-- Note: default version is still 0.1
--       we're installing v 0.2
create extension pg_foo version '0.2';
  1. pg_dump the database
    pg_dump -d <connstring> -Fp -f backup.sql

The backup.sql file looks like

-- Note: v 0.2 is defined before the call to `create extension`
CREATE FUNCTION pgtle."pg_foo--0.2.sql"() RETURNS text
    LANGUAGE sql
    AS $_X$SELECT $_pgtle_i_$ create function foo () returns int language sql as $$ select 1 $$; $_pgtle_i_$$_X$;

CREATE FUNCTION pgtle."pg_foo.control"() RETURNS text
    LANGUAGE sql
    AS $_X$SELECT $_pgtle_i_$
default_version = '0.1'  -- default version declared as 0.1
comment = 'foo'
relocatable = false
superuser = false
trusted = false
requires = 'pg_tle'
$_pgtle_i_$$_X$;

-- Note: version number is not listed, so pgtle (correctly) tries to install v 0.1
--       this crashes because v 0.1 is not yet defined
CREATE EXTENSION IF NOT EXISTS pg_foo WITH SCHEMA public;

-- Definition of v 0.1
CREATE FUNCTION pgtle."pg_foo--0.1.sql"() RETURNS text
    LANGUAGE sql
    AS $_X$SELECT $_pgtle_i_$ create function foo () returns int language sql as $$ select 1 $$; $_pgtle_i_$$_X$;

Expected outcome

Dependency links are tracked between TLE available versions and upgrade scripts such that they all appear before create extension <extension name> in pg_dump files.

Actual outcome

Only currently installed version of an extension is guaranteed to appear in the pg_dump before the create extension statement

adamguo0 commented 1 year ago

Thanks for reporting this issue! I've merged @imor's PR and cut a new tag: https://github.com/aws/pg_tle/releases/tag/v1.3.2