Commit 261a5c19 authored by Alexander Korotkov's avatar Alexander Korotkov

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
parent d8594d12
......@@ -563,6 +563,8 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey,
appendStringInfoChar(buf, 'm');
if (v->content.like_regex.flags & JSP_REGEX_WSPACE)
appendStringInfoChar(buf, 'x');
if (v->content.like_regex.flags & JSP_REGEX_QUOTE)
appendStringInfoChar(buf, 'q');
appendStringInfoChar(buf, '"');
}
......
......@@ -1664,6 +1664,17 @@ executeLikeRegex(JsonPathItem *jsp, JsonbValue *str, JsonbValue *rarg,
cxt->cflags &= ~REG_NEWLINE;
if (flags & JSP_REGEX_WSPACE)
cxt->cflags |= REG_EXPANDED;
/*
* 'q' flag can work together only with 'i'. When other is specified,
* then 'q' has no effect.
*/
if ((flags & JSP_REGEX_QUOTE) &&
!(flags & (JSP_REGEX_MLINE | JSP_REGEX_SLINE | JSP_REGEX_WSPACE)))
{
cxt->cflags &= ~REG_ADVANCED;
cxt->cflags |= REG_QUOTE;
}
}
if (RE_compile_and_execute(cxt->regex, str->val.string.val,
......
......@@ -510,6 +510,14 @@ makeItemLikeRegex(JsonPathParseItem *expr, JsonPathString *pattern,
v->value.like_regex.flags |= JSP_REGEX_WSPACE;
cflags |= REG_EXPANDED;
break;
case 'q':
v->value.like_regex.flags |= JSP_REGEX_QUOTE;
if (!(v->value.like_regex.flags & (JSP_REGEX_MLINE | JSP_REGEX_SLINE | JSP_REGEX_WSPACE)))
{
cflags &= ~REG_ADVANCED;
cflags |= REG_QUOTE;
}
break;
default:
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
......
......@@ -91,6 +91,7 @@ typedef enum JsonPathItemType
#define JSP_REGEX_SLINE 0x02 /* s flag, single-line mode */
#define JSP_REGEX_MLINE 0x04 /* m flag, multi-line mode */
#define JSP_REGEX_WSPACE 0x08 /* x flag, expanded syntax */
#define JSP_REGEX_QUOTE 0x10 /* q flag, no special characters */
/*
* Support functions to parse/construct binary value.
......
......@@ -1622,6 +1622,42 @@ select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "adc\nabc", "
"abdacb"
(2 rows)
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "q")');
jsonb_path_query
------------------
"a\\b"
"^a\\b$"
(2 rows)
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "")');
jsonb_path_query
------------------
"a\b"
(1 row)
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "q")');
jsonb_path_query
------------------
"^a\\b$"
(1 row)
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "q")');
jsonb_path_query
------------------
(0 rows)
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "iq")');
jsonb_path_query
------------------
"^a\\b$"
(1 row)
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "")');
jsonb_path_query
------------------
"a\b"
(1 row)
-- jsonpath operators
SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*]');
jsonb_path_query
......
......@@ -453,6 +453,24 @@ select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath;
$?(@ like_regex "pattern" flag "sx")
(1 row)
select '$ ? (@ like_regex "pattern" flag "q")'::jsonpath;
jsonpath
-------------------------------------
$?(@ like_regex "pattern" flag "q")
(1 row)
select '$ ? (@ like_regex "pattern" flag "iq")'::jsonpath;
jsonpath
--------------------------------------
$?(@ like_regex "pattern" flag "iq")
(1 row)
select '$ ? (@ like_regex "pattern" flag "smixq")'::jsonpath;
jsonpath
----------------------------------------
$?(@ like_regex "pattern" flag "imxq")
(1 row)
select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath;
ERROR: invalid input syntax for type jsonpath
LINE 1: select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath;
......
......@@ -339,6 +339,12 @@ select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "adc\nabc", "
select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "adc\nabc", "babc"]', 'lax $[*] ? (@ like_regex "^a b.* c " flag "ix")');
select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "adc\nabc", "babc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "m")');
select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "adc\nabc", "babc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "s")');
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "q")');
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "")');
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "q")');
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "q")');
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "iq")');
select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "")');
-- jsonpath operators
......
......@@ -83,6 +83,9 @@ select '$ ? (@ like_regex "pattern" flag "i")'::jsonpath;
select '$ ? (@ like_regex "pattern" flag "is")'::jsonpath;
select '$ ? (@ like_regex "pattern" flag "isim")'::jsonpath;
select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath;
select '$ ? (@ like_regex "pattern" flag "q")'::jsonpath;
select '$ ? (@ like_regex "pattern" flag "iq")'::jsonpath;
select '$ ? (@ like_regex "pattern" flag "smixq")'::jsonpath;
select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath;
select '$ < 1'::jsonpath;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment