Skip to content

Commit 40e6d81

Browse files
author
Nikita Glukhov
committed
Add jsonpath @? support
1 parent d6d0109 commit 40e6d81

File tree

6 files changed

+510
-10
lines changed

6 files changed

+510
-10
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ ifdef USE_ASSERT_CHECKING
3030
override CFLAGS += -DUSE_ASSERT_CHECKING
3131
endif
3232

33+
override CPPFLAGS += $(CPPFLAGS) -I$(srcdir)/include
34+
3335
jsquery_gram.o: jsquery_scan.c
3436

3537
jsquery_gram.c: BISONFLAGS += -d

include/utils/jsonpath.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#define NO_JSONPATH 1

jsonb_gin_ops.c

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "miscadmin.h"
2222
#include "utils/builtins.h"
2323
#include "utils/jsonb.h"
24+
#include "utils/jsonpath.h"
2425

2526
#include "jsquery.h"
2627

@@ -59,6 +60,7 @@ typedef struct
5960
#define BLOOM_BITS 2
6061
#define JsonbNestedContainsStrategyNumber 13
6162
#define JsQueryMatchStrategyNumber 14
63+
#define JsonpathExistsStrategyNumber 15
6264

6365
typedef struct
6466
{
@@ -584,7 +586,8 @@ gin_compare_partial_jsonb_value_path(PG_FUNCTION_ARGS)
584586
StrategyNumber strategy = PG_GETARG_UINT16(2);
585587
int32 result;
586588

587-
if (strategy == JsQueryMatchStrategyNumber)
589+
if (strategy == JsQueryMatchStrategyNumber ||
590+
strategy == JsonpathExistsStrategyNumber)
588591
{
589592
KeyExtra *extra = (KeyExtra *)PG_GETARG_POINTER(3);
590593
ExtractedNode *node = extra->node;
@@ -780,7 +783,6 @@ gin_extract_jsonb_query_value_path(PG_FUNCTION_ARGS)
780783
int i, n;
781784
uint32 *bloom;
782785
Entries e = {0};
783-
JsQuery *jq;
784786
ExtractedNode *root;
785787

786788
switch(strategy)
@@ -805,9 +807,20 @@ gin_extract_jsonb_query_value_path(PG_FUNCTION_ARGS)
805807
break;
806808

807809
case JsQueryMatchStrategyNumber:
808-
jq = PG_GETARG_JSQUERY(0);
809-
root = extractJsQuery(jq, make_value_path_entry_handler,
810-
check_value_path_entry_handler, (Pointer)&e);
810+
#ifndef NO_JSONPATH
811+
case JsonpathExistsStrategyNumber:
812+
if (strategy == JsonpathExistsStrategyNumber)
813+
root = extractJsonPath(PG_GETARG_JSONPATH_P(0),
814+
make_value_path_entry_handler,
815+
check_value_path_entry_handler,
816+
(Pointer)&e);
817+
else
818+
#endif
819+
root = extractJsQuery(PG_GETARG_JSQUERY(0),
820+
make_value_path_entry_handler,
821+
check_value_path_entry_handler,
822+
(Pointer)&e);
823+
811824
if (root)
812825
{
813826
*nentries = e.count;
@@ -864,6 +877,7 @@ gin_consistent_jsonb_value_path(PG_FUNCTION_ARGS)
864877
break;
865878

866879
case JsQueryMatchStrategyNumber:
880+
case JsonpathExistsStrategyNumber:
867881
if (nkeys == 0)
868882
res = true;
869883
else
@@ -925,6 +939,7 @@ gin_triconsistent_jsonb_value_path(PG_FUNCTION_ARGS)
925939
break;
926940

927941
case JsQueryMatchStrategyNumber:
942+
case JsonpathExistsStrategyNumber:
928943
if (nkeys == 0)
929944
res = GIN_MAYBE;
930945
else
@@ -1047,7 +1062,8 @@ gin_compare_partial_jsonb_path_value(PG_FUNCTION_ARGS)
10471062
{
10481063
result = (key->hash > partial_key->hash) ? 1 : -1;
10491064
}
1050-
else if (strategy == JsQueryMatchStrategyNumber)
1065+
else if (strategy == JsQueryMatchStrategyNumber ||
1066+
strategy == JsonpathExistsStrategyNumber)
10511067
{
10521068
KeyExtra *extra = (KeyExtra *)PG_GETARG_POINTER(3);
10531069
ExtractedNode *node = extra->node;
@@ -1245,7 +1261,6 @@ gin_extract_jsonb_query_path_value_internal(FunctionCallInfo fcinfo, bool lax)
12451261
int i;
12461262
Entries e = {0};
12471263
PathValueExtra extra;
1248-
JsQuery *jq;
12491264
ExtractedNode *root;
12501265

12511266
extra.entries = &e;
@@ -1259,9 +1274,20 @@ gin_extract_jsonb_query_path_value_internal(FunctionCallInfo fcinfo, bool lax)
12591274
break;
12601275

12611276
case JsQueryMatchStrategyNumber:
1262-
jq = PG_GETARG_JSQUERY(0);
1263-
root = extractJsQuery(jq, make_path_value_entry_handler,
1264-
check_path_value_entry_handler, (Pointer) &extra);
1277+
#ifndef NO_JSONPATH
1278+
case JsonpathExistsStrategyNumber:
1279+
if (strategy == JsonpathExistsStrategyNumber)
1280+
root = extractJsonPath(PG_GETARG_JSONPATH_P(0),
1281+
make_path_value_entry_handler,
1282+
check_path_value_entry_handler,
1283+
(Pointer) &extra);
1284+
else
1285+
#endif
1286+
root = extractJsQuery(PG_GETARG_JSQUERY(0),
1287+
make_path_value_entry_handler,
1288+
check_path_value_entry_handler,
1289+
(Pointer) &extra);
1290+
12651291
if (root)
12661292
{
12671293
*nentries = e.count;
@@ -1329,6 +1355,7 @@ gin_consistent_jsonb_path_value(PG_FUNCTION_ARGS)
13291355
break;
13301356

13311357
case JsQueryMatchStrategyNumber:
1358+
case JsonpathExistsStrategyNumber:
13321359
if (nkeys == 0)
13331360
res = true;
13341361
else
@@ -1390,6 +1417,7 @@ gin_triconsistent_jsonb_path_value(PG_FUNCTION_ARGS)
13901417
break;
13911418

13921419
case JsQueryMatchStrategyNumber:
1420+
case JsonpathExistsStrategyNumber:
13931421
if (nkeys == 0)
13941422
res = GIN_MAYBE;
13951423
else

jsquery--1.1.sql

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,3 +329,27 @@ CREATE OR REPLACE FUNCTION gin_debug_query_laxpath_value(jsquery)
329329
RETURNS text
330330
AS 'MODULE_PATHNAME'
331331
LANGUAGE C STRICT IMMUTABLE;
332+
333+
-- add support for operator @? (jsonb, jsonpath) if type jsonpath exists in catalog
334+
DO LANGUAGE plpgsql
335+
$$
336+
BEGIN
337+
PERFORM
338+
FROM
339+
pg_type t,
340+
pg_namespace ns
341+
WHERE
342+
t.typname = 'jsonpath' AND
343+
t.typnamespace = ns.oid AND
344+
ns.nspname = 'pg_catalog';
345+
346+
IF FOUND THEN
347+
ALTER OPERATOR FAMILY jsonb_path_value_ops USING gin
348+
ADD OPERATOR 15 @? (jsonb, jsonpath);
349+
ALTER OPERATOR FAMILY jsonb_laxpath_value_ops USING gin
350+
ADD OPERATOR 15 @? (jsonb, jsonpath);
351+
ALTER OPERATOR FAMILY jsonb_value_path_ops USING gin
352+
ADD OPERATOR 15 @? (jsonb, jsonpath);
353+
END IF;
354+
END
355+
$$;

jsquery.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "fmgr.h"
2020
#include "utils/numeric.h"
2121
#include "utils/jsonb.h"
22+
#include "utils/jsonpath.h"
2223

2324
typedef struct
2425
{
@@ -243,6 +244,10 @@ bool isLogicalNodeType(ExtractedNodeType type);
243244

244245
ExtractedNode *extractJsQuery(JsQuery *jq, MakeEntryHandler makeHandler,
245246
CheckEntryHandler checkHandler, Pointer extra);
247+
#ifndef NO_JSONPATH
248+
ExtractedNode *extractJsonPath(JsonPath *jp, MakeEntryHandler makeHandler,
249+
CheckEntryHandler checkHandler, Pointer extra);
250+
#endif
246251
char *debugJsQuery(JsQuery *jq, MakeEntryHandler makeHandler,
247252
CheckEntryHandler checkHandler, Pointer extra);
248253
bool queryNeedRecheck(ExtractedNode *node);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy