2828#include "utils/syscache.h"
2929#include "utils/typcache.h"
3030
31+ /*
32+ * String to output for infinite dates and timestamps.
33+ * Note the we don't use embedded quotes, unlike for json, because
34+ * we store jsonb strings dequoted.
35+ */
36+
37+ #define DT_INFINITY "infinity"
38+
3139typedef struct JsonbInState
3240{
3341JsonbParseState * parseState ;
@@ -714,23 +722,21 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
714722char buf [MAXDATELEN + 1 ];
715723
716724date = DatumGetDateADT (val );
725+ jb .type = jbvString ;
717726
718- /* XSD doesn't support infinite values */
719727if (DATE_NOT_FINITE (date ))
720- ereport ( ERROR ,
721- ( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
722- errmsg ( "date out of range" ),
723- errdetail ( "JSON does not support infinite date values." )));
728+ {
729+ jb . val . string . len = strlen ( DT_INFINITY );
730+ jb . val . string . val = pstrdup ( DT_INFINITY );
731+ }
724732else
725733{
726734j2date (date + POSTGRES_EPOCH_JDATE ,
727735& (tm .tm_year ),& (tm .tm_mon ),& (tm .tm_mday ));
728736EncodeDateOnly (& tm ,USE_XSD_DATES ,buf );
737+ jb .val .string .len = strlen (buf );
738+ jb .val .string .val = pstrdup (buf );
729739}
730-
731- jb .type = jbvString ;
732- jb .val .string .len = strlen (buf );
733- jb .val .string .val = pstrdup (buf );
734740}
735741break ;
736742case JSONBTYPE_TIMESTAMP :
@@ -741,23 +747,24 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
741747char buf [MAXDATELEN + 1 ];
742748
743749timestamp = DatumGetTimestamp (val );
750+ jb .type = jbvString ;
744751
745- /* XSD doesn't support infinite values */
746752if (TIMESTAMP_NOT_FINITE (timestamp ))
747- ereport ( ERROR ,
748- ( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
749- errmsg ( "timestamp out of range" ),
750- errdetail ( "JSON does not support infinite timestamp values." )));
753+ {
754+ jb . val . string . len = strlen ( DT_INFINITY );
755+ jb . val . string . val = pstrdup ( DT_INFINITY );
756+ }
751757else if (timestamp2tm (timestamp ,NULL ,& tm ,& fsec ,NULL ,NULL )== 0 )
758+ {
759+
752760EncodeDateTime (& tm ,fsec , false,0 ,NULL ,USE_XSD_DATES ,buf );
761+ jb .val .string .len = strlen (buf );
762+ jb .val .string .val = pstrdup (buf );
763+ }
753764else
754765ereport (ERROR ,
755766(errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
756767errmsg ("timestamp out of range" )));
757-
758- jb .type = jbvString ;
759- jb .val .string .len = strlen (buf );
760- jb .val .string .val = pstrdup (buf );
761768}
762769break ;
763770case JSONBTYPE_TIMESTAMPTZ :
@@ -770,23 +777,23 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
770777char buf [MAXDATELEN + 1 ];
771778
772779timestamp = DatumGetTimestamp (val );
780+ jb .type = jbvString ;
773781
774- /* XSD doesn't support infinite values */
775782if (TIMESTAMP_NOT_FINITE (timestamp ))
776- ereport ( ERROR ,
777- ( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
778- errmsg ( "timestamp out of range" ),
779- errdetail ( "JSON does not support infinite timestamp values." )));
783+ {
784+ jb . val . string . len = strlen ( DT_INFINITY );
785+ jb . val . string . val = pstrdup ( DT_INFINITY );
786+ }
780787else if (timestamp2tm (timestamp ,& tz ,& tm ,& fsec ,& tzn ,NULL )== 0 )
788+ {
781789EncodeDateTime (& tm ,fsec , true,tz ,tzn ,USE_XSD_DATES ,buf );
790+ jb .val .string .len = strlen (buf );
791+ jb .val .string .val = pstrdup (buf );
792+ }
782793else
783794ereport (ERROR ,
784795(errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
785796errmsg ("timestamp out of range" )));
786-
787- jb .type = jbvString ;
788- jb .val .string .len = strlen (buf );
789- jb .val .string .val = pstrdup (buf );
790797}
791798break ;
792799case JSONBTYPE_JSONCAST :