Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 798c950

Browse files
author
Nikita Glukhov
committed
Add jsonpath datetime() extension: UNIX epoch time to timestamptz
1 parent 98a3b62 commit 798c950

File tree

3 files changed

+98
-45
lines changed

3 files changed

+98
-45
lines changed

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 74 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,47 +1839,28 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
18391839
{
18401840
JsonbValue jbvbuf;
18411841
Datum value;
1842-
text *datetime_txt;
18431842
Oid typid;
18441843
int32 typmod = -1;
18451844
bool hasNext;
18461845

18471846
if (JsonbType(jb) == jbvScalar)
18481847
jb = JsonbExtractScalar(jb->val.binary.data, &jbvbuf);
18491848

1850-
if (jb->type != jbvString)
1849+
if (jb->type == jbvNumeric && !jsp->content.arg)
18511850
{
1852-
res = jperMakeError(ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION);
1853-
break;
1854-
}
1855-
1856-
datetime_txt = cstring_to_text_with_len(jb->val.string.val,
1857-
jb->val.string.len);
1858-
1859-
res = jperOk;
1860-
1861-
if (jsp->content.arg)
1862-
{
1863-
text *template_txt;
1864-
char *template_str;
1865-
int template_len;
1851+
/* Standard extension: unix epoch to timestamptz */
18661852
MemoryContext mcxt = CurrentMemoryContext;
18671853

1868-
jspGetArg(jsp, &elem);
1869-
1870-
if (elem.type != jpiString)
1871-
elog(ERROR, "invalid jsonpath item type for .datetime() argument");
1872-
1873-
template_str = jspGetString(&elem, &template_len);
1874-
template_txt = cstring_to_text_with_len(template_str,
1875-
template_len);
1876-
18771854
PG_TRY();
18781855
{
1879-
value = to_datetime(datetime_txt,
1880-
template_str, template_len,
1881-
false,
1882-
&typid, &typmod);
1856+
Datum unix_epoch =
1857+
DirectFunctionCall1(numeric_float8,
1858+
NumericGetDatum(jb->val.numeric));
1859+
1860+
value = DirectFunctionCall1(float8_timestamptz,
1861+
unix_epoch);
1862+
typid = TIMESTAMPTZOID;
1863+
res = jperOk;
18831864
}
18841865
PG_CATCH();
18851866
{
@@ -1893,29 +1874,80 @@ recursiveExecuteNoUnwrap(JsonPathExecContext *cxt, JsonPathItem *jsp,
18931874
res = jperMakeError(ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION);
18941875
}
18951876
PG_END_TRY();
1896-
1897-
pfree(template_txt);
18981877
}
1899-
else
1878+
else if (jb->type == jbvString)
19001879
{
1901-
if (!tryToParseDatetime("yyyy-mm-dd HH24:MI:SS TZH:TZM",
1880+
1881+
text *datetime_txt =
1882+
cstring_to_text_with_len(jb->val.string.val,
1883+
jb->val.string.len);
1884+
1885+
res = jperOk;
1886+
1887+
if (jsp->content.arg)
1888+
{
1889+
text *template_txt;
1890+
char *template_str;
1891+
int template_len;
1892+
MemoryContext mcxt = CurrentMemoryContext;
1893+
1894+
jspGetArg(jsp, &elem);
1895+
1896+
if (elem.type != jpiString)
1897+
elog(ERROR, "invalid jsonpath item type for .datetime() argument");
1898+
1899+
template_str = jspGetString(&elem, &template_len);
1900+
template_txt = cstring_to_text_with_len(template_str,
1901+
template_len);
1902+
1903+
PG_TRY();
1904+
{
1905+
value = to_datetime(datetime_txt,
1906+
template_str, template_len,
1907+
false,
1908+
&typid, &typmod);
1909+
}
1910+
PG_CATCH();
1911+
{
1912+
if (ERRCODE_TO_CATEGORY(geterrcode()) !=
1913+
ERRCODE_DATA_EXCEPTION)
1914+
PG_RE_THROW();
1915+
1916+
FlushErrorState();
1917+
MemoryContextSwitchTo(mcxt);
1918+
1919+
res = jperMakeError(ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION);
1920+
}
1921+
PG_END_TRY();
1922+
1923+
pfree(template_txt);
1924+
}
1925+
else
1926+
{
1927+
if (!tryToParseDatetime("yyyy-mm-dd HH24:MI:SS TZH:TZM",
19021928
datetime_txt, &value, &typid, &typmod) &&
1903-
!tryToParseDatetime("yyyy-mm-dd HH24:MI:SS TZH",
1929+
!tryToParseDatetime("yyyy-mm-dd HH24:MI:SS TZH",
19041930
datetime_txt, &value, &typid, &typmod) &&
1905-
!tryToParseDatetime("yyyy-mm-dd HH24:MI:SS",
1931+
!tryToParseDatetime("yyyy-mm-dd HH24:MI:SS",
19061932
datetime_txt, &value, &typid, &typmod) &&
1907-
!tryToParseDatetime("yyyy-mm-dd",
1933+
!tryToParseDatetime("yyyy-mm-dd",
19081934
datetime_txt, &value, &typid, &typmod) &&
1909-
!tryToParseDatetime("HH24:MI:SS TZH:TZM",
1935+
!tryToParseDatetime("HH24:MI:SS TZH:TZM",
19101936
datetime_txt, &value, &typid, &typmod) &&
1911-
!tryToParseDatetime("HH24:MI:SS TZH",
1937+
!tryToParseDatetime("HH24:MI:SS TZH",
19121938
datetime_txt, &value, &typid, &typmod) &&
1913-
!tryToParseDatetime("HH24:MI:SS",
1939+
!tryToParseDatetime("HH24:MI:SS",
19141940
datetime_txt, &value, &typid, &typmod))
1915-
res = jperMakeError(ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION);
1916-
}
1941+
res = jperMakeError(ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION);
1942+
}
19171943

1918-
pfree(datetime_txt);
1944+
pfree(datetime_txt);
1945+
}
1946+
else
1947+
{
1948+
res = jperMakeError(ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION);
1949+
break;
1950+
}
19191951

19201952
if (jperIsError(res))
19211953
break;

src/test/regress/expected/jsonb_jsonpath.out

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,8 +1138,6 @@ select jsonb 'null' @* '$.datetime()';
11381138
ERROR: Invalid argument for SQL/JSON datetime function
11391139
select jsonb 'true' @* '$.datetime()';
11401140
ERROR: Invalid argument for SQL/JSON datetime function
1141-
select jsonb '1' @* '$.datetime()';
1142-
ERROR: Invalid argument for SQL/JSON datetime function
11431141
select jsonb '[]' @* '$.datetime()';
11441142
?column?
11451143
----------
@@ -1151,6 +1149,25 @@ select jsonb '{}' @* '$.datetime()';
11511149
ERROR: Invalid argument for SQL/JSON datetime function
11521150
select jsonb '""' @* '$.datetime()';
11531151
ERROR: Invalid argument for SQL/JSON datetime function
1152+
-- Standard extension: UNIX epoch to timestamptz
1153+
select jsonb '0' @* '$.datetime()';
1154+
?column?
1155+
--------------------------------
1156+
"Wed Dec 31 16:00:00 1969 PST"
1157+
(1 row)
1158+
1159+
select jsonb '0' @* '$.datetime().type()';
1160+
?column?
1161+
----------------------------
1162+
"timestamp with time zone"
1163+
(1 row)
1164+
1165+
select jsonb '1490216035.5' @* '$.datetime()';
1166+
?column?
1167+
----------------------------------
1168+
"Wed Mar 22 13:53:55.5 2017 PDT"
1169+
(1 row)
1170+
11541171
select jsonb '"10-03-2017"' @* '$.datetime("dd-mm-yyyy")';
11551172
?column?
11561173
--------------

src/test/regress/sql/jsonb_jsonpath.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,16 @@ select jsonb '[null, 1, "abc", "abd", "aBdC", "abdacb", "babc"]' @* 'lax $[*] ?
232232

233233
select jsonb 'null' @* '$.datetime()';
234234
select jsonb 'true' @* '$.datetime()';
235-
select jsonb '1' @* '$.datetime()';
236235
select jsonb '[]' @* '$.datetime()';
237236
select jsonb '[]' @* 'strict $.datetime()';
238237
select jsonb '{}' @* '$.datetime()';
239238
select jsonb '""' @* '$.datetime()';
240239

240+
-- Standard extension: UNIX epoch to timestamptz
241+
select jsonb '0' @* '$.datetime()';
242+
select jsonb '0' @* '$.datetime().type()';
243+
select jsonb '1490216035.5' @* '$.datetime()';
244+
241245
select jsonb '"10-03-2017"' @* '$.datetime("dd-mm-yyyy")';
242246
select jsonb '"10-03-2017"' @* '$.datetime("dd-mm-yyyy").type()';
243247
select jsonb '"10-03-2017 12:34"' @* '$.datetime("dd-mm-yyyy")';

0 commit comments

Comments
 (0)