Hi,
Thanks for your very good review!
Ibrar Ahmed <[email protected]> writes:
> I looked at the discussion for this patch and the patch itself. Here
> are my comments and observations about the patch.
> What I got from the discussion is that the patch tries to implement a
> mechanism to install extension from series of SQL scripts from
> base/full version e.g. if a user wants to create an extension "1.1",
> system should run v1.0 script followed by 1.0--1.1 script. In that
> case we need to know about the base or full version which in the above
> case is v1.0. So the patch added a defualt_full_version option in
> extension control file.
Exactly, that was an idea from Robert and I implemented it quite
quickly. Too quickly as we can see from your testing report.
> Here are my comments about the patch
>
> * Note: Patch does not apply cleanly on latest code base. You probably
> need to re-base the code
Done. The thing is that meanwhile another solution to the main problem
has been found: drop support for installing hstore 1.0. Attached patch
fixes the problem by reinstalling hstore--1.0.sql and re-enabling this
version, and removing the hstore--1.1.sql file now that it's enough to
just have hstore--1.0--1.1.sql to install directly (and by default) the
newer version.
I think we will have to decide about taking only the mechanism or both
the mechanism and the actual change for the hstore contrib.
> * This is a user visible change so documentation change is required here.
Added coverage of the new parameter.
> * Also, You need to update the comment, because this code is now
> handling default_full_version as well.
>
> /*
> * Determine the (unpackaged) version to update from, if any, and then
> * figure out what sequence of update scripts we need to apply.
> */
> if ((d_old_version && d_old_version->arg) ||
> pcontrol->default_full_version)
Done. I also fixed the bugs you reported here. Here's an edited version
of the new (fixed) output:
dim=# set client_min_messages to debug1;
dim=# create extension hstore version '1.0';
DEBUG: execute_extension_script:
'/Users/dim/pgsql/ddl/share/extension/hstore--1.0.sql'
WARNING: => is deprecated as an operator name
CREATE EXTENSION
dim=# create extension hstore version '1.1';
DEBUG: execute_extension_script:
'/Users/dim/pgsql/ddl/share/extension/hstore--1.0.sql'
WARNING: => is deprecated as an operator name
DEBUG: execute_extension_script:
'/Users/dim/pgsql/ddl/share/extension/hstore--1.0--1.1.sql'
CREATE EXTENSION
dim=# create extension hstore;
DEBUG: execute_extension_script:
'/Users/dim/pgsql/ddl/share/extension/hstore--1.0.sql'
WARNING: => is deprecated as an operator name
DETAIL: This name may be disallowed altogether in future versions of
PostgreSQL.
DEBUG: execute_extension_script:
'/Users/dim/pgsql/ddl/share/extension/hstore--1.0--1.1.sql'
CREATE EXTENSION
> postgres=# CREATE EXTENSION hstore version '1.3' from '1.0';
> WARNING: /usr/local/pgsql/share/extension/hstore--1.0--1.1.sql
> WARNING: /usr/local/pgsql/share/extension/hstore--1.1--1.2.sql
> WARNING: /usr/local/pgsql/share/extension/hstore--1.2--1.3.sql
> CREATE EXTENSION
I liked your idea of extending the reporting about what files are used,
but of course we can't keep that at the WARNING level, so I made that
logging DEBUG1 in the attached patch.
> postgres=# CREATE EXTENSION hstore version '1.3' from '1.0';
Please try that case again, I believe it's fixed in the attached.
> - hstore regression is also failing.
That's because it doesn't cope anymore with the operator => warning, and
I left it this way because we have to decide about shipping hstore 1.0
once we have this patch in.
Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
*** a/contrib/hstore/Makefile
--- b/contrib/hstore/Makefile
***************
*** 5,11 **** OBJS = hstore_io.o hstore_op.o hstore_gist.o hstore_gin.o hstore_compat.o \
crc32.o
EXTENSION = hstore
! DATA = hstore--1.1.sql hstore--1.0--1.1.sql hstore--unpackaged--1.0.sql
REGRESS = hstore
--- 5,11 ----
crc32.o
EXTENSION = hstore
! DATA = hstore--1.0.sql hstore--1.0--1.1.sql hstore--unpackaged--1.0.sql
REGRESS = hstore
*** /dev/null
--- b/contrib/hstore/hstore--1.0.sql
***************
*** 0 ****
--- 1,530 ----
+ /* contrib/hstore/hstore--1.0.sql */
+
+ -- complain if script is sourced in psql, rather than via CREATE EXTENSION
+ \echo Use "CREATE EXTENSION hstore" to load this file. \quit
+
+ CREATE TYPE hstore;
+
+ CREATE FUNCTION hstore_in(cstring)
+ RETURNS hstore
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION hstore_out(hstore)
+ RETURNS cstring
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION hstore_recv(internal)
+ RETURNS hstore
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION hstore_send(hstore)
+ RETURNS bytea
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE TYPE hstore (
+ INTERNALLENGTH = -1,
+ INPUT = hstore_in,
+ OUTPUT = hstore_out,
+ RECEIVE = hstore_recv,
+ SEND = hstore_send,
+ STORAGE = extended
+ );
+
+ CREATE FUNCTION hstore_version_diag(hstore)
+ RETURNS integer
+ AS 'MODULE_PATHNAME','hstore_version_diag'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION fetchval(hstore,text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','hstore_fetchval'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR -> (
+ LEFTARG = hstore,
+ RIGHTARG = text,
+ PROCEDURE = fetchval
+ );
+
+ CREATE FUNCTION slice_array(hstore,text[])
+ RETURNS text[]
+ AS 'MODULE_PATHNAME','hstore_slice_to_array'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR -> (
+ LEFTARG = hstore,
+ RIGHTARG = text[],
+ PROCEDURE = slice_array
+ );
+
+ CREATE FUNCTION slice(hstore,text[])
+ RETURNS hstore
+ AS 'MODULE_PATHNAME','hstore_slice_to_hstore'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION isexists(hstore,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME','hstore_exists'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION exist(hstore,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME','hstore_exists'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR ? (
+ LEFTARG = hstore,
+ RIGHTARG = text,
+ PROCEDURE = exist,
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+ );
+
+ CREATE FUNCTION exists_any(hstore,text[])
+ RETURNS bool
+ AS 'MODULE_PATHNAME','hstore_exists_any'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR ?| (
+ LEFTARG = hstore,
+ RIGHTARG = text[],
+ PROCEDURE = exists_any,
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+ );
+
+ CREATE FUNCTION exists_all(hstore,text[])
+ RETURNS bool
+ AS 'MODULE_PATHNAME','hstore_exists_all'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR ?& (
+ LEFTARG = hstore,
+ RIGHTARG = text[],
+ PROCEDURE = exists_all,
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+ );
+
+ CREATE FUNCTION isdefined(hstore,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME','hstore_defined'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION defined(hstore,text)
+ RETURNS bool
+ AS 'MODULE_PATHNAME','hstore_defined'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION delete(hstore,text)
+ RETURNS hstore
+ AS 'MODULE_PATHNAME','hstore_delete'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION delete(hstore,text[])
+ RETURNS hstore
+ AS 'MODULE_PATHNAME','hstore_delete_array'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION delete(hstore,hstore)
+ RETURNS hstore
+ AS 'MODULE_PATHNAME','hstore_delete_hstore'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR - (
+ LEFTARG = hstore,
+ RIGHTARG = text,
+ PROCEDURE = delete
+ );
+
+ CREATE OPERATOR - (
+ LEFTARG = hstore,
+ RIGHTARG = text[],
+ PROCEDURE = delete
+ );
+
+ CREATE OPERATOR - (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = delete
+ );
+
+ CREATE FUNCTION hs_concat(hstore,hstore)
+ RETURNS hstore
+ AS 'MODULE_PATHNAME','hstore_concat'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR || (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hs_concat
+ );
+
+ CREATE FUNCTION hs_contains(hstore,hstore)
+ RETURNS bool
+ AS 'MODULE_PATHNAME','hstore_contains'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION hs_contained(hstore,hstore)
+ RETURNS bool
+ AS 'MODULE_PATHNAME','hstore_contained'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR @> (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hs_contains,
+ COMMUTATOR = '<@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+ );
+
+ CREATE OPERATOR <@ (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hs_contained,
+ COMMUTATOR = '@>',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+ );
+
+ -- obsolete:
+ CREATE OPERATOR @ (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hs_contains,
+ COMMUTATOR = '~',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+ );
+
+ CREATE OPERATOR ~ (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hs_contained,
+ COMMUTATOR = '@',
+ RESTRICT = contsel,
+ JOIN = contjoinsel
+ );
+
+ CREATE FUNCTION tconvert(text,text)
+ RETURNS hstore
+ AS 'MODULE_PATHNAME','hstore_from_text'
+ LANGUAGE C IMMUTABLE; -- not STRICT; needs to allow (key,NULL)
+
+ CREATE FUNCTION hstore(text,text)
+ RETURNS hstore
+ AS 'MODULE_PATHNAME','hstore_from_text'
+ LANGUAGE C IMMUTABLE; -- not STRICT; needs to allow (key,NULL)
+
+ CREATE OPERATOR => (
+ LEFTARG = text,
+ RIGHTARG = text,
+ PROCEDURE = hstore
+ );
+
+ CREATE FUNCTION hstore(text[],text[])
+ RETURNS hstore
+ AS 'MODULE_PATHNAME', 'hstore_from_arrays'
+ LANGUAGE C IMMUTABLE; -- not STRICT; allows (keys,null)
+
+ CREATE FUNCTION hstore(text[])
+ RETURNS hstore
+ AS 'MODULE_PATHNAME', 'hstore_from_array'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE CAST (text[] AS hstore)
+ WITH FUNCTION hstore(text[]);
+
+ CREATE FUNCTION hstore(record)
+ RETURNS hstore
+ AS 'MODULE_PATHNAME', 'hstore_from_record'
+ LANGUAGE C IMMUTABLE; -- not STRICT; allows (null::recordtype)
+
+ CREATE FUNCTION hstore_to_array(hstore)
+ RETURNS text[]
+ AS 'MODULE_PATHNAME','hstore_to_array'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR %% (
+ RIGHTARG = hstore,
+ PROCEDURE = hstore_to_array
+ );
+
+ CREATE FUNCTION hstore_to_matrix(hstore)
+ RETURNS text[]
+ AS 'MODULE_PATHNAME','hstore_to_matrix'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR %# (
+ RIGHTARG = hstore,
+ PROCEDURE = hstore_to_matrix
+ );
+
+ CREATE FUNCTION akeys(hstore)
+ RETURNS text[]
+ AS 'MODULE_PATHNAME','hstore_akeys'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION avals(hstore)
+ RETURNS text[]
+ AS 'MODULE_PATHNAME','hstore_avals'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION skeys(hstore)
+ RETURNS setof text
+ AS 'MODULE_PATHNAME','hstore_skeys'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION svals(hstore)
+ RETURNS setof text
+ AS 'MODULE_PATHNAME','hstore_svals'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION each(IN hs hstore,
+ OUT key text,
+ OUT value text)
+ RETURNS SETOF record
+ AS 'MODULE_PATHNAME','hstore_each'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION populate_record(anyelement,hstore)
+ RETURNS anyelement
+ AS 'MODULE_PATHNAME', 'hstore_populate_record'
+ LANGUAGE C IMMUTABLE; -- not STRICT; allows (null::rectype,hstore)
+
+ CREATE OPERATOR #= (
+ LEFTARG = anyelement,
+ RIGHTARG = hstore,
+ PROCEDURE = populate_record
+ );
+
+ -- btree support
+
+ CREATE FUNCTION hstore_eq(hstore,hstore)
+ RETURNS boolean
+ AS 'MODULE_PATHNAME','hstore_eq'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION hstore_ne(hstore,hstore)
+ RETURNS boolean
+ AS 'MODULE_PATHNAME','hstore_ne'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION hstore_gt(hstore,hstore)
+ RETURNS boolean
+ AS 'MODULE_PATHNAME','hstore_gt'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION hstore_ge(hstore,hstore)
+ RETURNS boolean
+ AS 'MODULE_PATHNAME','hstore_ge'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION hstore_lt(hstore,hstore)
+ RETURNS boolean
+ AS 'MODULE_PATHNAME','hstore_lt'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION hstore_le(hstore,hstore)
+ RETURNS boolean
+ AS 'MODULE_PATHNAME','hstore_le'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION hstore_cmp(hstore,hstore)
+ RETURNS integer
+ AS 'MODULE_PATHNAME','hstore_cmp'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR = (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hstore_eq,
+ COMMUTATOR = =,
+ NEGATOR = <>,
+ RESTRICT = eqsel,
+ JOIN = eqjoinsel,
+ MERGES,
+ HASHES
+ );
+ CREATE OPERATOR <> (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hstore_ne,
+ COMMUTATOR = <>,
+ NEGATOR = =,
+ RESTRICT = neqsel,
+ JOIN = neqjoinsel
+ );
+
+ -- the comparison operators have funky names (and are undocumented)
+ -- in an attempt to discourage anyone from actually using them. they
+ -- only exist to support the btree opclass
+
+ CREATE OPERATOR #<# (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hstore_lt,
+ COMMUTATOR = #>#,
+ NEGATOR = #>=#,
+ RESTRICT = scalarltsel,
+ JOIN = scalarltjoinsel
+ );
+ CREATE OPERATOR #<=# (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hstore_le,
+ COMMUTATOR = #>=#,
+ NEGATOR = #>#,
+ RESTRICT = scalarltsel,
+ JOIN = scalarltjoinsel
+ );
+ CREATE OPERATOR #># (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hstore_gt,
+ COMMUTATOR = #<#,
+ NEGATOR = #<=#,
+ RESTRICT = scalargtsel,
+ JOIN = scalargtjoinsel
+ );
+ CREATE OPERATOR #>=# (
+ LEFTARG = hstore,
+ RIGHTARG = hstore,
+ PROCEDURE = hstore_ge,
+ COMMUTATOR = #<=#,
+ NEGATOR = #<#,
+ RESTRICT = scalargtsel,
+ JOIN = scalargtjoinsel
+ );
+
+ CREATE OPERATOR CLASS btree_hstore_ops
+ DEFAULT FOR TYPE hstore USING btree
+ AS
+ OPERATOR 1 #<# ,
+ OPERATOR 2 #<=# ,
+ OPERATOR 3 = ,
+ OPERATOR 4 #>=# ,
+ OPERATOR 5 #># ,
+ FUNCTION 1 hstore_cmp(hstore,hstore);
+
+ -- hash support
+
+ CREATE FUNCTION hstore_hash(hstore)
+ RETURNS integer
+ AS 'MODULE_PATHNAME','hstore_hash'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE OPERATOR CLASS hash_hstore_ops
+ DEFAULT FOR TYPE hstore USING hash
+ AS
+ OPERATOR 1 = ,
+ FUNCTION 1 hstore_hash(hstore);
+
+ -- GiST support
+
+ CREATE TYPE ghstore;
+
+ CREATE FUNCTION ghstore_in(cstring)
+ RETURNS ghstore
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE FUNCTION ghstore_out(ghstore)
+ RETURNS cstring
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C STRICT IMMUTABLE;
+
+ CREATE TYPE ghstore (
+ INTERNALLENGTH = -1,
+ INPUT = ghstore_in,
+ OUTPUT = ghstore_out
+ );
+
+ CREATE FUNCTION ghstore_compress(internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION ghstore_decompress(internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION ghstore_penalty(internal,internal,internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION ghstore_picksplit(internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION ghstore_union(internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION ghstore_same(internal, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION ghstore_consistent(internal,internal,int,oid,internal)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE OPERATOR CLASS gist_hstore_ops
+ DEFAULT FOR TYPE hstore USING gist
+ AS
+ OPERATOR 7 @> ,
+ OPERATOR 9 ?(hstore,text) ,
+ OPERATOR 10 ?|(hstore,text[]) ,
+ OPERATOR 11 ?&(hstore,text[]) ,
+ --OPERATOR 8 <@ ,
+ OPERATOR 13 @ ,
+ --OPERATOR 14 ~ ,
+ FUNCTION 1 ghstore_consistent (internal, internal, int, oid, internal),
+ FUNCTION 2 ghstore_union (internal, internal),
+ FUNCTION 3 ghstore_compress (internal),
+ FUNCTION 4 ghstore_decompress (internal),
+ FUNCTION 5 ghstore_penalty (internal, internal, internal),
+ FUNCTION 6 ghstore_picksplit (internal, internal),
+ FUNCTION 7 ghstore_same (internal, internal, internal),
+ STORAGE ghstore;
+
+ -- GIN support
+
+ CREATE FUNCTION gin_extract_hstore(internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION gin_extract_hstore_query(internal, internal, int2, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION gin_consistent_hstore(internal, int2, internal, int4, internal, internal)
+ RETURNS bool
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE OPERATOR CLASS gin_hstore_ops
+ DEFAULT FOR TYPE hstore USING gin
+ AS
+ OPERATOR 7 @>,
+ OPERATOR 9 ?(hstore,text),
+ OPERATOR 10 ?|(hstore,text[]),
+ OPERATOR 11 ?&(hstore,text[]),
+ FUNCTION 1 bttextcmp(text,text),
+ FUNCTION 2 gin_extract_hstore(internal, internal),
+ FUNCTION 3 gin_extract_hstore_query(internal, internal, int2, internal, internal),
+ FUNCTION 4 gin_consistent_hstore(internal, int2, internal, int4, internal, internal),
+ STORAGE text;
*** a/contrib/hstore/hstore--1.1.sql
--- /dev/null
***************
*** 1,524 ****
- /* contrib/hstore/hstore--1.1.sql */
-
- -- complain if script is sourced in psql, rather than via CREATE EXTENSION
- \echo Use "CREATE EXTENSION hstore" to load this file. \quit
-
- CREATE TYPE hstore;
-
- CREATE FUNCTION hstore_in(cstring)
- RETURNS hstore
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION hstore_out(hstore)
- RETURNS cstring
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION hstore_recv(internal)
- RETURNS hstore
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION hstore_send(hstore)
- RETURNS bytea
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE TYPE hstore (
- INTERNALLENGTH = -1,
- INPUT = hstore_in,
- OUTPUT = hstore_out,
- RECEIVE = hstore_recv,
- SEND = hstore_send,
- STORAGE = extended
- );
-
- CREATE FUNCTION hstore_version_diag(hstore)
- RETURNS integer
- AS 'MODULE_PATHNAME','hstore_version_diag'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION fetchval(hstore,text)
- RETURNS text
- AS 'MODULE_PATHNAME','hstore_fetchval'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR -> (
- LEFTARG = hstore,
- RIGHTARG = text,
- PROCEDURE = fetchval
- );
-
- CREATE FUNCTION slice_array(hstore,text[])
- RETURNS text[]
- AS 'MODULE_PATHNAME','hstore_slice_to_array'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR -> (
- LEFTARG = hstore,
- RIGHTARG = text[],
- PROCEDURE = slice_array
- );
-
- CREATE FUNCTION slice(hstore,text[])
- RETURNS hstore
- AS 'MODULE_PATHNAME','hstore_slice_to_hstore'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION isexists(hstore,text)
- RETURNS bool
- AS 'MODULE_PATHNAME','hstore_exists'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION exist(hstore,text)
- RETURNS bool
- AS 'MODULE_PATHNAME','hstore_exists'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR ? (
- LEFTARG = hstore,
- RIGHTARG = text,
- PROCEDURE = exist,
- RESTRICT = contsel,
- JOIN = contjoinsel
- );
-
- CREATE FUNCTION exists_any(hstore,text[])
- RETURNS bool
- AS 'MODULE_PATHNAME','hstore_exists_any'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR ?| (
- LEFTARG = hstore,
- RIGHTARG = text[],
- PROCEDURE = exists_any,
- RESTRICT = contsel,
- JOIN = contjoinsel
- );
-
- CREATE FUNCTION exists_all(hstore,text[])
- RETURNS bool
- AS 'MODULE_PATHNAME','hstore_exists_all'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR ?& (
- LEFTARG = hstore,
- RIGHTARG = text[],
- PROCEDURE = exists_all,
- RESTRICT = contsel,
- JOIN = contjoinsel
- );
-
- CREATE FUNCTION isdefined(hstore,text)
- RETURNS bool
- AS 'MODULE_PATHNAME','hstore_defined'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION defined(hstore,text)
- RETURNS bool
- AS 'MODULE_PATHNAME','hstore_defined'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION delete(hstore,text)
- RETURNS hstore
- AS 'MODULE_PATHNAME','hstore_delete'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION delete(hstore,text[])
- RETURNS hstore
- AS 'MODULE_PATHNAME','hstore_delete_array'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION delete(hstore,hstore)
- RETURNS hstore
- AS 'MODULE_PATHNAME','hstore_delete_hstore'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR - (
- LEFTARG = hstore,
- RIGHTARG = text,
- PROCEDURE = delete
- );
-
- CREATE OPERATOR - (
- LEFTARG = hstore,
- RIGHTARG = text[],
- PROCEDURE = delete
- );
-
- CREATE OPERATOR - (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = delete
- );
-
- CREATE FUNCTION hs_concat(hstore,hstore)
- RETURNS hstore
- AS 'MODULE_PATHNAME','hstore_concat'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR || (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hs_concat
- );
-
- CREATE FUNCTION hs_contains(hstore,hstore)
- RETURNS bool
- AS 'MODULE_PATHNAME','hstore_contains'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION hs_contained(hstore,hstore)
- RETURNS bool
- AS 'MODULE_PATHNAME','hstore_contained'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR @> (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hs_contains,
- COMMUTATOR = '<@',
- RESTRICT = contsel,
- JOIN = contjoinsel
- );
-
- CREATE OPERATOR <@ (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hs_contained,
- COMMUTATOR = '@>',
- RESTRICT = contsel,
- JOIN = contjoinsel
- );
-
- -- obsolete:
- CREATE OPERATOR @ (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hs_contains,
- COMMUTATOR = '~',
- RESTRICT = contsel,
- JOIN = contjoinsel
- );
-
- CREATE OPERATOR ~ (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hs_contained,
- COMMUTATOR = '@',
- RESTRICT = contsel,
- JOIN = contjoinsel
- );
-
- CREATE FUNCTION tconvert(text,text)
- RETURNS hstore
- AS 'MODULE_PATHNAME','hstore_from_text'
- LANGUAGE C IMMUTABLE; -- not STRICT; needs to allow (key,NULL)
-
- CREATE FUNCTION hstore(text,text)
- RETURNS hstore
- AS 'MODULE_PATHNAME','hstore_from_text'
- LANGUAGE C IMMUTABLE; -- not STRICT; needs to allow (key,NULL)
-
- CREATE FUNCTION hstore(text[],text[])
- RETURNS hstore
- AS 'MODULE_PATHNAME', 'hstore_from_arrays'
- LANGUAGE C IMMUTABLE; -- not STRICT; allows (keys,null)
-
- CREATE FUNCTION hstore(text[])
- RETURNS hstore
- AS 'MODULE_PATHNAME', 'hstore_from_array'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE CAST (text[] AS hstore)
- WITH FUNCTION hstore(text[]);
-
- CREATE FUNCTION hstore(record)
- RETURNS hstore
- AS 'MODULE_PATHNAME', 'hstore_from_record'
- LANGUAGE C IMMUTABLE; -- not STRICT; allows (null::recordtype)
-
- CREATE FUNCTION hstore_to_array(hstore)
- RETURNS text[]
- AS 'MODULE_PATHNAME','hstore_to_array'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR %% (
- RIGHTARG = hstore,
- PROCEDURE = hstore_to_array
- );
-
- CREATE FUNCTION hstore_to_matrix(hstore)
- RETURNS text[]
- AS 'MODULE_PATHNAME','hstore_to_matrix'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR %# (
- RIGHTARG = hstore,
- PROCEDURE = hstore_to_matrix
- );
-
- CREATE FUNCTION akeys(hstore)
- RETURNS text[]
- AS 'MODULE_PATHNAME','hstore_akeys'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION avals(hstore)
- RETURNS text[]
- AS 'MODULE_PATHNAME','hstore_avals'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION skeys(hstore)
- RETURNS setof text
- AS 'MODULE_PATHNAME','hstore_skeys'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION svals(hstore)
- RETURNS setof text
- AS 'MODULE_PATHNAME','hstore_svals'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION each(IN hs hstore,
- OUT key text,
- OUT value text)
- RETURNS SETOF record
- AS 'MODULE_PATHNAME','hstore_each'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION populate_record(anyelement,hstore)
- RETURNS anyelement
- AS 'MODULE_PATHNAME', 'hstore_populate_record'
- LANGUAGE C IMMUTABLE; -- not STRICT; allows (null::rectype,hstore)
-
- CREATE OPERATOR #= (
- LEFTARG = anyelement,
- RIGHTARG = hstore,
- PROCEDURE = populate_record
- );
-
- -- btree support
-
- CREATE FUNCTION hstore_eq(hstore,hstore)
- RETURNS boolean
- AS 'MODULE_PATHNAME','hstore_eq'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION hstore_ne(hstore,hstore)
- RETURNS boolean
- AS 'MODULE_PATHNAME','hstore_ne'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION hstore_gt(hstore,hstore)
- RETURNS boolean
- AS 'MODULE_PATHNAME','hstore_gt'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION hstore_ge(hstore,hstore)
- RETURNS boolean
- AS 'MODULE_PATHNAME','hstore_ge'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION hstore_lt(hstore,hstore)
- RETURNS boolean
- AS 'MODULE_PATHNAME','hstore_lt'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION hstore_le(hstore,hstore)
- RETURNS boolean
- AS 'MODULE_PATHNAME','hstore_le'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION hstore_cmp(hstore,hstore)
- RETURNS integer
- AS 'MODULE_PATHNAME','hstore_cmp'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR = (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hstore_eq,
- COMMUTATOR = =,
- NEGATOR = <>,
- RESTRICT = eqsel,
- JOIN = eqjoinsel,
- MERGES,
- HASHES
- );
- CREATE OPERATOR <> (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hstore_ne,
- COMMUTATOR = <>,
- NEGATOR = =,
- RESTRICT = neqsel,
- JOIN = neqjoinsel
- );
-
- -- the comparison operators have funky names (and are undocumented)
- -- in an attempt to discourage anyone from actually using them. they
- -- only exist to support the btree opclass
-
- CREATE OPERATOR #<# (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hstore_lt,
- COMMUTATOR = #>#,
- NEGATOR = #>=#,
- RESTRICT = scalarltsel,
- JOIN = scalarltjoinsel
- );
- CREATE OPERATOR #<=# (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hstore_le,
- COMMUTATOR = #>=#,
- NEGATOR = #>#,
- RESTRICT = scalarltsel,
- JOIN = scalarltjoinsel
- );
- CREATE OPERATOR #># (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hstore_gt,
- COMMUTATOR = #<#,
- NEGATOR = #<=#,
- RESTRICT = scalargtsel,
- JOIN = scalargtjoinsel
- );
- CREATE OPERATOR #>=# (
- LEFTARG = hstore,
- RIGHTARG = hstore,
- PROCEDURE = hstore_ge,
- COMMUTATOR = #<=#,
- NEGATOR = #<#,
- RESTRICT = scalargtsel,
- JOIN = scalargtjoinsel
- );
-
- CREATE OPERATOR CLASS btree_hstore_ops
- DEFAULT FOR TYPE hstore USING btree
- AS
- OPERATOR 1 #<# ,
- OPERATOR 2 #<=# ,
- OPERATOR 3 = ,
- OPERATOR 4 #>=# ,
- OPERATOR 5 #># ,
- FUNCTION 1 hstore_cmp(hstore,hstore);
-
- -- hash support
-
- CREATE FUNCTION hstore_hash(hstore)
- RETURNS integer
- AS 'MODULE_PATHNAME','hstore_hash'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE OPERATOR CLASS hash_hstore_ops
- DEFAULT FOR TYPE hstore USING hash
- AS
- OPERATOR 1 = ,
- FUNCTION 1 hstore_hash(hstore);
-
- -- GiST support
-
- CREATE TYPE ghstore;
-
- CREATE FUNCTION ghstore_in(cstring)
- RETURNS ghstore
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE FUNCTION ghstore_out(ghstore)
- RETURNS cstring
- AS 'MODULE_PATHNAME'
- LANGUAGE C STRICT IMMUTABLE;
-
- CREATE TYPE ghstore (
- INTERNALLENGTH = -1,
- INPUT = ghstore_in,
- OUTPUT = ghstore_out
- );
-
- CREATE FUNCTION ghstore_compress(internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION ghstore_decompress(internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION ghstore_penalty(internal,internal,internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION ghstore_picksplit(internal, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION ghstore_union(internal, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION ghstore_same(internal, internal, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION ghstore_consistent(internal,internal,int,oid,internal)
- RETURNS bool
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE OPERATOR CLASS gist_hstore_ops
- DEFAULT FOR TYPE hstore USING gist
- AS
- OPERATOR 7 @> ,
- OPERATOR 9 ?(hstore,text) ,
- OPERATOR 10 ?|(hstore,text[]) ,
- OPERATOR 11 ?&(hstore,text[]) ,
- --OPERATOR 8 <@ ,
- OPERATOR 13 @ ,
- --OPERATOR 14 ~ ,
- FUNCTION 1 ghstore_consistent (internal, internal, int, oid, internal),
- FUNCTION 2 ghstore_union (internal, internal),
- FUNCTION 3 ghstore_compress (internal),
- FUNCTION 4 ghstore_decompress (internal),
- FUNCTION 5 ghstore_penalty (internal, internal, internal),
- FUNCTION 6 ghstore_picksplit (internal, internal),
- FUNCTION 7 ghstore_same (internal, internal, internal),
- STORAGE ghstore;
-
- -- GIN support
-
- CREATE FUNCTION gin_extract_hstore(internal, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION gin_extract_hstore_query(internal, internal, int2, internal, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION gin_consistent_hstore(internal, int2, internal, int4, internal, internal)
- RETURNS bool
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE OPERATOR CLASS gin_hstore_ops
- DEFAULT FOR TYPE hstore USING gin
- AS
- OPERATOR 7 @>,
- OPERATOR 9 ?(hstore,text),
- OPERATOR 10 ?|(hstore,text[]),
- OPERATOR 11 ?&(hstore,text[]),
- FUNCTION 1 bttextcmp(text,text),
- FUNCTION 2 gin_extract_hstore(internal, internal),
- FUNCTION 3 gin_extract_hstore_query(internal, internal, int2, internal, internal),
- FUNCTION 4 gin_consistent_hstore(internal, int2, internal, int4, internal, internal),
- STORAGE text;
--- 0 ----
*** a/contrib/hstore/hstore.control
--- b/contrib/hstore/hstore.control
***************
*** 1,5 ****
--- 1,6 ----
# hstore extension
comment = 'data type for storing sets of (key, value) pairs'
default_version = '1.1'
+ default_full_version = '1.0'
module_pathname = '$libdir/hstore'
relocatable = true
*** a/doc/src/sgml/extend.sgml
--- b/doc/src/sgml/extend.sgml
***************
*** 423,428 ****
--- 423,443 ----
</varlistentry>
<varlistentry>
+ <term><varname>default_full_version</varname> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ This option allows an extension author to avoid shiping all versions
+ scripts when shipping an extension. When a version is requested and
+ the matching script does not exist on disk,
+ set <replaceable>default_full_version</replaceable> to the first
+ script you still ship and PostgreSQL will apply the intermediate
+ upgrade script as per the <command>ALTER EXTENSION UPDATE</command>
+ command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>comment</varname> (<type>string</type>)</term>
<listitem>
<para>
*** a/src/backend/commands/extension.c
--- b/src/backend/commands/extension.c
***************
*** 68,73 **** typedef struct ExtensionControlFile
--- 68,74 ----
char *name; /* name of the extension */
char *directory; /* directory for script files */
char *default_version; /* default install target version, if any */
+ char *default_full_version; /* default install source version, if any */
char *module_pathname; /* string to substitute for MODULE_PATHNAME */
char *comment; /* comment, if any */
char *schema; /* target schema (allowed if !relocatable) */
***************
*** 507,512 **** parse_extension_control_file(ExtensionControlFile *control,
--- 508,517 ----
control->default_version = pstrdup(item->value);
}
+ else if (strcmp(item->name, "default_full_version") == 0)
+ {
+ control->default_full_version = pstrdup(item->value);
+ }
else if (strcmp(item->name, "module_pathname") == 0)
{
control->module_pathname = pstrdup(item->value);
***************
*** 804,809 **** execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
--- 809,816 ----
filename = get_extension_script_filename(control, from_version, version);
+ elog(DEBUG1, "execute_extension_script: '%s'", filename);
+
/*
* Force client_min_messages and log_min_messages to be at least WARNING,
* so that we won't spam the user with useless NOTICE messages from common
***************
*** 1289,1328 **** CreateExtension(CreateExtensionStmt *stmt)
/*
* Determine the (unpackaged) version to update from, if any, and then
* figure out what sequence of update scripts we need to apply.
*/
! if (d_old_version && d_old_version->arg)
{
! oldVersionName = strVal(d_old_version->arg);
! check_valid_version_name(oldVersionName);
! if (strcmp(oldVersionName, versionName) == 0)
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("FROM version must be different from installation target version \"%s\"",
! versionName)));
! updateVersions = identify_update_path(pcontrol,
! oldVersionName,
! versionName);
! if (list_length(updateVersions) == 1)
{
! /*
! * Simple case where there's just one update script to run. We
! * will not need any follow-on update steps.
! */
! Assert(strcmp((char *) linitial(updateVersions), versionName) == 0);
! updateVersions = NIL;
}
else
{
! /*
! * Multi-step sequence. We treat this as installing the version
! * that is the target of the first script, followed by successive
! * updates to the later versions.
! */
! versionName = (char *) linitial(updateVersions);
! updateVersions = list_delete_first(updateVersions);
}
}
else
--- 1296,1370 ----
/*
* Determine the (unpackaged) version to update from, if any, and then
* figure out what sequence of update scripts we need to apply.
+ *
+ * When we have a default_full_version and the target is different from it,
+ * apply the same algorithm to find a sequence of updates. If the user did
+ * ask for a target version that happens to be the same as the
+ * default_full_version, just install that one directly.
*/
! if ((d_old_version && d_old_version->arg) || pcontrol->default_full_version)
{
! bool unpackaged = (d_old_version && d_old_version->arg);
! if (unpackaged)
! oldVersionName = strVal(d_old_version->arg);
! else
! oldVersionName = pcontrol->default_full_version;
! check_valid_version_name(oldVersionName);
! if (strcmp(oldVersionName, versionName) == 0)
{
! if (unpackaged)
! {
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("FROM version must be different from installation target version \"%s\"",
! versionName)));
! }
! else
! {
! /*
! * CREATE EXTENSION ... VERSION = default_full_version, just
! * pretend we don't have a default_full_version for the
! * remaining of the code here, as that's the behavior we want
! * to see happening.
! */
! pcontrol->default_full_version = NULL;
! oldVersionName = NULL;
! updateVersions = NIL;
! }
}
else
{
! /* oldVersionName != versionName */
! updateVersions = identify_update_path(pcontrol,
! oldVersionName,
! versionName);
! }
!
! /* in the create from unpackaged case, reduce the update list */
! if (unpackaged)
! {
! if (list_length(updateVersions) == 1)
! {
! /*
! * Simple case where there's just one update script to run. We
! * will not need any follow-on update steps.
! */
! Assert(strcmp((char *) linitial(updateVersions), versionName) == 0);
! updateVersions = NIL;
! }
! else
! {
! /*
! * Multi-step sequence. We treat this as installing the version
! * that is the target of the first script, followed by successive
! * updates to the later versions.
! */
! versionName = (char *) linitial(updateVersions);
! updateVersions = list_delete_first(updateVersions);
! }
}
}
else
***************
*** 1458,1475 **** CreateExtension(CreateExtensionStmt *stmt)
/*
* Execute the installation script file
! */
! execute_extension_script(extensionOid, control,
! oldVersionName, versionName,
! requiredSchemas,
! schemaName, schemaOid);
!
! /*
* If additional update scripts have to be executed, apply the updates as
* though a series of ALTER EXTENSION UPDATE commands were given
*/
! ApplyExtensionUpdates(extensionOid, pcontrol,
! versionName, updateVersions);
}
/*
--- 1500,1529 ----
/*
* Execute the installation script file
! *
* If additional update scripts have to be executed, apply the updates as
* though a series of ALTER EXTENSION UPDATE commands were given
*/
! if (pcontrol->default_full_version)
! {
! execute_extension_script(extensionOid, control,
! NULL, oldVersionName,
! requiredSchemas,
! schemaName, schemaOid);
!
! ApplyExtensionUpdates(extensionOid, pcontrol,
! oldVersionName, updateVersions);
! }
! else
! {
! execute_extension_script(extensionOid, control,
! oldVersionName, versionName,
! requiredSchemas,
! schemaName, schemaOid);
!
! ApplyExtensionUpdates(extensionOid, pcontrol,
! versionName, updateVersions);
! }
}
/*
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers