Skip to content

Commit 0ab9809

Browse files
author
Nikita Glukhov
committed
Add generic json support in user functions
1 parent 1e2c673 commit 0ab9809

File tree

6 files changed

+271
-17
lines changed

6 files changed

+271
-17
lines changed

src/backend/tsearch/to_tsany.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ typedef struct TSVectorBuildState
4242
Oid cfgId;
4343
} TSVectorBuildState;
4444

45-
static void add_to_tsvector(void *_state, char *elem_value, int elem_len);
45+
static void add_to_tsvector(void *_state, const char *elem_value, int elem_len);
4646

4747

4848
Datum
@@ -360,7 +360,13 @@ jsonb_to_tsvector(PG_FUNCTION_ARGS)
360360
* Worker function for json(_string)_to_tsvector(_byid)
361361
*/
362362
static TSVector
363-
json_to_tsvector_worker(Oid cfgId, text *json, uint32 flags)
363+
json_to_tsvector_worker(Oid cfgId,
364+
#ifndef JSON_GENERIC
365+
text *json,
366+
#else
367+
Jsonb *json,
368+
#endif
369+
uint32 flags)
364370
{
365371
TSVectorBuildState state;
366372
ParsedText prs;
@@ -370,7 +376,11 @@ json_to_tsvector_worker(Oid cfgId, text *json, uint32 flags)
370376
state.prs = &prs;
371377
state.cfgId = cfgId;
372378

379+
#ifndef JSON_GENERIC
373380
iterate_json_values(json, flags, &state, add_to_tsvector);
381+
#else
382+
iterate_jsonb_values(json, flags, &state, add_to_tsvector);
383+
#endif
374384

375385
return make_tsvector(&prs);
376386
}
@@ -379,7 +389,11 @@ Datum
379389
json_string_to_tsvector_byid(PG_FUNCTION_ARGS)
380390
{
381391
Oid cfgId = PG_GETARG_OID(0);
392+
#ifndef JSON_GENERIC
382393
text *json = PG_GETARG_TEXT_P(1);
394+
#else
395+
Jsonb *json = DatumGetJsontP(PG_GETARG_DATUM(1));
396+
#endif
383397
TSVector result;
384398

385399
result = json_to_tsvector_worker(cfgId, json, jtiString);
@@ -391,7 +405,11 @@ json_string_to_tsvector_byid(PG_FUNCTION_ARGS)
391405
Datum
392406
json_string_to_tsvector(PG_FUNCTION_ARGS)
393407
{
408+
#ifndef JSON_GENERIC
394409
text *json = PG_GETARG_TEXT_P(0);
410+
#else
411+
Jsonb *json = DatumGetJsontP(PG_GETARG_DATUM(0));
412+
#endif
395413
Oid cfgId;
396414
TSVector result;
397415

@@ -406,7 +424,11 @@ Datum
406424
json_to_tsvector_byid(PG_FUNCTION_ARGS)
407425
{
408426
Oid cfgId = PG_GETARG_OID(0);
427+
#ifndef JSON_GENERIC
409428
text *json = PG_GETARG_TEXT_P(1);
429+
#else
430+
Jsonb *json = DatumGetJsontP(PG_GETARG_DATUM(1));
431+
#endif
410432
Jsonb *jbFlags = PG_GETARG_JSONB_P(2);
411433
TSVector result;
412434
uint32 flags = parse_jsonb_index_flags(jbFlags);
@@ -421,7 +443,11 @@ json_to_tsvector_byid(PG_FUNCTION_ARGS)
421443
Datum
422444
json_to_tsvector(PG_FUNCTION_ARGS)
423445
{
446+
#ifndef JSON_GENERIC
424447
text *json = PG_GETARG_TEXT_P(0);
448+
#else
449+
Jsonb *json = DatumGetJsontP(PG_GETARG_DATUM(0));
450+
#endif
425451
Jsonb *jbFlags = PG_GETARG_JSONB_P(1);
426452
Oid cfgId;
427453
TSVector result;
@@ -439,7 +465,7 @@ json_to_tsvector(PG_FUNCTION_ARGS)
439465
* Parse lexemes in an element of a json(b) value, add to TSVectorBuildState.
440466
*/
441467
static void
442-
add_to_tsvector(void *_state, char *elem_value, int elem_len)
468+
add_to_tsvector(void *_state, const char *elem_value, int elem_len)
443469
{
444470
TSVectorBuildState *state = (TSVectorBuildState *) _state;
445471
ParsedText *prs = state->prs;
@@ -459,7 +485,7 @@ add_to_tsvector(void *_state, char *elem_value, int elem_len)
459485

460486
prevwords = prs->curwords;
461487

462-
parsetext(state->cfgId, prs, elem_value, elem_len);
488+
parsetext(state->cfgId, prs, (char *) elem_value, elem_len);
463489

464490
/*
465491
* If we extracted any words from this JSON element, advance pos to create

src/backend/tsearch/wparser.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,10 @@ ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS)
379379
text *opt = (PG_NARGS() > 3 && PG_GETARG_POINTER(3)) ? PG_GETARG_TEXT_P(3) : NULL;
380380
Jsonb *out;
381381
JsonTransformStringValuesAction action = (JsonTransformStringValuesAction) headline_json_value;
382+
JsonValue jv;
382383
HeadlineParsedText prs;
383384
HeadlineJsonState *state = palloc0(sizeof(HeadlineJsonState));
385+
Datum res;
384386

385387
memset(&prs, 0, sizeof(HeadlineParsedText));
386388
prs.lenwords = 32;
@@ -402,6 +404,9 @@ ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS)
402404

403405
out = transform_jsonb_string_values(jb, state, action);
404406

407+
/* flatten result to jsonb before jb freeing */
408+
res = JsonFlattenToJsonbDatum(out);
409+
405410
PG_FREE_IF_COPY(jb, 1);
406411
PG_FREE_IF_COPY(query, 2);
407412
if (opt)
@@ -415,7 +420,7 @@ ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS)
415420
pfree(prs.stopsel);
416421
}
417422

418-
PG_RETURN_JSONB_P(out);
423+
PG_RETURN_DATUM(res);
419424
}
420425

421426
Datum
@@ -450,7 +455,11 @@ Datum
450455
ts_headline_json_byid_opt(PG_FUNCTION_ARGS)
451456
{
452457
Oid tsconfig = PG_GETARG_OID(0);
458+
#ifndef JSON_GENERIC
453459
text *json = PG_GETARG_TEXT_P(1);
460+
#else
461+
Jsonb *json = DatumGetJsontP(PG_GETARG_DATUM(1));
462+
#endif
454463
TSQuery query = PG_GETARG_TSQUERY(2);
455464
text *opt = (PG_NARGS() > 3 && PG_GETARG_POINTER(3)) ? PG_GETARG_TEXT_P(3) : NULL;
456465
text *out;
@@ -477,7 +486,18 @@ ts_headline_json_byid_opt(PG_FUNCTION_ARGS)
477486
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
478487
errmsg("text search parser does not support headline creation")));
479488

489+
#ifndef JSON_GENERIC
480490
out = transform_json_string_values(json, state, action);
491+
#else
492+
{
493+
Jsonb *jsonb = transform_jsonb_string_values(json, state, action);
494+
char *str = JsonToCString(&jsonb->root);
495+
496+
out = cstring_to_text(str);
497+
498+
pfree(str);
499+
}
500+
#endif
481501

482502
PG_FREE_IF_COPY(json, 1);
483503
PG_FREE_IF_COPY(query, 2);

src/backend/utils/adt/json.c

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,65 @@
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
14+
15+
#define JSON_C
16+
17+
#define JSONXOID JSONOID
18+
19+
#define jsonb_in _json_in
20+
#define jsonb_recv _json_recv
21+
22+
#define jsonb_out json_out
23+
#define jsonb_send json_send
24+
#define array_to_jsonb array_to_json
25+
#define row_to_jsonb row_to_json
26+
#define row_to_jsonb_pretty row_to_json_pretty
27+
#define to_jsonb to_json
28+
#define jsonb_agg_transfn json_agg_transfn
29+
#define jsonb_agg_finalfn json_agg_finalfn
30+
#define jsonb_object_agg_transfn json_object_agg_transfn
31+
#define jsonb_object_agg_finalfn json_object_agg_finalfn
32+
#define jsonb_build_object json_build_object
33+
#define jsonb_build_object_noargs json_build_object_noargs
34+
#define jsonb_build_array json_build_array
35+
#define jsonb_build_array_noargs json_build_array_noargs
36+
#define jsonb_object json_object
37+
#define jsonb_object_two_arg json_object_two_arg
38+
#define jsonb_typeof json_typeof
39+
40+
#define jsonb_array_element json_array_element
41+
#define jsonb_array_element_text json_array_element_text
42+
#define jsonb_array_elements json_array_elements
43+
#define jsonb_array_elements_text json_array_elements_text
44+
#define jsonb_array_length json_array_length
45+
#define jsonb_canonical json_canonical
46+
#define jsonb_concat json_concat
47+
#define jsonb_delete json_delete
48+
#define jsonb_delete_idx json_delete_idx
49+
#define jsonb_delete_path json_delete_path
50+
#define jsonb_delete_array json_delete_array
51+
#define jsonb_each json_each
52+
#define jsonb_each_text json_each_text
53+
#define jsonb_insert json_insert
54+
#define jsonb_extract_path json_extract_path
55+
#define jsonb_extract_path_text json_extract_path_text
56+
#define jsonb_object_field json_object_field
57+
#define jsonb_object_field_text json_object_field_text
58+
#define jsonb_object_keys json_object_keys
59+
#define jsonb_populate_record json_populate_record
60+
#define jsonb_populate_recordset json_populate_recordset
61+
#define jsonb_pretty json_pretty
62+
#define jsonb_set json_set
63+
#define jsonb_set_lax json_set_lax
64+
#define jsonb_strip_nulls json_strip_nulls
65+
#define jsonb_to_record json_to_record
66+
#define jsonb_to_recordset json_to_recordset
67+
#define jsonb_get_element json_get_element
68+
#define jsonb_set_element json_set_element
69+
70+
#define JsonxContainerOps (&jsontContainerOps)
71+
#define JsonxPGetDatum(json) JsontPGetDatum(json)
72+
1473
#include "postgres.h"
1574

1675
#include "catalog/pg_type.h"
@@ -66,9 +125,11 @@ static void json_categorize_type(Oid typoid,
66125
static void datum_to_json(Datum val, bool is_null, StringInfo result,
67126
JsonTypeCategory tcategory, Oid outfuncoid,
68127
bool key_scalar);
128+
#ifndef JSON_GENERIC
69129
static void add_json(Datum val, bool is_null, StringInfo result,
70130
Oid val_type, bool key_scalar);
71131
static text *catenate_stringinfo_string(StringInfo buffer, const char *addon);
132+
#endif
72133

73134
/*
74135
* Input.
@@ -88,6 +149,7 @@ json_in(PG_FUNCTION_ARGS)
88149
PG_RETURN_TEXT_P(result);
89150
}
90151

152+
#ifndef JSON_GENERIC
91153
/*
92154
* Output.
93155
*/
@@ -113,6 +175,7 @@ json_send(PG_FUNCTION_ARGS)
113175
pq_sendtext(&buf, VARDATA_ANY(t), VARSIZE_ANY_EXHDR(t));
114176
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
115177
}
178+
#endif
116179

117180
/*
118181
* Binary receive.
@@ -626,6 +689,8 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
626689
ReleaseTupleDesc(tupdesc);
627690
}
628691

692+
#ifndef JSON_GENERIC
693+
629694
/*
630695
* Append JSON text for "val" to "result".
631696
*
@@ -657,6 +722,8 @@ add_json(Datum val, bool is_null, StringInfo result,
657722
datum_to_json(val, is_null, result, tcategory, outfuncoid, key_scalar);
658723
}
659724

725+
#endif
726+
660727
/*
661728
* SQL function array_to_json(row)
662729
*/
@@ -723,6 +790,8 @@ row_to_json_pretty(PG_FUNCTION_ARGS)
723790
PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
724791
}
725792

793+
#ifndef JSON_GENERIC
794+
726795
/*
727796
* SQL function to_json(anyvalue)
728797
*/
@@ -1271,7 +1340,7 @@ json_object_two_arg(PG_FUNCTION_ARGS)
12711340

12721341
PG_RETURN_TEXT_P(rval);
12731342
}
1274-
1343+
#endif
12751344

12761345
/*
12771346
* Produce a JSON string literal, properly escaping characters in the text.
@@ -1318,6 +1387,7 @@ escape_json(StringInfo buf, const char *str)
13181387
appendStringInfoCharMacro(buf, '"');
13191388
}
13201389

1390+
#ifndef JSON_GENERIC
13211391
/*
13221392
* SQL function json_typeof(json) -> text
13231393
*
@@ -1375,3 +1445,8 @@ json_typeof(PG_FUNCTION_ARGS)
13751445

13761446
PG_RETURN_TEXT_P(cstring_to_text(type));
13771447
}
1448+
1449+
#endif
1450+
1451+
#include "jsonb.c"
1452+
#include "jsonfuncs.c"

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