@@ -241,18 +241,16 @@ $$ LANGUAGE plpgsql;
241241
242242
243243
244- -- ! @brief Extract encrypted JSONB as array for GIN indexing
244+ -- ! @brief Extract full encrypted JSONB elements as array
245245-- !
246- -- ! Extracts the encrypted JSONB data and returns it as a native jsonb[]
247- -- ! array. This enables efficient GIN indexing using PostgreSQL's built-in array_ops
248- -- ! which has native hash support for jsonb elements.
246+ -- ! Extracts all JSONB elements from the STE vector including non-deterministic fields.
247+ -- ! Use jsonb_array() instead for GIN indexing and containment queries.
249248-- !
250249-- ! @param val jsonb containing encrypted EQL payload
251- -- ! @return jsonb[] Array of JSONB elements for indexing
250+ -- ! @return jsonb[] Array of full JSONB elements
252251-- !
253- -- ! @note Preferred for GIN indexes as jsonb has native hash support
254- -- ! @see eql_v2.jsonb_array(eql_v2_encrypted)
255- CREATE FUNCTION eql_v2 .jsonb_array(val jsonb)
252+ -- ! @see eql_v2.jsonb_array
253+ CREATE FUNCTION eql_v2 .jsonb_array_from_array_elements(val jsonb)
256254RETURNS jsonb[]
257255IMMUTABLE STRICT PARALLEL SAFE
258256LANGUAGE SQL
@@ -266,21 +264,53 @@ AS $$
266264$$;
267265
268266
269- -- ! @brief Extract encrypted JSONB as array from encrypted column value
270- -- !
271- -- ! Extracts the encrypted JSONB data from an encrypted column value and returns it as a
272- -- ! native jsonb[] array for GIN indexing.
267+ -- ! @brief Extract full encrypted JSONB elements as array from encrypted column
273268-- !
274269-- ! @param val eql_v2_encrypted Encrypted column value
275- -- ! @return jsonb[] Array of JSONB elements for indexing
270+ -- ! @return jsonb[] Array of full JSONB elements
276271-- !
277- -- ! @example
278- -- ! -- Create GIN index for containment queries
279- -- ! CREATE INDEX idx_jsonb ON mytable USING GIN (eql_v2.jsonb_array(encrypted_col));
272+ -- ! @see eql_v2.jsonb_array_from_array_elements(jsonb)
273+ CREATE FUNCTION eql_v2 .jsonb_array_from_array_elements(val eql_v2_encrypted)
274+ RETURNS jsonb[]
275+ IMMUTABLE STRICT PARALLEL SAFE
276+ LANGUAGE SQL
277+ AS $$
278+ SELECT eql_v2 .jsonb_array_from_array_elements (val .data );
279+ $$;
280+
281+
282+ -- ! @brief Extract deterministic fields as array for GIN indexing
283+ -- !
284+ -- ! Extracts only deterministic search term fields (s, b3, hm, ocv, ocf) from each
285+ -- ! STE vector element. Excludes non-deterministic ciphertext for correct containment
286+ -- ! comparison using PostgreSQL's native @> operator.
287+ -- !
288+ -- ! @param val jsonb containing encrypted EQL payload
289+ -- ! @return jsonb[] Array of JSONB elements with only deterministic fields
290+ -- !
291+ -- ! @note Use this for GIN indexes and containment queries
292+ -- ! @see eql_v2.jsonb_contains
293+ CREATE FUNCTION eql_v2 .jsonb_array(val jsonb)
294+ RETURNS jsonb[]
295+ IMMUTABLE STRICT PARALLEL SAFE
296+ LANGUAGE SQL
297+ AS $$
298+ SELECT ARRAY(
299+ SELECT jsonb_object_agg(kv .key , kv .value )
300+ FROM jsonb_array_elements(
301+ CASE WHEN val ? ' sv' THEN val- > ' sv' ELSE jsonb_build_array(val) END
302+ ) AS elem,
303+ LATERAL jsonb_each(elem) AS kv(key, value)
304+ WHERE kv .key IN (' s' , ' b3' , ' hm' , ' ocv' , ' ocf' )
305+ GROUP BY elem
306+ );
307+ $$;
308+
309+
310+ -- ! @brief Extract deterministic fields as array from encrypted column
280311-- !
281- -- ! -- Query using containment
282- -- ! SELECT * FROM mytable
283- -- ! WHERE eql_v2.jsonb_array(encrypted_col) @> eql_v2.jsonb_array(search_value);
312+ -- ! @param val eql_v2_encrypted Encrypted column value
313+ -- ! @return jsonb[] Array of JSONB elements with only deterministic fields
284314-- !
285315-- ! @see eql_v2.jsonb_array(jsonb)
286316CREATE FUNCTION eql_v2 .jsonb_array(val eql_v2_encrypted)
@@ -321,6 +351,46 @@ AS $$
321351$$;
322352
323353
354+ -- ! @brief GIN-indexable JSONB containment check (encrypted, jsonb)
355+ -- !
356+ -- ! Checks if encrypted value 'a' contains all JSONB elements from jsonb value 'b'.
357+ -- ! Uses jsonb[] arrays internally for native PostgreSQL GIN index support.
358+ -- !
359+ -- ! @param a eql_v2_encrypted Container value (typically a table column)
360+ -- ! @param b jsonb JSONB value to search for
361+ -- ! @return Boolean True if a contains all elements of b
362+ -- !
363+ -- ! @see eql_v2.jsonb_array
364+ -- ! @see eql_v2.jsonb_contains(eql_v2_encrypted, eql_v2_encrypted)
365+ CREATE FUNCTION eql_v2 .jsonb_contains(a eql_v2_encrypted, b jsonb)
366+ RETURNS boolean
367+ IMMUTABLE STRICT PARALLEL SAFE
368+ LANGUAGE SQL
369+ AS $$
370+ SELECT eql_v2 .jsonb_array (a) @> eql_v2 .jsonb_array (b);
371+ $$;
372+
373+
374+ -- ! @brief GIN-indexable JSONB containment check (jsonb, encrypted)
375+ -- !
376+ -- ! Checks if jsonb value 'a' contains all JSONB elements from encrypted value 'b'.
377+ -- ! Uses jsonb[] arrays internally for native PostgreSQL GIN index support.
378+ -- !
379+ -- ! @param a jsonb Container JSONB value
380+ -- ! @param b eql_v2_encrypted Encrypted value to search for
381+ -- ! @return Boolean True if a contains all elements of b
382+ -- !
383+ -- ! @see eql_v2.jsonb_array
384+ -- ! @see eql_v2.jsonb_contains(eql_v2_encrypted, eql_v2_encrypted)
385+ CREATE FUNCTION eql_v2 .jsonb_contains(a jsonb, b eql_v2_encrypted)
386+ RETURNS boolean
387+ IMMUTABLE STRICT PARALLEL SAFE
388+ LANGUAGE SQL
389+ AS $$
390+ SELECT eql_v2 .jsonb_array (a) @> eql_v2 .jsonb_array (b);
391+ $$;
392+
393+
324394-- ! @brief GIN-indexable JSONB "is contained by" check
325395-- !
326396-- ! Checks if all JSONB elements from 'a' are contained in 'b'.
@@ -341,6 +411,46 @@ AS $$
341411$$;
342412
343413
414+ -- ! @brief GIN-indexable JSONB "is contained by" check (encrypted, jsonb)
415+ -- !
416+ -- ! Checks if all JSONB elements from encrypted value 'a' are contained in jsonb value 'b'.
417+ -- ! Uses jsonb[] arrays internally for native PostgreSQL GIN index support.
418+ -- !
419+ -- ! @param a eql_v2_encrypted Value to check (typically a table column)
420+ -- ! @param b jsonb Container JSONB value
421+ -- ! @return Boolean True if all elements of a are contained in b
422+ -- !
423+ -- ! @see eql_v2.jsonb_array
424+ -- ! @see eql_v2.jsonb_contained_by(eql_v2_encrypted, eql_v2_encrypted)
425+ CREATE FUNCTION eql_v2 .jsonb_contained_by(a eql_v2_encrypted, b jsonb)
426+ RETURNS boolean
427+ IMMUTABLE STRICT PARALLEL SAFE
428+ LANGUAGE SQL
429+ AS $$
430+ SELECT eql_v2 .jsonb_array (a) < @ eql_v2 .jsonb_array (b);
431+ $$;
432+
433+
434+ -- ! @brief GIN-indexable JSONB "is contained by" check (jsonb, encrypted)
435+ -- !
436+ -- ! Checks if all JSONB elements from jsonb value 'a' are contained in encrypted value 'b'.
437+ -- ! Uses jsonb[] arrays internally for native PostgreSQL GIN index support.
438+ -- !
439+ -- ! @param a jsonb Value to check
440+ -- ! @param b eql_v2_encrypted Container encrypted value
441+ -- ! @return Boolean True if all elements of a are contained in b
442+ -- !
443+ -- ! @see eql_v2.jsonb_array
444+ -- ! @see eql_v2.jsonb_contained_by(eql_v2_encrypted, eql_v2_encrypted)
445+ CREATE FUNCTION eql_v2 .jsonb_contained_by(a jsonb, b eql_v2_encrypted)
446+ RETURNS boolean
447+ IMMUTABLE STRICT PARALLEL SAFE
448+ LANGUAGE SQL
449+ AS $$
450+ SELECT eql_v2 .jsonb_array (a) < @ eql_v2 .jsonb_array (b);
451+ $$;
452+
453+
344454-- ! @brief Check if STE vector array contains a specific encrypted element
345455-- !
346456-- ! Tests whether any element in the STE vector array 'a' contains the encrypted value 'b'.
0 commit comments