aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/json.c
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2015-02-26 12:25:21 -0500
committerAndrew Dunstan <andrew@dunslane.net>2015-02-26 12:25:21 -0500
commitbda76c1c8cfb1d11751ba6be88f0242850481733 (patch)
treede3272dade43151c7f9668e18cb8111f2da70bb6 /src/backend/utils/adt/json.c
parentfd6a3f3ad4067f1b8fc28e9de6e99e5936d82161 (diff)
downloadpostgresql-bda76c1c8cfb1d11751ba6be88f0242850481733.tar.gz
postgresql-bda76c1c8cfb1d11751ba6be88f0242850481733.zip
Render infinite date/timestamps as 'infinity' for json/jsonb
Commit ab14a73a6c raised an error in these cases and later the behaviour was copied to jsonb. This is what the XML code, which we then adopted, does, as the XSD types don't accept infinite values. However, json dates and timestamps are just strings as far as json is concerned, so there is no reason not to render these values as 'infinity'. The json portion of this is backpatched to 9.4 where the behaviour was introduced. The jsonb portion only affects the development branch. Per gripe on pgsql-general.
Diffstat (limited to 'src/backend/utils/adt/json.c')
-rw-r--r--src/backend/utils/adt/json.c43
1 files changed, 22 insertions, 21 deletions
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 951b6554007..d0d7206ae93 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -32,6 +32,9 @@
#include "utils/typcache.h"
#include "utils/syscache.h"
+/* String to output for infinite dates and timestamps */
+#define DT_INFINITY "\"infinity\""
+
/*
* The context of the parser is maintained by the recursive descent
* mechanism, but is passed explicitly to the error reporting routine
@@ -1436,20 +1439,18 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
date = DatumGetDateADT(val);
- /* XSD doesn't support infinite values */
if (DATE_NOT_FINITE(date))
- ereport(ERROR,
- (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("date out of range"),
- errdetail("JSON does not support infinite date values.")));
+ {
+ /* we have to format infinity ourselves */
+ appendStringInfoString(result,DT_INFINITY);
+ }
else
{
j2date(date + POSTGRES_EPOCH_JDATE,
&(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
EncodeDateOnly(&tm, USE_XSD_DATES, buf);
+ appendStringInfo(result, "\"%s\"", buf);
}
-
- appendStringInfo(result, "\"%s\"", buf);
}
break;
case JSONTYPE_TIMESTAMP:
@@ -1461,20 +1462,20 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
timestamp = DatumGetTimestamp(val);
- /* XSD doesn't support infinite values */
if (TIMESTAMP_NOT_FINITE(timestamp))
- ereport(ERROR,
- (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("timestamp out of range"),
- errdetail("JSON does not support infinite timestamp values.")));
+ {
+ /* we have to format infinity ourselves */
+ appendStringInfoString(result,DT_INFINITY);
+ }
else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
+ {
EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
+ appendStringInfo(result, "\"%s\"", buf);
+ }
else
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
-
- appendStringInfo(result, "\"%s\"", buf);
}
break;
case JSONTYPE_TIMESTAMPTZ:
@@ -1488,20 +1489,20 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
timestamp = DatumGetTimestamp(val);
- /* XSD doesn't support infinite values */
if (TIMESTAMP_NOT_FINITE(timestamp))
- ereport(ERROR,
- (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("timestamp out of range"),
- errdetail("JSON does not support infinite timestamp values.")));
+ {
+ /* we have to format infinity ourselves */
+ appendStringInfoString(result,DT_INFINITY);
+ }
else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
+ {
EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
+ appendStringInfo(result, "\"%s\"", buf);
+ }
else
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
-
- appendStringInfo(result, "\"%s\"", buf);
}
break;
case JSONTYPE_JSON: