Skip to content

Commit c0e925e

Browse files
author
hackorum
committed
Apply cast_jsonb_to_hstore2.patch
1 parent 72e6184 commit c0e925e

6 files changed

Lines changed: 258 additions & 0 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
MODULES = cast_jsonb_to_hstore
2+
EXTENSION = cast_jsonb_to_hstore
3+
DATA = cast_jsonb_to_hstore--1.0.sql
4+
PGFILEDESC = "Convert data between different character sets"
5+
REGRESS = cast_jsonb_to_hstore
6+
EXTRA_INSTALL = contrib/hstore
7+
8+
ifdef USE_PGXS
9+
PG_CONFIG = PG_CONFIG
10+
PGXS := $(shell $(PG_CONFIG) --pgxs)
11+
include $(PGXS)
12+
else
13+
PG_CPPFLAGS = -I$(top_srcdir)/contrib
14+
subdir = contrib/cast_jsonb_to_hstore
15+
top_builddir = ../..
16+
include $(top_builddir)/src/Makefile.global
17+
include $(top_srcdir)/contrib/contrib-global.mk
18+
endif
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
\echo Use "CREATE EXTENSION cast_jsonb_to_hstore" to load this file. \quit
2+
CREATE OR REPLACE FUNCTION jsonb_to_hstore(j0 jsonb)
3+
RETURNS hstore
4+
AS '$libdir/cast_jsonb_to_hstore', 'jsonb_to_hstore'
5+
LANGUAGE C IMMUTABLE STRICT;
6+
7+
CREATE OR REPLACE FUNCTION json_to_hstore(j0 json)
8+
RETURNS hstore AS
9+
$BODY$
10+
SELECT hstore(array_agg(key), array_agg(value))
11+
FROM json_each_text(j0)
12+
$BODY$
13+
LANGUAGE 'sql' IMMUTABLE;
14+
15+
CREATE CAST (jsonb AS hstore) WITH FUNCTION jsonb_to_hstore(jsonb) AS IMPLICIT;
16+
CREATE CAST (json AS hstore) WITH FUNCTION json_to_hstore(json) AS IMPLICIT;
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#include "postgres.h"
2+
#include "hstore/hstore.h"
3+
#include "utils/jsonb.h"
4+
5+
PG_MODULE_MAGIC;
6+
7+
typedef int (*hstoreUniquePairs_t) (Pairs *a, int32 l, int32 *buflen);
8+
static hstoreUniquePairs_t hstoreUniquePairs_p;
9+
typedef HStore *(*hstorePairs_t) (Pairs *pairs, int32 pcount, int32 buflen);
10+
static hstorePairs_t hstorePairs_p;
11+
typedef size_t (*hstoreCheckKeyLen_t) (size_t len);
12+
static hstoreCheckKeyLen_t hstoreCheckKeyLen_p;
13+
typedef size_t (*hstoreCheckValLen_t) (size_t len);
14+
static hstoreCheckValLen_t hstoreCheckValLen_p;
15+
16+
void
17+
_PG_init(void)
18+
{
19+
AssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
20+
hstoreUniquePairs_p = (hstoreUniquePairs_t)
21+
load_external_function("$libdir/hstore", "hstoreUniquePairs",
22+
true, NULL);
23+
AssertVariableIsOfType(&hstorePairs, hstorePairs_t);
24+
hstorePairs_p = (hstorePairs_t)
25+
load_external_function("$libdir/hstore", "hstorePairs",
26+
true, NULL);
27+
AssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
28+
hstoreCheckKeyLen_p = (hstoreCheckKeyLen_t)
29+
load_external_function("$libdir/hstore", "hstoreCheckKeyLen",
30+
true, NULL);
31+
AssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
32+
hstoreCheckValLen_p = (hstoreCheckValLen_t)
33+
load_external_function("$libdir/hstore", "hstoreCheckValLen",
34+
true, NULL);
35+
}
36+
37+
#define hstoreUniquePairs hstoreUniquePairs_p
38+
#define hstorePairs hstorePairs_p
39+
#define hstoreCheckKeyLen hstoreCheckKeyLen_p
40+
#define hstoreCheckValLen hstoreCheckValLen_p
41+
42+
PG_FUNCTION_INFO_V1(jsonb_to_hstore);
43+
44+
Datum
45+
jsonb_to_hstore(PG_FUNCTION_ARGS)
46+
{
47+
int32 buflen;
48+
int32 i;
49+
int32 pcount;
50+
HStore *out;
51+
Pairs *pairs;
52+
53+
Jsonb *in = PG_GETARG_JSONB_P(0);
54+
JsonbContainer *jsonb = &in->root;
55+
56+
JsonbValue v;
57+
JsonbIterator *it;
58+
JsonbIteratorToken r;
59+
60+
it = JsonbIteratorInit(jsonb);
61+
r = JsonbIteratorNext(&it, &v, true);
62+
63+
i = 0;
64+
pcount = v.val.object.nPairs;
65+
pairs = palloc(pcount * sizeof(Pairs));
66+
67+
if (r == WJB_BEGIN_OBJECT)
68+
{
69+
while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
70+
{
71+
if (r == WJB_KEY)
72+
{
73+
//key- v, value- val
74+
JsonbValue val;
75+
if (JsonbIteratorNext(&it, &val, true) == WJB_VALUE)
76+
{
77+
pairs[i].key = pstrdup(v.val.string.val);
78+
pairs[i].keylen = hstoreCheckKeyLen(v.val.string.len);
79+
pairs[i].needfree = true;
80+
81+
switch (val.type)
82+
{
83+
case jbvNumeric:
84+
pairs[i].val = pstrdup((numeric_normalize(val.val.numeric)));
85+
pairs[i].vallen = hstoreCheckValLen(strlen(pairs[i].val));
86+
pairs[i].isnull = false;
87+
break;
88+
case jbvString:
89+
pairs[i].val = strdup((val.val.string.val));
90+
pairs[i].vallen = hstoreCheckValLen(val.val.string.len);
91+
pairs[i].isnull = false;
92+
break;
93+
case jbvNull:
94+
pairs[i].isnull = true;
95+
break;
96+
case jbvBool:
97+
if (val.val.boolean)
98+
{
99+
pairs[i].val = "true";
100+
pairs[i].vallen = hstoreCheckValLen(strlen("true"));
101+
}
102+
else
103+
{
104+
pairs[i].val = "false";
105+
pairs[i].vallen = hstoreCheckValLen(strlen("false"));
106+
}
107+
pairs[i].isnull = false;
108+
break;
109+
default:
110+
ereport(ERROR,(errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Unsupported value type for casting to hstore")));
111+
break;
112+
}
113+
}
114+
}
115+
++i;
116+
}
117+
}
118+
pcount = hstoreUniquePairs(pairs, pcount, &buflen);
119+
out = hstorePairs(pairs, pcount, buflen);
120+
PG_RETURN_POINTER(out);
121+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
comment = 'function for convert json hstore'
2+
default_version = '1.0'
3+
module_pathname = '$libdir/cast_jsonb_to_hstore'
4+
relocatable = true
5+
requires = 'hstore'
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* The file is used to test cast_jsonb_to_hstore.sql
3+
*/
4+
CREATE EXTENSION hstore;
5+
CREATE EXTENSION cast_jsonb_to_hstore;
6+
SELECT '{"aaa":"absr"}'::jsonb::hstore;
7+
hstore
8+
---------------
9+
"aaa"=>"absr"
10+
(1 row)
11+
12+
SELECT '{"aaa":"absr"}'::jsonb::hstore->'aaa';
13+
?column?
14+
----------
15+
absr
16+
(1 row)
17+
18+
SELECT '{"aaa":1234}'::jsonb::hstore;
19+
hstore
20+
---------------
21+
"aaa"=>"1234"
22+
(1 row)
23+
24+
SELECT '{"aaa":1234}'::jsonb::hstore->'aaa';
25+
?column?
26+
----------
27+
1234
28+
(1 row)
29+
30+
SELECT '{"aaa":true}'::jsonb::hstore;
31+
hstore
32+
---------------
33+
"aaa"=>"true"
34+
(1 row)
35+
36+
SELECT '{"aaa":true}'::jsonb::hstore->'aaa';
37+
?column?
38+
----------
39+
true
40+
(1 row)
41+
42+
SELECT '{"aaa":null}'::jsonb::hstore;
43+
hstore
44+
-------------
45+
"aaa"=>NULL
46+
(1 row)
47+
48+
SELECT '{"aaa":null}'::jsonb::hstore->'aaa';
49+
?column?
50+
----------
51+
52+
(1 row)
53+
54+
SELECT '{"1234":"absr"}'::jsonb::hstore;
55+
hstore
56+
----------------
57+
"1234"=>"absr"
58+
(1 row)
59+
60+
SELECT E'{"a": "\'ght"}'::jsonb::hstore;
61+
hstore
62+
-------------
63+
"a"=>"'ght"
64+
(1 row)
65+
66+
SELECT E'{"a": "\'ght"}'::jsonb::hstore->'a';
67+
?column?
68+
----------
69+
'ght
70+
(1 row)
71+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* The file is used to test cast_jsonb_to_hstore.sql
3+
*/
4+
CREATE EXTENSION hstore;
5+
CREATE EXTENSION cast_jsonb_to_hstore;
6+
7+
SELECT '{"aaa":"absr"}'::jsonb::hstore;
8+
9+
SELECT '{"aaa":"absr"}'::jsonb::hstore->'aaa';
10+
11+
SELECT '{"aaa":1234}'::jsonb::hstore;
12+
13+
SELECT '{"aaa":1234}'::jsonb::hstore->'aaa';
14+
15+
SELECT '{"aaa":true}'::jsonb::hstore;
16+
17+
SELECT '{"aaa":true}'::jsonb::hstore->'aaa';
18+
19+
SELECT '{"aaa":null}'::jsonb::hstore;
20+
21+
SELECT '{"aaa":null}'::jsonb::hstore->'aaa';
22+
23+
SELECT '{"1234":"absr"}'::jsonb::hstore;
24+
25+
SELECT E'{"a": "\'ght"}'::jsonb::hstore;
26+
27+
SELECT E'{"a": "\'ght"}'::jsonb::hstore->'a';

0 commit comments

Comments
 (0)