aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/json.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-08-17 22:57:15 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2014-08-17 22:57:46 -0400
commite56ec50c1622010c010e1c84bc02ce44285c4f41 (patch)
treeae99cf2479ddb8493f517013e6ee91f350bc81f2 /src/backend/utils/adt/json.c
parent3e9f70f1287b9324e398a084a8e881ea6aefc3eb (diff)
downloadpostgresql-e56ec50c1622010c010e1c84bc02ce44285c4f41.tar.gz
postgresql-e56ec50c1622010c010e1c84bc02ce44285c4f41.zip
Use ISO 8601 format for dates converted to JSON, too.
Commit f30015b6d794c15d52abbb3df3a65081fbefb1ed made this happen for timestamp and timestamptz, but it seems pretty inconsistent to not do it for simple dates as well. (In passing, I re-pgindent'd json.c.)
Diffstat (limited to 'src/backend/utils/adt/json.c')
-rw-r--r--src/backend/utils/adt/json.c55
1 files changed, 43 insertions, 12 deletions
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 68132aea4bf..494a0285267 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -25,6 +25,7 @@
#include "parser/parse_coerce.h"
#include "utils/array.h"
#include "utils/builtins.h"
+#include "utils/date.h"
#include "utils/datetime.h"
#include "utils/lsyscache.h"
#include "utils/json.h"
@@ -55,8 +56,9 @@ typedef enum /* type categories for datum_to_json */
JSONTYPE_NULL, /* null, so we didn't bother to identify */
JSONTYPE_BOOL, /* boolean (built-in types only) */
JSONTYPE_NUMERIC, /* numeric (ditto) */
- JSONTYPE_TIMESTAMP, /* we use special formatting for timestamp */
- JSONTYPE_TIMESTAMPTZ, /* ... and timestamptz */
+ JSONTYPE_DATE, /* we use special formatting for datetimes */
+ JSONTYPE_TIMESTAMP,
+ JSONTYPE_TIMESTAMPTZ,
JSONTYPE_JSON, /* JSON itself (and JSONB) */
JSONTYPE_ARRAY, /* array */
JSONTYPE_COMPOSITE, /* composite */
@@ -1267,6 +1269,10 @@ json_categorize_type(Oid typoid,
*tcategory = JSONTYPE_NUMERIC;
break;
+ case DATEOID:
+ *tcategory = JSONTYPE_DATE;
+ break;
+
case TIMESTAMPOID:
*tcategory = JSONTYPE_TIMESTAMP;
break;
@@ -1348,7 +1354,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
tcategory == JSONTYPE_CAST))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("key value must be scalar, not array, composite, or json")));
+ errmsg("key value must be scalar, not array, composite, or json")));
switch (tcategory)
{
@@ -1388,6 +1394,30 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
}
pfree(outputstr);
break;
+ case JSONTYPE_DATE:
+ {
+ DateADT date;
+ struct pg_tm tm;
+ char buf[MAXDATELEN + 1];
+
+ 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.")));
+ 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);
+ }
+ break;
case JSONTYPE_TIMESTAMP:
{
Timestamp timestamp;
@@ -1410,7 +1440,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
- appendStringInfo(result,"\"%s\"",buf);
+ appendStringInfo(result, "\"%s\"", buf);
}
break;
case JSONTYPE_TIMESTAMPTZ:
@@ -1437,7 +1467,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
- appendStringInfo(result,"\"%s\"",buf);
+ appendStringInfo(result, "\"%s\"", buf);
}
break;
case JSONTYPE_JSON:
@@ -2305,20 +2335,21 @@ escape_json(StringInfo buf, const char *str)
appendStringInfoString(buf, "\\\"");
break;
case '\\':
+
/*
* Unicode escapes are passed through as is. There is no
* requirement that they denote a valid character in the
* server encoding - indeed that is a big part of their
* usefulness.
*
- * All we require is that they consist of \uXXXX where
- * the Xs are hexadecimal digits. It is the responsibility
- * of the caller of, say, to_json() to make sure that the
- * unicode escape is valid.
+ * All we require is that they consist of \uXXXX where the Xs
+ * are hexadecimal digits. It is the responsibility of the
+ * caller of, say, to_json() to make sure that the unicode
+ * escape is valid.
*
- * In the case of a jsonb string value being escaped, the
- * only unicode escape that should be present is \u0000,
- * all the other unicode escapes will have been resolved.
+ * In the case of a jsonb string value being escaped, the only
+ * unicode escape that should be present is \u0000, all the
+ * other unicode escapes will have been resolved.
*/
if (p[1] == 'u' &&
isxdigit((unsigned char) p[2]) &&