Skip to content

Commit 9ceb350

Browse files
authored
Merge pull request #117 from cipherstash/jsonb-functions-take-eql_v1_encrypted
Jsonb functions accept eql_v2_encrypted as selector param
2 parents 2905a33 + 9eb5bc8 commit 9ceb350

File tree

5 files changed

+112
-63
lines changed

5 files changed

+112
-63
lines changed

src/encrypted/functions.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,15 @@ AS $$
7373
$$ LANGUAGE plpgsql;
7474

7575

76+
CREATE FUNCTION eql_v2.meta_data(val jsonb)
77+
RETURNS jsonb
78+
IMMUTABLE STRICT PARALLEL SAFE
79+
AS $$
80+
BEGIN
81+
RETURN jsonb_build_object(
82+
'i', val->'i',
83+
'v', val->'v'
84+
);
85+
END;
86+
$$ LANGUAGE plpgsql;
87+

src/jsonb/functions.sql

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@ AS $$
3030
sv eql_v2_encrypted[];
3131
found jsonb[];
3232
e jsonb;
33+
meta jsonb;
3334
ary boolean;
3435
BEGIN
3536

3637
IF val IS NULL THEN
3738
RETURN NEXT NULL;
3839
END IF;
3940

41+
-- Column identifier and version
42+
meta := eql_v2.meta_data(val);
43+
4044
sv := eql_v2.ste_vec(val);
4145

4246
FOR idx IN 1..array_length(sv, 1) LOOP
@@ -55,13 +59,14 @@ AS $$
5559

5660
IF ary THEN
5761
-- Wrap found array elements as eql_v2_encrypted
58-
RETURN NEXT jsonb_build_object(
62+
63+
RETURN NEXT (meta || jsonb_build_object(
5964
'sv', found,
6065
'a', 1
61-
)::eql_v2_encrypted;
66+
))::eql_v2_encrypted;
6267

6368
ELSE
64-
RETURN NEXT found[1]::eql_v2_encrypted;
69+
RETURN NEXT (meta || found[1])::eql_v2_encrypted;
6570
END IF;
6671

6772
END IF;
@@ -71,6 +76,16 @@ AS $$
7176
$$ LANGUAGE plpgsql;
7277

7378

79+
CREATE FUNCTION eql_v2.jsonb_path_query(val eql_v2_encrypted, selector eql_v2_encrypted)
80+
RETURNS SETOF eql_v2_encrypted
81+
IMMUTABLE STRICT PARALLEL SAFE
82+
AS $$
83+
BEGIN
84+
RETURN QUERY
85+
SELECT * FROM eql_v2.jsonb_path_query(val.data, eql_v2.selector(selector));
86+
END;
87+
$$ LANGUAGE plpgsql;
88+
7489

7590
CREATE FUNCTION eql_v2.jsonb_path_query(val eql_v2_encrypted, selector text)
7691
RETURNS SETOF eql_v2_encrypted
@@ -83,6 +98,8 @@ AS $$
8398
$$ LANGUAGE plpgsql;
8499

85100

101+
------------------------------------------------------------------------------------
102+
86103

87104
CREATE FUNCTION eql_v2.jsonb_path_exists(val jsonb, selector text)
88105
RETURNS boolean
@@ -96,6 +113,17 @@ AS $$
96113
$$ LANGUAGE plpgsql;
97114

98115

116+
CREATE FUNCTION eql_v2.jsonb_path_exists(val eql_v2_encrypted, selector eql_v2_encrypted)
117+
RETURNS boolean
118+
IMMUTABLE STRICT PARALLEL SAFE
119+
AS $$
120+
BEGIN
121+
RETURN EXISTS (
122+
SELECT eql_v2.jsonb_path_query(val, eql_v2.selector(selector))
123+
);
124+
END;
125+
$$ LANGUAGE plpgsql;
126+
99127

100128
CREATE FUNCTION eql_v2.jsonb_path_exists(val eql_v2_encrypted, selector text)
101129
RETURNS boolean
@@ -109,8 +137,8 @@ AS $$
109137
$$ LANGUAGE plpgsql;
110138

111139

112-
--
113-
--
140+
------------------------------------------------------------------------------------
141+
114142

115143
CREATE FUNCTION eql_v2.jsonb_path_query_first(val jsonb, selector text)
116144
RETURNS eql_v2_encrypted
@@ -128,6 +156,19 @@ AS $$
128156
$$ LANGUAGE plpgsql;
129157

130158

159+
CREATE FUNCTION eql_v2.jsonb_path_query_first(val eql_v2_encrypted, selector eql_v2_encrypted)
160+
RETURNS eql_v2_encrypted
161+
IMMUTABLE STRICT PARALLEL SAFE
162+
AS $$
163+
BEGIN
164+
RETURN (
165+
SELECT e
166+
FROM eql_v2.jsonb_path_query(val.data, eql_v2.selector(selector)) as e
167+
LIMIT 1
168+
);
169+
END;
170+
$$ LANGUAGE plpgsql;
171+
131172

132173
CREATE FUNCTION eql_v2.jsonb_path_query_first(val eql_v2_encrypted, selector text)
133174
RETURNS eql_v2_encrypted
@@ -144,7 +185,7 @@ $$ LANGUAGE plpgsql;
144185

145186

146187

147-
--
188+
------------------------------------------------------------------------------------
148189

149190

150191
-- =====================================================================

src/jsonb/functions_test.sql

Lines changed: 48 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,87 +5,62 @@ SELECT create_table_with_encrypted();
55
SELECT seed_encrypted_json();
66

77

8-
-- CREATE TABLE unencrypted
9-
-- (
10-
-- id bigint GENERATED ALWAYS AS IDENTITY,
11-
-- u jsonb,
12-
-- PRIMARY KEY(id)
13-
-- );
14-
-- INSERT INTO unencrypted (u)
15-
-- VALUES
16-
-- ('{"a": [1, 2, 3] }'),
17-
-- ('{"a": [1, 2, 3, 4] }'),
18-
-- ('{"a": [1, 2, 3, 4, 5] }');
19-
20-
-- SELECT *
21-
-- FROM unencrypted
22-
-- WHERE EXISTS (
23-
-- SELECT 1
24-
-- FROM jsonb_array_elements(u->'a') AS elem
25-
-- WHERE elem::int < 2
26-
-- );
27-
28-
-- SELECT seed_encrypted(get_array_ste_vec()::eql_v2_encrypted);
29-
-- SELECT *
30-
-- FROM encrypted
31-
-- WHERE EXISTS (
32-
-- SELECT 1
33-
-- FROM eql_v2.jsonb_array_elements(e->'f510853730e1c3dbd31b86963f029dd5') AS elem
34-
-- WHERE elem > '{"ocf": "b0c0a7385cb2f7dfe32a2649a9d8294794b8fc05585a240c1315f1e45ee7d9012616db3f01b43fa94351618670a29c24fc75df1392d52764c757b34495888b1c"}'::jsonb
35-
-- );
36-
37-
-- SELECT eql_v2.jsonb_path_query_first(e, '33743aed3ae636f6bf05cff11ac4b519') as e
38-
-- FROM encrypted
39-
-- WHERE eql_v2.jsonb_path_query(e, '33743aed3ae636f6bf05cff11ac4b519') IS NOT NULL;
40-
41-
42-
43-
-- "ocf": "b0c0a7385cb2f7dfe32a2649a9d8294794b8fc05585a240c1315f1e45ee7d9012616db3f01b43fa94351618670a29c24fc75df1392d52764c757b34495888b1c",
44-
45-
-- SELECT eql_v2.jsonb_array_elements(eql_v2.jsonb_path_query(e, 'f510853730e1c3dbd31b86963f029dd5')) as e FROM encrypted ;
46-
47-
48-
8+
-- ========================================================================
9+
--
10+
-- Selector &.a[*]
11+
-- -> 33743aed3ae636f6bf05cff11ac4b519
12+
--
13+
DO $$
14+
BEGIN
4915

50-
-- -- SELECT eql_v2.jsonb_path_exists(e, ''f510853730e1c3dbd31b86963f029dd5'') FROM encrypted;
51-
-- -- SELECT eql_v2.jsonb_path_query(e, 'f510853730e1c3dbd31b86963f029dd5') FROM encrypted;
16+
PERFORM seed_encrypted_json();
17+
PERFORM seed_encrypted(get_array_ste_vec()::eql_v2_encrypted);
5218

53-
-- -- SELECT eql_v2.jsonb_path_query(e, 'f510853730e1c3dbd31b86963f029dd5') as e FROM encrypted;
54-
-- -- SELECT eql_v2.jsonb_array_length(eql_v2.jsonb_path_query(e, 'f510853730e1c3dbd31b86963f029dd5')) as e FROM encrypted LIMIT 1;
55-
-- -- SELECT eql_v2.jsonb_array_elements(eql_v2.jsonb_path_query(e, 'f510853730e1c3dbd31b86963f029dd5')) as e FROM encrypted ;
56-
-- -- SELECT eql_v2.jsonb_array_elements_text(eql_v2.jsonb_path_query(e, 'f510853730e1c3dbd31b86963f029dd5')) as e FROM encrypted ;
57-
-- -- SELECT eql_v2.jsonb_array_length(eql_v2.jsonb_path_query(e, 'f510853730e1c3dbd31b86963f029dd5')) as e FROM encrypted LIMIT 1;
58-
-- -- SELECT eql_v2.jsonb_path_query(e, 'f510853730e1c3dbd31b86963f029dd5') as e FROM encrypted;
19+
PERFORM assert_result(
20+
'jsonb_array_elements returns array elements from jsonb_path_query result',
21+
'SELECT eql_v2.jsonb_array_elements(eql_v2.jsonb_path_query(e, ''f510853730e1c3dbd31b86963f029dd5'')) as e FROM encrypted;');
5922

23+
PERFORM assert_count(
24+
'jsonb_array_elements returns the correct number of array elements from jsonb_path_query result',
25+
'SELECT eql_v2.jsonb_array_elements(eql_v2.jsonb_path_query(e, ''f510853730e1c3dbd31b86963f029dd5'')) as e FROM encrypted;',
26+
5);
6027

28+
PERFORM assert_exception(
29+
'jsonb_array_elements exception if input is not an array',
30+
'SELECT eql_v2.jsonb_array_elements(eql_v2.jsonb_path_query(e, ''33743aed3ae636f6bf05cff11ac4b519'')) as e FROM encrypted LIMIT 1;');
6131

32+
END;
33+
$$ LANGUAGE plpgsql;
6234

63-
-- ========================================================================
6435
--
65-
-- Selector &.a[*]
36+
-- Selector &.a[*] as eql_v2_encrypted
6637
-- -> 33743aed3ae636f6bf05cff11ac4b519
6738
--
6839
DO $$
6940
DECLARE
70-
sv eql_v2_encrypted;
71-
results eql_v2_encrypted[];
41+
selector eql_v2_encrypted;
42+
7243
BEGIN
7344

7445
PERFORM seed_encrypted_json();
7546
PERFORM seed_encrypted(get_array_ste_vec()::eql_v2_encrypted);
7647

48+
selector := '{"s": "f510853730e1c3dbd31b86963f029dd5"}'::jsonb::eql_v2_encrypted;
49+
7750
PERFORM assert_result(
78-
'jsonb_array_elements returns array elements from jsonb_path_query result',
79-
'SELECT eql_v2.jsonb_array_elements(eql_v2.jsonb_path_query(e, ''f510853730e1c3dbd31b86963f029dd5'')) as e FROM encrypted;');
51+
'jsonb_array_elements returns array elements from jsonb_path_query result using eql_v2_encrypted selector',
52+
format('SELECT eql_v2.jsonb_array_elements_text(eql_v2.jsonb_path_query(e, %L::eql_v2_encrypted)) as e FROM encrypted;', selector));
8053

8154
PERFORM assert_count(
8255
'jsonb_array_elements returns the correct number of array elements from jsonb_path_query result',
83-
'SELECT eql_v2.jsonb_array_elements(eql_v2.jsonb_path_query(e, ''f510853730e1c3dbd31b86963f029dd5'')) as e FROM encrypted;',
56+
format('SELECT eql_v2.jsonb_array_elements_text(eql_v2.jsonb_path_query(e, %L::eql_v2_encrypted)) as e FROM encrypted;', selector),
8457
5);
8558

59+
selector := '{"s": "33743aed3ae636f6bf05cff11ac4b519"}'::jsonb::eql_v2_encrypted;
60+
8661
PERFORM assert_exception(
8762
'jsonb_array_elements exception if input is not an array',
88-
'SELECT eql_v2.jsonb_array_elements(eql_v2.jsonb_path_query(e, ''33743aed3ae636f6bf05cff11ac4b519'')) as e FROM encrypted LIMIT 1;');
63+
format('SELECT eql_v2.jsonb_array_elements_text(eql_v2.jsonb_path_query(e, %L::eql_v2_encrypted)) as e FROM encrypted;', selector));
8964

9065
END;
9166
$$ LANGUAGE plpgsql;
@@ -217,6 +192,22 @@ DO $$
217192
$$ LANGUAGE plpgsql;
218193

219194

195+
DO $$
196+
DECLARE
197+
result jsonb;
198+
BEGIN
199+
PERFORM seed_encrypted_json();
200+
201+
SELECT eql_v2.jsonb_path_query(e, '2517068c0d1f9d4d41d2c666211f785e')::jsonb FROM encrypted LIMIT 1 INTO result;
202+
203+
ASSERT result ? 'i';
204+
ASSERT result ? 'v';
205+
206+
END;
207+
$$ LANGUAGE plpgsql;
208+
209+
210+
220211
DO $$
221212
BEGIN
222213

src/ste_vec/functions.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ CREATE FUNCTION eql_v2.selector(val jsonb)
4545
IMMUTABLE STRICT PARALLEL SAFE
4646
AS $$
4747
BEGIN
48+
IF val IS NULL THEN
49+
RETURN NULL;
50+
END IF;
51+
4852
IF val ? 's' THEN
4953
RETURN val->>'s';
5054
END IF;

tests/test_helpers.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ AS $$
320320
"hm": "unique.%s",
321321
"b3": "blake3.%s",
322322
"bf": %s,
323+
323324
"v": 2
324325
}',
325326
random_key,

0 commit comments

Comments
 (0)