Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+2
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

+11
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

+8
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

+1
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

+36
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

+18
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

+6
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

+3
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)