Skip to content

Commit 261a5c1

Browse files
committed
Support 'q' flag in jsonpath 'like_regex' predicate
SQL/JSON standard defines that jsonpath 'like_regex' predicate should support the same set of flags as XQuery/XPath. It appears that implementation of 'q' flag was missed. This commit fixes that. Discussion: https://postgr.es/m/CAPpHfdtyfPsxLYiTjp5Ov8T5xGsB5t3CwE5%2B3PS%3DLLwA%2BxTJog%40mail.gmail.com Author: Nikita Glukhov, Alexander Korotkov
1 parent d8594d1 commit 261a5c1

File tree

8 files changed

+85
-0
lines changed

8 files changed

+85
-0
lines changed

src/backend/utils/adt/jsonpath.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,8 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
563563
appendStringInfoChar(buf, 'm');
564564
if (v->content.like_regex.flags & JSP_REGEX_WSPACE)
565565
appendStringInfoChar(buf, 'x');
566+
if (v->content.like_regex.flags & JSP_REGEX_QUOTE)
567+
appendStringInfoChar(buf, 'q');
566568

567569
appendStringInfoChar(buf, '"');
568570
}

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,17 @@ executeLikeRegex(JsonPathItem *jsp, JsonbValue *str, JsonbValue *rarg,
16641664
cxt->cflags &= ~REG_NEWLINE;
16651665
if (flags & JSP_REGEX_WSPACE)
16661666
cxt->cflags |= REG_EXPANDED;
1667+
1668+
/*
1669+
* 'q' flag can work together only with 'i'. When other is specified,
1670+
* then 'q' has no effect.
1671+
*/
1672+
if ((flags & JSP_REGEX_QUOTE) &&
1673+
!(flags & (JSP_REGEX_MLINE | JSP_REGEX_SLINE | JSP_REGEX_WSPACE)))
1674+
{
1675+
cxt->cflags &= ~REG_ADVANCED;
1676+
cxt->cflags |= REG_QUOTE;
1677+
}
16671678
}
16681679

16691680
if (RE_compile_and_execute(cxt->regex, str->val.string.val,

src/backend/utils/adt/jsonpath_gram.y

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,14 @@ makeItemLikeRegex(JsonPathParseItem *expr, JsonPathString *pattern,
510510
v->value.like_regex.flags |= JSP_REGEX_WSPACE;
511511
cflags |= REG_EXPANDED;
512512
break;
513+
case 'q':
514+
v->value.like_regex.flags |= JSP_REGEX_QUOTE;
515+
if (!(v->value.like_regex.flags & (JSP_REGEX_MLINE | JSP_REGEX_SLINE | JSP_REGEX_WSPACE)))
516+
{
517+
cflags &= ~REG_ADVANCED;
518+
cflags |= REG_QUOTE;
519+
}
520+
break;
513521
default:
514522
ereport(ERROR,
515523
(errcode(ERRCODE_SYNTAX_ERROR),

src/include/utils/jsonpath.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ typedef enum JsonPathItemType
9191
#define JSP_REGEX_SLINE 0x02 /* s flag, single-line mode */
9292
#define JSP_REGEX_MLINE 0x04 /* m flag, multi-line mode */
9393
#define JSP_REGEX_WSPACE 0x08 /* x flag, expanded syntax */
94+
#define JSP_REGEX_QUOTE 0x10 /* q flag, no special characters */
9495

9596
/*
9697
* Support functions to parse/construct binary value.

src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,6 +1622,42 @@ select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "adc\nabc", "
16221622
"abdacb"
16231623
(2 rows)
16241624

1625+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "q")');
1626+
jsonb_path_query
1627+
------------------
1628+
"a\\b"
1629+
"^a\\b$"
1630+
(2 rows)
1631+
1632+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "")');
1633+
jsonb_path_query
1634+
------------------
1635+
"a\b"
1636+
(1 row)
1637+
1638+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "q")');
1639+
jsonb_path_query
1640+
------------------
1641+
"^a\\b$"
1642+
(1 row)
1643+
1644+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "q")');
1645+
jsonb_path_query
1646+
------------------
1647+
(0 rows)
1648+
1649+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "iq")');
1650+
jsonb_path_query
1651+
------------------
1652+
"^a\\b$"
1653+
(1 row)
1654+
1655+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "")');
1656+
jsonb_path_query
1657+
------------------
1658+
"a\b"
1659+
(1 row)
1660+
16251661
-- jsonpath operators
16261662
SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*]');
16271663
jsonb_path_query

src/test/regress/expected/jsonpath.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,24 @@ select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath;
453453
$?(@ like_regex "pattern" flag "sx")
454454
(1 row)
455455

456+
select '$ ? (@ like_regex "pattern" flag "q")'::jsonpath;
457+
jsonpath
458+
-------------------------------------
459+
$?(@ like_regex "pattern" flag "q")
460+
(1 row)
461+
462+
select '$ ? (@ like_regex "pattern" flag "iq")'::jsonpath;
463+
jsonpath
464+
--------------------------------------
465+
$?(@ like_regex "pattern" flag "iq")
466+
(1 row)
467+
468+
select '$ ? (@ like_regex "pattern" flag "smixq")'::jsonpath;
469+
jsonpath
470+
----------------------------------------
471+
$?(@ like_regex "pattern" flag "imxq")
472+
(1 row)
473+
456474
select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath;
457475
ERROR: invalid input syntax for type jsonpath
458476
LINE 1: select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath;

src/test/regress/sql/jsonb_jsonpath.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,12 @@ select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "adc\nabc", "
339339
select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "adc\nabc", "babc"]', 'lax $[*] ? (@ like_regex "^a b.* c " flag "ix")');
340340
select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "adc\nabc", "babc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "m")');
341341
select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "adc\nabc", "babc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "s")');
342+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "q")');
343+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "")');
344+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "q")');
345+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "q")');
346+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "iq")');
347+
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "")');
342348

343349
-- jsonpath operators
344350

src/test/regress/sql/jsonpath.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ select '$ ? (@ like_regex "pattern" flag "i")'::jsonpath;
8383
select '$ ? (@ like_regex "pattern" flag "is")'::jsonpath;
8484
select '$ ? (@ like_regex "pattern" flag "isim")'::jsonpath;
8585
select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath;
86+
select '$ ? (@ like_regex "pattern" flag "q")'::jsonpath;
87+
select '$ ? (@ like_regex "pattern" flag "iq")'::jsonpath;
88+
select '$ ? (@ like_regex "pattern" flag "smixq")'::jsonpath;
8689
select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath;
8790
8891
select '$ < 1'::jsonpath;

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