Skip to content

Commit b2248ec

Browse files
author
Nikita Glukhov
committed
Add optimization flags to debug functions
1 parent 85c7e1c commit b2248ec

File tree

4 files changed

+120
-69
lines changed

4 files changed

+120
-69
lines changed

jsonb_gin_ops.c

Lines changed: 70 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -765,37 +765,76 @@ gin_extract_jsonb_value_path(PG_FUNCTION_ARGS)
765765
PG_RETURN_POINTER(gin_extract_jsonb_value_path_internal(jb, nentries, NULL));
766766
}
767767

768-
Datum
769-
gin_debug_query_value_path(PG_FUNCTION_ARGS)
768+
static text *
769+
gin_debug_query_internal(FunctionCallInfo fcinfo,
770+
MakeEntryHandler makeHandler,
771+
CheckEntryHandler checkHandler, Pointer extra)
770772
{
771-
JsQuery *jq;
772-
Entries e = {0};
773+
JsQuery *jq = PG_GETARG_JSQUERY(0);
773774
ExtractedNode *root;
774775
char *s;
776+
int optimize = 0;
777+
778+
if (PG_GETARG_BOOL(1))
779+
optimize |= optFlatten;
780+
if (PG_GETARG_BOOL(2))
781+
optimize |= optSimplify;
782+
if (PG_GETARG_BOOL(3))
783+
optimize |= optSelectivity;
775784

776-
jq = PG_GETARG_JSQUERY(0);
777-
root = extractJsQuery(jq, make_value_path_entry_handler,
778-
check_value_path_entry_handler, (Pointer)&e);
785+
root = extractJsQuery(jq, optimize, makeHandler, checkHandler, extra);
779786
s = debugExtractedQuery(root);
780787

781-
PG_RETURN_TEXT_P(cstring_to_text(s));
788+
return cstring_to_text(s);
782789
}
783790

784-
#ifndef NO_JSONPATH
785791
Datum
786-
gin_debug_jsonpath_value_path(PG_FUNCTION_ARGS)
792+
gin_debug_query_value_path(PG_FUNCTION_ARGS)
787793
{
788-
JsonPath *jp;
789794
Entries e = {0};
795+
796+
PG_RETURN_TEXT_P(gin_debug_query_internal(fcinfo,
797+
make_value_path_entry_handler,
798+
check_value_path_entry_handler,
799+
(Pointer) &e));
800+
}
801+
802+
#ifndef NO_JSONPATH
803+
static text *
804+
gin_debug_jsonpath_internal(FunctionCallInfo fcinfo,
805+
bool arrayPathItems,
806+
MakeEntryHandler makeHandler,
807+
CheckEntryHandler checkHandler, Pointer extra)
808+
{
809+
JsonPath *jp = PG_GETARG_JSONPATH_P(0);
790810
ExtractedNode *root;
791811
char *s;
792-
793-
jp = PG_GETARG_JSONPATH_P(0);
794-
root = extractJsonPath(jp, false, false, make_value_path_entry_handler,
795-
check_value_path_entry_handler, (Pointer)&e);
812+
int optimize = 0;
813+
bool exists = PG_GETARG_BOOL(1);
814+
815+
if (PG_GETARG_BOOL(2))
816+
optimize |= optFlatten;
817+
if (PG_GETARG_BOOL(3))
818+
optimize |= optSimplify;
819+
if (PG_GETARG_BOOL(4))
820+
optimize |= optSelectivity;
821+
822+
root = extractJsonPath(jp, exists, arrayPathItems, optimize,
823+
makeHandler, checkHandler, extra);
796824
s = debugExtractedQuery(root);
797825

798-
PG_RETURN_TEXT_P(cstring_to_text(s));
826+
return cstring_to_text(s);
827+
}
828+
829+
Datum
830+
gin_debug_jsonpath_value_path(PG_FUNCTION_ARGS)
831+
{
832+
Entries e = {0};
833+
834+
PG_RETURN_TEXT_P(gin_debug_jsonpath_internal(fcinfo, false,
835+
make_value_path_entry_handler,
836+
check_value_path_entry_handler,
837+
(Pointer) &e));
799838
}
800839
#endif
801840

@@ -843,12 +882,14 @@ gin_extract_jsonb_query_value_path(PG_FUNCTION_ARGS)
843882
root = extractJsonPath(PG_GETARG_JSONPATH_P(0),
844883
strategy == JsonpathExistsStrategyNumber,
845884
false,
885+
optAll,
846886
make_value_path_entry_handler,
847887
check_value_path_entry_handler,
848888
(Pointer)&e);
849889
else
850890
#endif
851891
root = extractJsQuery(PG_GETARG_JSQUERY(0),
892+
optAll,
852893
make_value_path_entry_handler,
853894
check_value_path_entry_handler,
854895
(Pointer)&e);
@@ -1257,21 +1298,16 @@ gin_extract_jsonb_laxpath_value(PG_FUNCTION_ARGS)
12571298
static Datum
12581299
gin_debug_query_path_value_internal(FunctionCallInfo fcinfo, bool lax)
12591300
{
1260-
JsQuery *jq;
12611301
Entries e = {0};
12621302
PathValueExtra extra;
1263-
ExtractedNode *root;
1264-
char *s;
12651303

12661304
extra.entries = &e;
12671305
extra.lax = lax;
12681306

1269-
jq = PG_GETARG_JSQUERY(0);
1270-
root = extractJsQuery(jq, make_path_value_entry_handler,
1271-
check_path_value_entry_handler, (Pointer) &extra);
1272-
s = debugExtractedQuery(root);
1273-
1274-
PG_RETURN_TEXT_P(cstring_to_text(s));
1307+
PG_RETURN_TEXT_P(gin_debug_query_internal(fcinfo,
1308+
make_path_value_entry_handler,
1309+
check_path_value_entry_handler,
1310+
(Pointer) &extra));
12751311
}
12761312

12771313
Datum
@@ -1287,38 +1323,31 @@ gin_debug_query_laxpath_value(PG_FUNCTION_ARGS)
12871323
}
12881324

12891325
#ifndef NO_JSONPATH
1290-
static Datum
1326+
static text *
12911327
gin_debug_jsonpath_path_value_internal(FunctionCallInfo fcinfo, bool lax)
12921328
{
1293-
JsonPath *jp;
12941329
Entries e = {0};
12951330
PathValueExtra extra;
1296-
ExtractedNode *root;
1297-
char *s;
12981331

12991332
extra.entries = &e;
13001333
extra.lax = lax;
13011334

1302-
jp = PG_GETARG_JSONPATH_P(0);
1303-
root = extractJsonPath(jp, false, !lax,
1304-
make_path_value_entry_handler,
1305-
check_path_value_entry_handler,
1306-
(Pointer) &extra);
1307-
s = debugExtractedQuery(root);
1308-
1309-
PG_RETURN_TEXT_P(cstring_to_text(s));
1335+
return gin_debug_jsonpath_internal(fcinfo, !lax,
1336+
make_path_value_entry_handler,
1337+
check_path_value_entry_handler,
1338+
(Pointer) &extra);
13101339
}
13111340

13121341
Datum
13131342
gin_debug_jsonpath_path_value(PG_FUNCTION_ARGS)
13141343
{
1315-
PG_RETURN_DATUM(gin_debug_jsonpath_path_value_internal(fcinfo, false));
1344+
PG_RETURN_TEXT_P(gin_debug_jsonpath_path_value_internal(fcinfo, false));
13161345
}
13171346

13181347
Datum
13191348
gin_debug_jsonpath_laxpath_value(PG_FUNCTION_ARGS)
13201349
{
1321-
PG_RETURN_DATUM(gin_debug_jsonpath_path_value_internal(fcinfo, true));
1350+
PG_RETURN_TEXT_P(gin_debug_jsonpath_path_value_internal(fcinfo, true));
13221351
}
13231352
#endif
13241353

@@ -1355,12 +1384,14 @@ gin_extract_jsonb_query_path_value_internal(FunctionCallInfo fcinfo, bool lax)
13551384
root = extractJsonPath(PG_GETARG_JSONPATH_P(0),
13561385
strategy == JsonpathExistsStrategyNumber,
13571386
!lax,
1387+
optAll,
13581388
make_path_value_entry_handler,
13591389
check_path_value_entry_handler,
13601390
(Pointer) &extra);
13611391
else
13621392
#endif
13631393
root = extractJsQuery(PG_GETARG_JSQUERY(0),
1394+
optAll,
13641395
make_path_value_entry_handler,
13651396
check_path_value_entry_handler,
13661397
(Pointer) &extra);

jsquery--1.1.sql

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -315,17 +315,17 @@ CREATE OPERATOR CLASS jsonb_laxpath_value_ops
315315
FUNCTION 6 gin_triconsistent_jsonb_path_value(internal, smallint, anyarray, integer, internal, internal, internal),
316316
STORAGE bytea;
317317

318-
CREATE OR REPLACE FUNCTION gin_debug_query_value_path(jsquery)
318+
CREATE OR REPLACE FUNCTION gin_debug_query_value_path(jsquery, flatten bool = true, simplify bool = true, selectivity bool = true)
319319
RETURNS text
320320
AS 'MODULE_PATHNAME'
321321
LANGUAGE C STRICT IMMUTABLE;
322322

323-
CREATE OR REPLACE FUNCTION gin_debug_query_path_value(jsquery)
323+
CREATE OR REPLACE FUNCTION gin_debug_query_path_value(jsquery, flatten bool = true, simplify bool = true, selectivity bool = true)
324324
RETURNS text
325325
AS 'MODULE_PATHNAME'
326326
LANGUAGE C STRICT IMMUTABLE;
327327

328-
CREATE OR REPLACE FUNCTION gin_debug_query_laxpath_value(jsquery)
328+
CREATE OR REPLACE FUNCTION gin_debug_query_laxpath_value(jsquery, flatten bool = true, simplify bool = true, selectivity bool = true)
329329
RETURNS text
330330
AS 'MODULE_PATHNAME'
331331
LANGUAGE C STRICT IMMUTABLE;
@@ -357,17 +357,17 @@ BEGIN
357357
ALTER OPERATOR FAMILY jsonb_value_path_ops USING gin
358358
ADD OPERATOR 16 @@ (jsonb, jsonpath);
359359

360-
CREATE OR REPLACE FUNCTION gin_debug_jsonpath_value_path(jsonpath)
360+
CREATE OR REPLACE FUNCTION gin_debug_jsonpath_value_path(jsonpath, is_exists bool = false, flatten bool = true, simplify bool = true, selectivity bool = true)
361361
RETURNS text
362362
AS 'MODULE_PATHNAME'
363363
LANGUAGE C STRICT IMMUTABLE;
364364

365-
CREATE OR REPLACE FUNCTION gin_debug_jsonpath_path_value(jsonpath)
365+
CREATE OR REPLACE FUNCTION gin_debug_jsonpath_path_value(jsonpath, is_exists bool = false, flatten bool = true, simplify bool = true, selectivity bool = true)
366366
RETURNS text
367367
AS 'MODULE_PATHNAME'
368368
LANGUAGE C STRICT IMMUTABLE;
369369

370-
CREATE OR REPLACE FUNCTION gin_debug_jsonpath_laxpath_value(jsonpath)
370+
CREATE OR REPLACE FUNCTION gin_debug_jsonpath_laxpath_value(jsonpath, is_exists bool = false, flatten bool = true, simplify bool = true, selectivity bool = true)
371371
RETURNS text
372372
AS 'MODULE_PATHNAME'
373373
LANGUAGE C STRICT IMMUTABLE;

jsquery.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,20 @@ typedef int (*MakeEntryHandler)(ExtractedNode *node, Pointer extra);
242242
typedef bool (*CheckEntryHandler)(ExtractedNode *node, Pointer extra);
243243
bool isLogicalNodeType(ExtractedNodeType type);
244244

245-
ExtractedNode *extractJsQuery(JsQuery *jq, MakeEntryHandler makeHandler,
245+
typedef enum
246+
{
247+
optFlatten = 0x01,
248+
optSimplify = 0x02,
249+
optSelectivity = 0x04,
250+
optAll = 0x07
251+
} JsQueryOptFlags;
252+
253+
ExtractedNode *extractJsQuery(JsQuery *jq, int optimize,
254+
MakeEntryHandler makeHandler,
246255
CheckEntryHandler checkHandler, Pointer extra);
247256
#ifndef NO_JSONPATH
248257
ExtractedNode *extractJsonPath(JsonPath *jp, bool exists, bool arrayPathItems,
258+
int optimize,
249259
MakeEntryHandler makeHandler,
250260
CheckEntryHandler checkHandler, Pointer extra);
251261
#endif

jsquery_extract.c

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static int compareJsQueryItem(JsQueryItem *v1, JsQueryItem *v2);
3333
static void processGroup(ExtractedNode *node, int start, int end);
3434
static void simplifyRecursive(ExtractedNode *node);
3535
static SelectivityClass getScalarSelectivityClass(ExtractedNode *node);
36-
static ExtractedNode *makeEntries(ExtractedNode *node, MakeEntryHandler handler, Pointer extra);
36+
static ExtractedNode *makeEntries(ExtractedNode *node, bool skipNonSelective, MakeEntryHandler handler, Pointer extra);
3737
static void setSelectivityClass(ExtractedNode *node, CheckEntryHandler checkHandler, Pointer extra);
3838
static void debugPath(StringInfo buf, PathItem *path);
3939
static void debugValue(StringInfo buf, JsQueryItem *v);
@@ -1204,7 +1204,8 @@ getScalarSelectivityClass(ExtractedNode *node)
12041204
* Make entries for all leaf tree nodes using user-provided handler.
12051205
*/
12061206
static ExtractedNode *
1207-
makeEntries(ExtractedNode *node, MakeEntryHandler handler, Pointer extra)
1207+
makeEntries(ExtractedNode *node, bool skipNonSelective,
1208+
MakeEntryHandler handler, Pointer extra)
12081209
{
12091210
if (node->type == eAnd || node->type == eOr)
12101211
{
@@ -1216,11 +1217,12 @@ makeEntries(ExtractedNode *node, MakeEntryHandler handler, Pointer extra)
12161217
if (!child)
12171218
continue;
12181219
/* Skip non-selective AND children */
1219-
if (child->sClass > node->sClass &&
1220+
if (skipNonSelective &&
1221+
child->sClass > node->sClass &&
12201222
node->type == eAnd &&
12211223
!child->forceIndex)
12221224
continue;
1223-
child = makeEntries(child, handler, extra);
1225+
child = makeEntries(child, skipNonSelective, handler, extra);
12241226
if (child)
12251227
{
12261228
node->args.items[j] = child;
@@ -1319,34 +1321,48 @@ setSelectivityClass(ExtractedNode *node, CheckEntryHandler checkHandler,
13191321
}
13201322
}
13211323

1324+
static ExtractedNode *
1325+
emitExtractedQuery(ExtractedNode *root, int optimize,
1326+
MakeEntryHandler makeHandler,
1327+
CheckEntryHandler checkHandler,
1328+
Pointer extra)
1329+
{
1330+
if (!root)
1331+
return NULL;
1332+
1333+
if (optimize & optFlatten)
1334+
flatternTree(root);
1335+
1336+
if (optimize & optSimplify)
1337+
simplifyRecursive(root);
1338+
1339+
setSelectivityClass(root, checkHandler, extra);
1340+
1341+
return makeEntries(root, (optimize & optSelectivity) != 0, makeHandler, extra);
1342+
}
1343+
13221344
/*
13231345
* Turn jsquery into tree of entries using user-provided handler.
13241346
*/
13251347
ExtractedNode *
1326-
extractJsQuery(JsQuery *jq, MakeEntryHandler makeHandler,
1327-
CheckEntryHandler checkHandler, Pointer extra)
1348+
extractJsQuery(JsQuery *jq, int optimize, MakeEntryHandler makeHandler,
1349+
CheckEntryHandler checkHandler, Pointer extra)
13281350
{
13291351
ExtractedNode *root;
13301352
JsQueryItem jsq;
13311353

13321354
jsqInit(&jsq, jq);
13331355
root = recursiveExtract(&jsq, false, false, NULL);
1334-
if (root)
1335-
{
1336-
flatternTree(root);
1337-
simplifyRecursive(root);
1338-
setSelectivityClass(root, checkHandler, extra);
1339-
root = makeEntries(root, makeHandler, extra);
1340-
}
1341-
return root;
1356+
1357+
return emitExtractedQuery(root, optimize, makeHandler, checkHandler, extra);
13421358
}
13431359

13441360
#ifndef NO_JSONPATH
13451361
/*
13461362
* Turn jsonpath into tree of entries using user-provided handler.
13471363
*/
13481364
ExtractedNode *
1349-
extractJsonPath(JsonPath *jp, bool exists, bool arrayPathItems,
1365+
extractJsonPath(JsonPath *jp, bool exists, bool arrayPathItems, int optimize,
13501366
MakeEntryHandler makeHandler,
13511367
CheckEntryHandler checkHandler, Pointer extra)
13521368
{
@@ -1358,14 +1374,8 @@ extractJsonPath(JsonPath *jp, bool exists, bool arrayPathItems,
13581374
root = exists
13591375
? extractJsonPathExists(&jsp, lax, NULL)
13601376
: recursiveExtractJsonPathExpr(&jsp, lax, false, NULL);
1361-
if (root)
1362-
{
1363-
flatternTree(root);
1364-
simplifyRecursive(root);
1365-
setSelectivityClass(root, checkHandler, extra);
1366-
root = makeEntries(root, makeHandler, extra);
1367-
}
1368-
return root;
1377+
1378+
return emitExtractedQuery(root, optimize, makeHandler, checkHandler, extra);
13691379
}
13701380
#endif
13711381

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