25
25
#include "parser/parse_coerce.h"
26
26
#include "utils/array.h"
27
27
#include "utils/builtins.h"
28
+ #include "utils/date.h"
28
29
#include "utils/datetime.h"
29
30
#include "utils/lsyscache.h"
30
31
#include "utils/json.h"
@@ -55,8 +56,9 @@ typedef enum /* type categories for datum_to_json */
55
56
JSONTYPE_NULL , /* null, so we didn't bother to identify */
56
57
JSONTYPE_BOOL , /* boolean (built-in types only) */
57
58
JSONTYPE_NUMERIC , /* numeric (ditto) */
58
- JSONTYPE_TIMESTAMP , /* we use special formatting for timestamp */
59
- JSONTYPE_TIMESTAMPTZ , /* ... and timestamptz */
59
+ JSONTYPE_DATE , /* we use special formatting for datetimes */
60
+ JSONTYPE_TIMESTAMP ,
61
+ JSONTYPE_TIMESTAMPTZ ,
60
62
JSONTYPE_JSON , /* JSON itself (and JSONB) */
61
63
JSONTYPE_ARRAY , /* array */
62
64
JSONTYPE_COMPOSITE , /* composite */
@@ -1267,6 +1269,10 @@ json_categorize_type(Oid typoid,
1267
1269
* tcategory = JSONTYPE_NUMERIC ;
1268
1270
break ;
1269
1271
1272
+ case DATEOID :
1273
+ * tcategory = JSONTYPE_DATE ;
1274
+ break ;
1275
+
1270
1276
case TIMESTAMPOID :
1271
1277
* tcategory = JSONTYPE_TIMESTAMP ;
1272
1278
break ;
@@ -1348,7 +1354,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
1348
1354
tcategory == JSONTYPE_CAST ))
1349
1355
ereport (ERROR ,
1350
1356
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1351
- errmsg ("key value must be scalar, not array, composite, or json" )));
1357
+ errmsg ("key value must be scalar, not array, composite, or json" )));
1352
1358
1353
1359
switch (tcategory )
1354
1360
{
@@ -1388,6 +1394,30 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
1388
1394
}
1389
1395
pfree (outputstr );
1390
1396
break ;
1397
+ case JSONTYPE_DATE :
1398
+ {
1399
+ DateADT date ;
1400
+ struct pg_tm tm ;
1401
+ char buf [MAXDATELEN + 1 ];
1402
+
1403
+ date = DatumGetDateADT (val );
1404
+
1405
+ /* XSD doesn't support infinite values */
1406
+ if (DATE_NOT_FINITE (date ))
1407
+ ereport (ERROR ,
1408
+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
1409
+ errmsg ("date out of range" ),
1410
+ errdetail ("JSON does not support infinite date values." )));
1411
+ else
1412
+ {
1413
+ j2date (date + POSTGRES_EPOCH_JDATE ,
1414
+ & (tm .tm_year ), & (tm .tm_mon ), & (tm .tm_mday ));
1415
+ EncodeDateOnly (& tm , USE_XSD_DATES , buf );
1416
+ }
1417
+
1418
+ appendStringInfo (result , "\"%s\"" , buf );
1419
+ }
1420
+ break ;
1391
1421
case JSONTYPE_TIMESTAMP :
1392
1422
{
1393
1423
Timestamp timestamp ;
@@ -1410,7 +1440,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
1410
1440
(errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
1411
1441
errmsg ("timestamp out of range" )));
1412
1442
1413
- appendStringInfo (result ,"\"%s\"" ,buf );
1443
+ appendStringInfo (result , "\"%s\"" , buf );
1414
1444
}
1415
1445
break ;
1416
1446
case JSONTYPE_TIMESTAMPTZ :
@@ -1437,7 +1467,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
1437
1467
(errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
1438
1468
errmsg ("timestamp out of range" )));
1439
1469
1440
- appendStringInfo (result ,"\"%s\"" ,buf );
1470
+ appendStringInfo (result , "\"%s\"" , buf );
1441
1471
}
1442
1472
break ;
1443
1473
case JSONTYPE_JSON :
@@ -2305,20 +2335,21 @@ escape_json(StringInfo buf, const char *str)
2305
2335
appendStringInfoString (buf , "\\\"" );
2306
2336
break ;
2307
2337
case '\\' :
2338
+
2308
2339
/*
2309
2340
* Unicode escapes are passed through as is. There is no
2310
2341
* requirement that they denote a valid character in the
2311
2342
* server encoding - indeed that is a big part of their
2312
2343
* usefulness.
2313
2344
*
2314
- * All we require is that they consist of \uXXXX where
2315
- * the Xs are hexadecimal digits. It is the responsibility
2316
- * of the caller of, say, to_json() to make sure that the
2317
- * unicode escape is valid.
2345
+ * All we require is that they consist of \uXXXX where the Xs
2346
+ * are hexadecimal digits. It is the responsibility of the
2347
+ * caller of, say, to_json() to make sure that the unicode
2348
+ * escape is valid.
2318
2349
*
2319
- * In the case of a jsonb string value being escaped, the
2320
- * only unicode escape that should be present is \u0000,
2321
- * all the other unicode escapes will have been resolved.
2350
+ * In the case of a jsonb string value being escaped, the only
2351
+ * unicode escape that should be present is \u0000, all the
2352
+ * other unicode escapes will have been resolved.
2322
2353
*/
2323
2354
if (p [1 ] == 'u' &&
2324
2355
isxdigit ((unsigned char ) p [2 ]) &&
0 commit comments