#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"
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 */
*tcategory = JSONTYPE_NUMERIC;
break;
+ case DATEOID:
+ *tcategory = JSONTYPE_DATE;
+ break;
+
case TIMESTAMPOID:
*tcategory = JSONTYPE_TIMESTAMP;
break;
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)
{
}
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;
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
- appendStringInfo(result,"\"%s\"",buf);
+ appendStringInfo(result, "\"%s\"", buf);
}
break;
case JSONTYPE_TIMESTAMPTZ:
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
- appendStringInfo(result,"\"%s\"",buf);
+ appendStringInfo(result, "\"%s\"", buf);
}
break;
case JSONTYPE_JSON:
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]) &&