aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/formatting.c20
-rw-r--r--src/backend/utils/adt/jsonpath_exec.c8
-rw-r--r--src/test/regress/expected/jsonb_jsonpath.out19
-rw-r--r--src/test/regress/sql/jsonb_jsonpath.sql6
4 files changed, 49 insertions, 4 deletions
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index f9aa968f098..b91ff7bb803 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1381,10 +1381,12 @@ parse_format(FormatNode *node, const char *str, const KeyWord *kw,
{
int chlen;
- if (flags & STD_FLAG)
+ if ((flags & STD_FLAG) && *str != '"')
{
/*
- * Standard mode, allow only following separators: "-./,':; "
+ * Standard mode, allow only following separators: "-./,':; ".
+ * However, we support double quotes even in standard mode
+ * (see below). This is our extension of standard mode.
*/
if (strchr("-./,':; ", *str) == NULL)
ereport(ERROR,
@@ -3346,7 +3348,19 @@ DCH_from_char(FormatNode *node, const char *in, TmFromChar *out,
}
else
{
- s += pg_mblen(s);
+ int chlen = pg_mblen(s);
+
+ /*
+ * Standard mode requires strict match of format characters.
+ */
+ if (std && n->type == NODE_TYPE_CHAR &&
+ strncmp(s, n->character, chlen) != 0)
+ RETURN_ERROR(ereport(ERROR,
+ (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
+ errmsg("unmatched format character \"%s\"",
+ n->character))));
+
+ s += chlen;
}
continue;
}
diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c
index 31b88d67416..28be845770a 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -1833,6 +1833,9 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
/*
* According to SQL/JSON standard enumerate ISO formats for: date,
* timetz, time, timestamptz, timestamp.
+ *
+ * We also support ISO 8601 for timestamps, because to_json[b]()
+ * functions use this format.
*/
static const char *fmt_str[] =
{
@@ -1842,7 +1845,10 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
"HH24:MI:SS",
"yyyy-mm-dd HH24:MI:SSTZH:TZM",
"yyyy-mm-dd HH24:MI:SSTZH",
- "yyyy-mm-dd HH24:MI:SS"
+ "yyyy-mm-dd HH24:MI:SS",
+ "yyyy-mm-dd\"T\"HH24:MI:SSTZH:TZM",
+ "yyyy-mm-dd\"T\"HH24:MI:SSTZH",
+ "yyyy-mm-dd\"T\"HH24:MI:SS"
};
/* cache for format texts */
diff --git a/src/test/regress/expected/jsonb_jsonpath.out b/src/test/regress/expected/jsonb_jsonpath.out
index 31d6f05a7c2..508ddd797ed 100644
--- a/src/test/regress/expected/jsonb_jsonpath.out
+++ b/src/test/regress/expected/jsonb_jsonpath.out
@@ -1722,6 +1722,16 @@ select jsonb_path_query('"12:34:56 +05:20"', '$.datetime("HH24:MI:SS TZH:TZM").t
"time with time zone"
(1 row)
+select jsonb_path_query('"10-03-2017T12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")');
+ jsonb_path_query
+-----------------------
+ "2017-03-10T12:34:56"
+(1 row)
+
+select jsonb_path_query('"10-03-2017t12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")');
+ERROR: unmatched format character "T"
+select jsonb_path_query('"10-03-2017 12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")');
+ERROR: unmatched format character "T"
set time zone '+00';
select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")');
jsonb_path_query
@@ -1901,6 +1911,15 @@ select jsonb_path_query('"2017-03-10 12:34:56+3:10"', '$.datetime()');
"2017-03-10T12:34:56+03:10"
(1 row)
+select jsonb_path_query('"2017-03-10T12:34:56+3:10"', '$.datetime()');
+ jsonb_path_query
+-----------------------------
+ "2017-03-10T12:34:56+03:10"
+(1 row)
+
+select jsonb_path_query('"2017-03-10t12:34:56+3:10"', '$.datetime()');
+ERROR: datetime format is not recognized: "2017-03-10t12:34:56+3:10"
+HINT: Use a datetime template argument to specify the input data format.
select jsonb_path_query('"12:34:56"', '$.datetime().type()');
jsonb_path_query
--------------------------
diff --git a/src/test/regress/sql/jsonb_jsonpath.sql b/src/test/regress/sql/jsonb_jsonpath.sql
index dc25ceb283d..60f73cb0590 100644
--- a/src/test/regress/sql/jsonb_jsonpath.sql
+++ b/src/test/regress/sql/jsonb_jsonpath.sql
@@ -368,6 +368,10 @@ select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH2
select jsonb_path_query('"12:34:56"', '$.datetime("HH24:MI:SS").type()');
select jsonb_path_query('"12:34:56 +05:20"', '$.datetime("HH24:MI:SS TZH:TZM").type()');
+select jsonb_path_query('"10-03-2017T12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")');
+select jsonb_path_query('"10-03-2017t12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")');
+select jsonb_path_query('"10-03-2017 12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")');
+
set time zone '+00';
select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")');
@@ -408,6 +412,8 @@ select jsonb_path_query('"2017-03-10 12:34:56+3"', '$.datetime().type()');
select jsonb_path_query('"2017-03-10 12:34:56+3"', '$.datetime()');
select jsonb_path_query('"2017-03-10 12:34:56+3:10"', '$.datetime().type()');
select jsonb_path_query('"2017-03-10 12:34:56+3:10"', '$.datetime()');
+select jsonb_path_query('"2017-03-10T12:34:56+3:10"', '$.datetime()');
+select jsonb_path_query('"2017-03-10t12:34:56+3:10"', '$.datetime()');
select jsonb_path_query('"12:34:56"', '$.datetime().type()');
select jsonb_path_query('"12:34:56"', '$.datetime()');
select jsonb_path_query('"12:34:56+3"', '$.datetime().type()');