hstore: add hstore_length function
Hi there-
I've attached a small patch exposing HS_COUNT to the user as
"hstore_length(hstore)". Documentation, upgrade sql files, and a few
tests are also included.
Almost every hstore function calls HS_COUNT, but I couldn't determine
if there was a reason this exposure didn't already exist.
Without this function, I've been converting an hstore into an array
and then counting it - a more expensive operation (~30-40% slower than
SELECTing the hstore itself in a few of my tests).
I will add this thread and patch to the next Commitfest.
Thanks,
Korbin Hoffman
Attachments:
hstore_length-v1.patchapplication/octet-stream; name=hstore_length-v1.patchDownload
diff --git a/contrib/hstore/Makefile b/contrib/hstore/Makefile
new file mode 100644
index 82908de..3000679
*** a/contrib/hstore/Makefile
--- b/contrib/hstore/Makefile
*************** OBJS = hstore_io.o hstore_op.o hstore_gi
*** 5,11 ****
$(WIN32RES)
EXTENSION = hstore
! DATA = hstore--1.3.sql hstore--1.2--1.3.sql \
hstore--1.1--1.2.sql hstore--1.0--1.1.sql \
hstore--unpackaged--1.0.sql
PGFILEDESC = "hstore - key/value pair data type"
--- 5,12 ----
$(WIN32RES)
EXTENSION = hstore
! DATA = hstore--1.4.sql \
! hstore--1.3--1.4.sql hstore--1.2--1.3.sql \
hstore--1.1--1.2.sql hstore--1.0--1.1.sql \
hstore--unpackaged--1.0.sql
PGFILEDESC = "hstore - key/value pair data type"
diff --git a/contrib/hstore/expected/hstore.out b/contrib/hstore/expected/hstore.out
new file mode 100644
index 6773a2b..dd1a13f
*** a/contrib/hstore/expected/hstore.out
--- b/contrib/hstore/expected/hstore.out
*************** select json_agg(q) from (select f1, hsto
*** 1507,1509 ****
--- 1507,1528 ----
{"f1":"rec2","f2":{"b": false, "c": "null", "d": -12345, "e": "012345.6", "f": -1.234, "g": 0.345e-4, "a key": 2}}]
(1 row)
+ -- length
+ select hstore_length('a=>b');
+ hstore_length
+ ---------------
+ 1
+ (1 row)
+
+ select hstore_length('a=>b, b=>null');
+ hstore_length
+ ---------------
+ 2
+ (1 row)
+
+ select hstore_length('');
+ hstore_length
+ ---------------
+ 0
+ (1 row)
+
diff --git a/contrib/hstore/hstore--1.3--1.4.sql b/contrib/hstore/hstore--1.3--1.4.sql
new file mode 100644
index ...23ab9ae
*** a/contrib/hstore/hstore--1.3--1.4.sql
--- b/contrib/hstore/hstore--1.3--1.4.sql
***************
*** 0 ****
--- 1,9 ----
+ /* contrib/hstore/hstore--1.3--1.4.sql */
+
+ -- complain if script is sourced in psql, rather than via ALTER EXTENSION
+ \echo Use "ALTER EXTENSION hstore UPDATE TO '1.4'" to load this file. \quit
+
+ CREATE FUNCTION hstore_length(hstore)
+ RETURNS integer
+ AS 'MODULE_PATHNAME', 'hstore_length'
+ LANGUAGE C IMMUTABLE STRICT;
diff --git a/contrib/hstore/hstore--1.3.sql b/contrib/hstore/hstore--1.3.sql
new file mode .
index b9b478d..e69de29
*** a/contrib/hstore/hstore--1.3.sql
--- b/contrib/hstore/hstore--1.3.sql
***************
*** 1,550 ****
- /* contrib/hstore/hstore--1.3.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_to_json(hstore)
- RETURNS json
- AS 'MODULE_PATHNAME', 'hstore_to_json'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE CAST (hstore AS json)
- WITH FUNCTION hstore_to_json(hstore);
-
- CREATE FUNCTION hstore_to_json_loose(hstore)
- RETURNS json
- AS 'MODULE_PATHNAME', 'hstore_to_json_loose'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION hstore_to_jsonb(hstore)
- RETURNS jsonb
- AS 'MODULE_PATHNAME', 'hstore_to_jsonb'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE CAST (hstore AS jsonb)
- WITH FUNCTION hstore_to_jsonb(hstore);
-
- CREATE FUNCTION hstore_to_jsonb_loose(hstore)
- RETURNS jsonb
- AS 'MODULE_PATHNAME', 'hstore_to_jsonb_loose'
- LANGUAGE C IMMUTABLE STRICT;
-
- 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 ghstore
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION ghstore_same(ghstore, ghstore, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION ghstore_consistent(internal,hstore,smallint,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, hstore, smallint, 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 (ghstore, ghstore, internal),
- STORAGE ghstore;
-
- -- GIN support
-
- CREATE FUNCTION gin_extract_hstore(hstore, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION gin_extract_hstore_query(hstore, internal, int2, internal, internal)
- RETURNS internal
- AS 'MODULE_PATHNAME'
- LANGUAGE C IMMUTABLE STRICT;
-
- CREATE FUNCTION gin_consistent_hstore(internal, int2, hstore, 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(hstore, internal),
- FUNCTION 3 gin_extract_hstore_query(hstore, internal, int2, internal, internal),
- FUNCTION 4 gin_consistent_hstore(internal, int2, hstore, int4, internal, internal),
- STORAGE text;
--- 0 ----
diff --git a/contrib/hstore/hstore--1.4.sql b/contrib/hstore/hstore--1.4.sql
new file mode 100644
index ...8feb20f
*** a/contrib/hstore/hstore--1.4.sql
--- b/contrib/hstore/hstore--1.4.sql
***************
*** 0 ****
--- 1,555 ----
+ /* contrib/hstore/hstore--1.4.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_to_json(hstore)
+ RETURNS json
+ AS 'MODULE_PATHNAME', 'hstore_to_json'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE CAST (hstore AS json)
+ WITH FUNCTION hstore_to_json(hstore);
+
+ CREATE FUNCTION hstore_to_json_loose(hstore)
+ RETURNS json
+ AS 'MODULE_PATHNAME', 'hstore_to_json_loose'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION hstore_to_jsonb(hstore)
+ RETURNS jsonb
+ AS 'MODULE_PATHNAME', 'hstore_to_jsonb'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE CAST (hstore AS jsonb)
+ WITH FUNCTION hstore_to_jsonb(hstore);
+
+ CREATE FUNCTION hstore_to_jsonb_loose(hstore)
+ RETURNS jsonb
+ AS 'MODULE_PATHNAME', 'hstore_to_jsonb_loose'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION hstore_length(hstore)
+ RETURNS integer
+ AS 'MODULE_PATHNAME', 'hstore_length'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ 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 ghstore
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION ghstore_same(ghstore, ghstore, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION ghstore_consistent(internal,hstore,smallint,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, hstore, smallint, 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 (ghstore, ghstore, internal),
+ STORAGE ghstore;
+
+ -- GIN support
+
+ CREATE FUNCTION gin_extract_hstore(hstore, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION gin_extract_hstore_query(hstore, internal, int2, internal, internal)
+ RETURNS internal
+ AS 'MODULE_PATHNAME'
+ LANGUAGE C IMMUTABLE STRICT;
+
+ CREATE FUNCTION gin_consistent_hstore(internal, int2, hstore, 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(hstore, internal),
+ FUNCTION 3 gin_extract_hstore_query(hstore, internal, int2, internal, internal),
+ FUNCTION 4 gin_consistent_hstore(internal, int2, hstore, int4, internal, internal),
+ STORAGE text;
diff --git a/contrib/hstore/hstore.control b/contrib/hstore/hstore.control
new file mode 100644
index dcc3b68..f99a937
*** a/contrib/hstore/hstore.control
--- b/contrib/hstore/hstore.control
***************
*** 1,5 ****
# hstore extension
comment = 'data type for storing sets of (key, value) pairs'
! default_version = '1.3'
module_pathname = '$libdir/hstore'
relocatable = true
--- 1,5 ----
# hstore extension
comment = 'data type for storing sets of (key, value) pairs'
! default_version = '1.4'
module_pathname = '$libdir/hstore'
relocatable = true
diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c
new file mode 100644
index 1e2dc88..fb0bf9b
*** a/contrib/hstore/hstore_op.c
--- b/contrib/hstore/hstore_op.c
*************** HSTORE_POLLUTE(hstore_avals, avals);
*** 25,30 ****
--- 25,31 ----
HSTORE_POLLUTE(hstore_skeys, skeys);
HSTORE_POLLUTE(hstore_svals, svals);
HSTORE_POLLUTE(hstore_each, each);
+ HSTORE_POLLUTE(hstore_length, length);
/*
*************** hstore_each(PG_FUNCTION_ARGS)
*** 1076,1081 ****
--- 1077,1091 ----
SRF_RETURN_DONE(funcctx);
}
+ PG_FUNCTION_INFO_V1(hstore_length);
+ Datum
+ hstore_length(PG_FUNCTION_ARGS)
+ {
+ HStore *hs = PG_GETARG_HS(0);
+ int count = HS_COUNT(hs);
+
+ PG_RETURN_INT32(count);
+ }
/*
* btree sort order for hstores isn't intended to be useful; we really only
diff --git a/contrib/hstore/sql/hstore.sql b/contrib/hstore/sql/hstore.sql
new file mode 100644
index 4851478..c1f8aed
*** a/contrib/hstore/sql/hstore.sql
--- b/contrib/hstore/sql/hstore.sql
*************** insert into test_json_agg values ('rec1'
*** 345,347 ****
--- 345,352 ----
('rec2','"a key" =>2, b => f, c => "null", d=> -12345, e => 012345.6, f=> -1.234, g=> 0.345e-4');
select json_agg(q) from test_json_agg q;
select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_json_agg) q;
+
+ -- length
+ select hstore_length('a=>b');
+ select hstore_length('a=>b, b=>null');
+ select hstore_length('');
diff --git a/doc/src/sgml/hstore.sgml b/doc/src/sgml/hstore.sgml
new file mode 100644
index db5d440..3671821
*** a/doc/src/sgml/hstore.sgml
--- b/doc/src/sgml/hstore.sgml
*************** b
*** 306,311 ****
--- 306,319 ----
</row>
<row>
+ <entry><function>hstore_length(hstore)</function><indexterm><primary>hstore_length</primary></indexterm></entry>
+ <entry><type>int</type></entry>
+ <entry>get the number of elements in <type>hstore</></entry>
+ <entry><literal>hstore_length('a=>1,b=>2')</literal></entry>
+ <entry><literal>2</literal></entry>
+ </row>
+
+ <row>
<entry><function>hstore_to_array(hstore)</function><indexterm><primary>hstore_to_array</primary></indexterm></entry>
<entry><type>text[]</type></entry>
<entry>get <type>hstore</>'s keys and values as an array of alternating
On Fri, Jun 3, 2016 at 7:58 AM, Korbin Hoffman <k1@k1.io> wrote:
Hi there-
I've attached a small patch exposing HS_COUNT to the user as
"hstore_length(hstore)". Documentation, upgrade sql files, and a few
tests are also included.Almost every hstore function calls HS_COUNT, but I couldn't determine
if there was a reason this exposure didn't already exist.Without this function, I've been converting an hstore into an array
and then counting it - a more expensive operation (~30-40% slower than
SELECTing the hstore itself in a few of my tests).I will add this thread and patch to the next Commitfest.
Something goes wrong when applying against master:
$ git apply ~/Downloads/hstore_length-v1.patch
error: contrib/hstore/Makefile: already exists in working directory
error: contrib/hstore/expected/hstore.out: already exists in working
directory
error: contrib/hstore/hstore--1.3.sql: already exists in working directory
error: contrib/hstore/hstore.control: already exists in working directory
error: contrib/hstore/hstore_op.c: already exists in working directory
error: contrib/hstore/sql/hstore.sql: already exists in working directory
error: doc/src/sgml/hstore.sgml: already exists in working directory
Anyway I have some comments:
1) I don't see any reason to add this sort of thing if you're adding a new
function
+ HSTORE_POLLUTE(hstore_length, length);
2) Shouldn't this declaration use 'uint32' instead of 'int' ??
+ int count = HS_COUNT(hs);
+
+ PG_RETURN_INT32(count);
maybe
+ uint32 count = HS_COUNT(hs);
+
+ PG_RETURN_UINT32(count);
Regards,
--
Fabrízio de Royes Mello
Consultoria/Coaching PostgreSQL
Show quoted text
Timbira: http://www.timbira.com.br
Blog: http://fabriziomello.github.io
Linkedin: http://br.linkedin.com/in/fabriziomello
Twitter: http://twitter.com/fabriziomello
Github: http://github.com/fabriziomello
Thanks for the review, Fabrízio.
Attached is the updated patch, rebased and tested against master.
I integrated feedback from your first point and am no longer
HS_POLLUTE'ing the namespace for the new function.
With regards to your second point- I've been maintaining consistency
with the rest of the hstore module. Hstore's _size is internally
stored as a uint, but all uses of HS_COUNT across the feature end up
stored in a signed int. I could only find (grep) a few occurrences of
PG_RETURN_UINT32 across the entire codebase, and none in the hstore
module. If there's strong consensus for change, though, I'm happy to
do so.
Thanks,
Korbin Hoffman
On Mon, Jun 6, 2016 at 1:23 PM, Fabrízio de Royes Mello
<fabriziomello@gmail.com> wrote:
Show quoted text
On Fri, Jun 3, 2016 at 7:58 AM, Korbin Hoffman <k1@k1.io> wrote:
Hi there-
I've attached a small patch exposing HS_COUNT to the user as
"hstore_length(hstore)". Documentation, upgrade sql files, and a few
tests are also included.Almost every hstore function calls HS_COUNT, but I couldn't determine
if there was a reason this exposure didn't already exist.Without this function, I've been converting an hstore into an array
and then counting it - a more expensive operation (~30-40% slower than
SELECTing the hstore itself in a few of my tests).I will add this thread and patch to the next Commitfest.
Something goes wrong when applying against master:
$ git apply ~/Downloads/hstore_length-v1.patch
error: contrib/hstore/Makefile: already exists in working directory
error: contrib/hstore/expected/hstore.out: already exists in working
directory
error: contrib/hstore/hstore--1.3.sql: already exists in working directory
error: contrib/hstore/hstore.control: already exists in working directory
error: contrib/hstore/hstore_op.c: already exists in working directory
error: contrib/hstore/sql/hstore.sql: already exists in working directory
error: doc/src/sgml/hstore.sgml: already exists in working directoryAnyway I have some comments:
1) I don't see any reason to add this sort of thing if you're adding a new
function+ HSTORE_POLLUTE(hstore_length, length);
2) Shouldn't this declaration use 'uint32' instead of 'int' ??
+ int count = HS_COUNT(hs); + + PG_RETURN_INT32(count);maybe
+ uint32 count = HS_COUNT(hs); + + PG_RETURN_UINT32(count);Regards,
--
Fabrízio de Royes Mello
Consultoria/Coaching PostgreSQLTimbira: http://www.timbira.com.br
Blog: http://fabriziomello.github.io
Linkedin: http://br.linkedin.com/in/fabriziomello
Twitter: http://twitter.com/fabriziomello
Github: http://github.com/fabriziomello
Attachments:
hstore_length-v2.patchapplication/octet-stream; name=hstore_length-v2.patchDownload
diff --git a/contrib/hstore/Makefile b/contrib/hstore/Makefile
index 82908de..3000679 100644
--- a/contrib/hstore/Makefile
+++ b/contrib/hstore/Makefile
@@ -5,7 +5,8 @@ OBJS = hstore_io.o hstore_op.o hstore_gist.o hstore_gin.o hstore_compat.o \
$(WIN32RES)
EXTENSION = hstore
-DATA = hstore--1.3.sql hstore--1.2--1.3.sql \
+DATA = hstore--1.4.sql \
+ hstore--1.3--1.4.sql hstore--1.2--1.3.sql \
hstore--1.1--1.2.sql hstore--1.0--1.1.sql \
hstore--unpackaged--1.0.sql
PGFILEDESC = "hstore - key/value pair data type"
diff --git a/contrib/hstore/expected/hstore.out b/contrib/hstore/expected/hstore.out
index 6773a2b..dd1a13f 100644
--- a/contrib/hstore/expected/hstore.out
+++ b/contrib/hstore/expected/hstore.out
@@ -1507,3 +1507,22 @@ select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_jso
{"f1":"rec2","f2":{"b": false, "c": "null", "d": -12345, "e": "012345.6", "f": -1.234, "g": 0.345e-4, "a key": 2}}]
(1 row)
+-- length
+select hstore_length('a=>b');
+ hstore_length
+---------------
+ 1
+(1 row)
+
+select hstore_length('a=>b, b=>null');
+ hstore_length
+---------------
+ 2
+(1 row)
+
+select hstore_length('');
+ hstore_length
+---------------
+ 0
+(1 row)
+
diff --git a/contrib/hstore/hstore--1.3--1.4.sql b/contrib/hstore/hstore--1.3--1.4.sql
new file mode 100644
index 0000000..23ab9ae
--- /dev/null
+++ b/contrib/hstore/hstore--1.3--1.4.sql
@@ -0,0 +1,9 @@
+/* contrib/hstore/hstore--1.3--1.4.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION hstore UPDATE TO '1.4'" to load this file. \quit
+
+CREATE FUNCTION hstore_length(hstore)
+RETURNS integer
+AS 'MODULE_PATHNAME', 'hstore_length'
+LANGUAGE C IMMUTABLE STRICT;
diff --git a/contrib/hstore/hstore--1.3.sql b/contrib/hstore/hstore--1.3.sql
deleted file mode 100644
index b9b478d..0000000
--- a/contrib/hstore/hstore--1.3.sql
+++ /dev/null
@@ -1,550 +0,0 @@
-/* contrib/hstore/hstore--1.3.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_to_json(hstore)
-RETURNS json
-AS 'MODULE_PATHNAME', 'hstore_to_json'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE CAST (hstore AS json)
- WITH FUNCTION hstore_to_json(hstore);
-
-CREATE FUNCTION hstore_to_json_loose(hstore)
-RETURNS json
-AS 'MODULE_PATHNAME', 'hstore_to_json_loose'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION hstore_to_jsonb(hstore)
-RETURNS jsonb
-AS 'MODULE_PATHNAME', 'hstore_to_jsonb'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE CAST (hstore AS jsonb)
- WITH FUNCTION hstore_to_jsonb(hstore);
-
-CREATE FUNCTION hstore_to_jsonb_loose(hstore)
-RETURNS jsonb
-AS 'MODULE_PATHNAME', 'hstore_to_jsonb_loose'
-LANGUAGE C IMMUTABLE STRICT;
-
-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 ghstore
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION ghstore_same(ghstore, ghstore, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION ghstore_consistent(internal,hstore,smallint,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, hstore, smallint, 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 (ghstore, ghstore, internal),
- STORAGE ghstore;
-
--- GIN support
-
-CREATE FUNCTION gin_extract_hstore(hstore, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gin_extract_hstore_query(hstore, internal, int2, internal, internal)
-RETURNS internal
-AS 'MODULE_PATHNAME'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gin_consistent_hstore(internal, int2, hstore, 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(hstore, internal),
- FUNCTION 3 gin_extract_hstore_query(hstore, internal, int2, internal, internal),
- FUNCTION 4 gin_consistent_hstore(internal, int2, hstore, int4, internal, internal),
- STORAGE text;
diff --git a/contrib/hstore/hstore--1.4.sql b/contrib/hstore/hstore--1.4.sql
new file mode 100644
index 0000000..8feb20f
--- /dev/null
+++ b/contrib/hstore/hstore--1.4.sql
@@ -0,0 +1,555 @@
+/* contrib/hstore/hstore--1.4.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_to_json(hstore)
+RETURNS json
+AS 'MODULE_PATHNAME', 'hstore_to_json'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE CAST (hstore AS json)
+ WITH FUNCTION hstore_to_json(hstore);
+
+CREATE FUNCTION hstore_to_json_loose(hstore)
+RETURNS json
+AS 'MODULE_PATHNAME', 'hstore_to_json_loose'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION hstore_to_jsonb(hstore)
+RETURNS jsonb
+AS 'MODULE_PATHNAME', 'hstore_to_jsonb'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE CAST (hstore AS jsonb)
+ WITH FUNCTION hstore_to_jsonb(hstore);
+
+CREATE FUNCTION hstore_to_jsonb_loose(hstore)
+RETURNS jsonb
+AS 'MODULE_PATHNAME', 'hstore_to_jsonb_loose'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION hstore_length(hstore)
+RETURNS integer
+AS 'MODULE_PATHNAME', 'hstore_length'
+LANGUAGE C IMMUTABLE STRICT;
+
+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 ghstore
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION ghstore_same(ghstore, ghstore, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION ghstore_consistent(internal,hstore,smallint,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, hstore, smallint, 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 (ghstore, ghstore, internal),
+ STORAGE ghstore;
+
+-- GIN support
+
+CREATE FUNCTION gin_extract_hstore(hstore, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gin_extract_hstore_query(hstore, internal, int2, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gin_consistent_hstore(internal, int2, hstore, 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(hstore, internal),
+ FUNCTION 3 gin_extract_hstore_query(hstore, internal, int2, internal, internal),
+ FUNCTION 4 gin_consistent_hstore(internal, int2, hstore, int4, internal, internal),
+ STORAGE text;
diff --git a/contrib/hstore/hstore.control b/contrib/hstore/hstore.control
index dcc3b68..f99a937 100644
--- a/contrib/hstore/hstore.control
+++ b/contrib/hstore/hstore.control
@@ -1,5 +1,5 @@
# hstore extension
comment = 'data type for storing sets of (key, value) pairs'
-default_version = '1.3'
+default_version = '1.4'
module_pathname = '$libdir/hstore'
relocatable = true
diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c
index 1e2dc88..67742c1 100644
--- a/contrib/hstore/hstore_op.c
+++ b/contrib/hstore/hstore_op.c
@@ -1076,6 +1076,15 @@ hstore_each(PG_FUNCTION_ARGS)
SRF_RETURN_DONE(funcctx);
}
+PG_FUNCTION_INFO_V1(hstore_length);
+Datum
+hstore_length(PG_FUNCTION_ARGS)
+{
+ HStore *hs = PG_GETARG_HS(0);
+ int count = HS_COUNT(hs);
+
+ PG_RETURN_INT32(count);
+}
/*
* btree sort order for hstores isn't intended to be useful; we really only
diff --git a/contrib/hstore/sql/hstore.sql b/contrib/hstore/sql/hstore.sql
index 4851478..c1f8aed 100644
--- a/contrib/hstore/sql/hstore.sql
+++ b/contrib/hstore/sql/hstore.sql
@@ -345,3 +345,8 @@ insert into test_json_agg values ('rec1','"a key" =>1, b => t, c => null, d=> 12
('rec2','"a key" =>2, b => f, c => "null", d=> -12345, e => 012345.6, f=> -1.234, g=> 0.345e-4');
select json_agg(q) from test_json_agg q;
select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_json_agg) q;
+
+-- length
+select hstore_length('a=>b');
+select hstore_length('a=>b, b=>null');
+select hstore_length('');
diff --git a/doc/src/sgml/hstore.sgml b/doc/src/sgml/hstore.sgml
index db5d440..3671821 100644
--- a/doc/src/sgml/hstore.sgml
+++ b/doc/src/sgml/hstore.sgml
@@ -306,6 +306,14 @@ b
</row>
<row>
+ <entry><function>hstore_length(hstore)</function><indexterm><primary>hstore_length</primary></indexterm></entry>
+ <entry><type>int</type></entry>
+ <entry>get the number of elements in <type>hstore</></entry>
+ <entry><literal>hstore_length('a=>1,b=>2')</literal></entry>
+ <entry><literal>2</literal></entry>
+ </row>
+
+ <row>
<entry><function>hstore_to_array(hstore)</function><indexterm><primary>hstore_to_array</primary></indexterm></entry>
<entry><type>text[]</type></entry>
<entry>get <type>hstore</>'s keys and values as an array of alternating
Import Notes
Resolved by subject fallback
On Mon, Jun 6, 2016 at 7:57 PM, Korbin Hoffman <k1@k1.io> wrote:
With regards to your second point- I've been maintaining consistency
with the rest of the hstore module. Hstore's _size is internally
stored as a uint, but all uses of HS_COUNT across the feature end up
stored in a signed int. I could only find (grep) a few occurrences of
PG_RETURN_UINT32 across the entire codebase, and none in the hstore
module. If there's strong consensus for change, though, I'm happy to
do so.
The PG_RETURN_BLAH macro chosen should match the declared return type
of that function. So if your function, for example, returns int4 (or
integer, which is the same thing), PG_RETURN_INT32 is correct.
There are no built-in SQL datatypes for unsigned integers, which is
why you did not find many uses of PG_RETURN_UINT32 in the code base.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Jun 8, 2016 at 10:44 AM, Robert Haas <robertmhaas@gmail.com> wrote:
On Mon, Jun 6, 2016 at 7:57 PM, Korbin Hoffman <k1@k1.io> wrote:
With regards to your second point- I've been maintaining consistency
with the rest of the hstore module. Hstore's _size is internally
stored as a uint, but all uses of HS_COUNT across the feature end up
stored in a signed int. I could only find (grep) a few occurrences of
PG_RETURN_UINT32 across the entire codebase, and none in the hstore
module. If there's strong consensus for change, though, I'm happy to
do so.The PG_RETURN_BLAH macro chosen should match the declared return type
of that function. So if your function, for example, returns int4 (or
integer, which is the same thing), PG_RETURN_INT32 is correct.There are no built-in SQL datatypes for unsigned integers, which is
why you did not find many uses of PG_RETURN_UINT32 in the code base.
Since this patch was never updated in response to this review, I am
marking it "Returned with Feedback" in this CommitFest. If it is
updated, it can be resubmitted to a future CommitFest.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers