Thanks to visit codestin.com
Credit goes to github.com

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)