Fujii Masao <masao.fu...@gmail.com> writes: >>> Though I'm not familiar with CREATE EXTENSION. Why did you exclude 1.0.sql >>> from DATA? In hstore/Makefile, 1.0.sql is included. You think we should >>> prevent >>> old version (i.e., 1.0) of pg_stat_statements from being used in 9.2? >> >> I'm not sure. My feeling is that we probably don't want to ship all >> the old scripts forever. People should install the latest version, >> and use the upgrade scripts to get there if they have an older one. >> So my gut feeling here is to change hstore to exclude that file rather >> than adding it here. Any other opinions?
The problem with the hstore scripts is that you had to copy the 1.0 script, change a couple of lines, and call that 1.1, and you also had to provide the 1.0--1.1 script file. The solution would be to be able to create hstore 1.1 from 1.0 automatically and I sent over a very simple patch to do that, albeit after the deadline for the current CF (that's why it's not listed). Maybe that's simple enough to be considered? (re-attaching here) b/contrib/hstore/Makefile | 2 b/contrib/hstore/hstore.control | 1 b/src/backend/commands/extension.c | 83 +++-- contrib/hstore/hstore--1.1.sql | 524 ------------------------------------- 4 files changed, 57 insertions(+), 553 deletions(-) > Agreed. But I wonder why VERSION option is usable in CREATE EXTENSION > if people always should use the latest version. Maybe I'm missing something.. I think not that many people are using 9.1 in production already. Also bear in mind that the mechanism is not made only for contrib, it makes sense to ship in-house procedure code as an extension too. Regards, -- Dimitri Fontaine http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
diff --git a/contrib/hstore/Makefile b/contrib/hstore/Makefile index e9e5e53..2d624d3 100644 --- a/contrib/hstore/Makefile +++ b/contrib/hstore/Makefile @@ -5,7 +5,7 @@ OBJS = hstore_io.o hstore_op.o hstore_gist.o hstore_gin.o hstore_compat.o \ crc32.o EXTENSION = hstore -DATA = hstore--1.0.sql hstore--1.1.sql hstore--1.0--1.1.sql \ +DATA = hstore--1.0.sql hstore--1.1.sql.orig hstore--1.0--1.1.sql \ hstore--unpackaged--1.0.sql REGRESS = hstore diff --git a/contrib/hstore/hstore--1.1.sql b/contrib/hstore/hstore--1.1.sql deleted file mode 100644 index e95ad32..0000000 --- a/contrib/hstore/hstore--1.1.sql +++ /dev/null @@ -1,524 +0,0 @@ -/* 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; diff --git a/contrib/hstore/hstore.control b/contrib/hstore/hstore.control index 4104e17..0c49ade 100644 --- 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 diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 6ecbbc7..2fb1658 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -66,6 +66,7 @@ typedef struct ExtensionControlFile 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) */ @@ -505,6 +506,10 @@ parse_extension_control_file(ExtensionControlFile *control, 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); @@ -1288,9 +1293,15 @@ 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) + if ((d_old_version && d_old_version->arg) || pcontrol->default_full_version) { - oldVersionName = strVal(d_old_version->arg); + 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) @@ -1303,24 +1314,28 @@ CreateExtension(CreateExtensionStmt *stmt) 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 + /* in the create from unpackaged case, redude the update list */ + if (unpackaged) { - /* - * 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); + 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 @@ -1455,18 +1470,30 @@ 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); + 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 (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers