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{
3341 JsonbParseState * parseState ;
@@ -714,23 +722,21 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
714722 char buf [MAXDATELEN + 1 ];
715723
716724 date = DatumGetDateADT (val );
725+ jb .type = jbvString ;
717726
718- /* XSD doesn't support infinite values */
719727 if (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+ }
724732 else
725733 {
726734 j2date (date + POSTGRES_EPOCH_JDATE ,
727735 & (tm .tm_year ), & (tm .tm_mon ), & (tm .tm_mday ));
728736 EncodeDateOnly (& 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 }
735741 break ;
736742 case JSONBTYPE_TIMESTAMP :
@@ -741,23 +747,24 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
741747 char buf [MAXDATELEN + 1 ];
742748
743749 timestamp = DatumGetTimestamp (val );
750+ jb .type = jbvString ;
744751
745- /* XSD doesn't support infinite values */
746752 if (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+ }
751757 else if (timestamp2tm (timestamp , NULL , & tm , & fsec , NULL , NULL ) == 0 )
758+ {
759+
752760 EncodeDateTime (& tm , fsec , false, 0 , NULL , USE_XSD_DATES , buf );
761+ jb .val .string .len = strlen (buf );
762+ jb .val .string .val = pstrdup (buf );
763+ }
753764 else
754765 ereport (ERROR ,
755766 (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
756767 errmsg ("timestamp out of range" )));
757-
758- jb .type = jbvString ;
759- jb .val .string .len = strlen (buf );
760- jb .val .string .val = pstrdup (buf );
761768 }
762769 break ;
763770 case JSONBTYPE_TIMESTAMPTZ :
@@ -770,23 +777,23 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
770777 char buf [MAXDATELEN + 1 ];
771778
772779 timestamp = DatumGetTimestamp (val );
780+ jb .type = jbvString ;
773781
774- /* XSD doesn't support infinite values */
775782 if (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+ }
780787 else if (timestamp2tm (timestamp , & tz , & tm , & fsec , & tzn , NULL ) == 0 )
788+ {
781789 EncodeDateTime (& tm , fsec , true, tz , tzn , USE_XSD_DATES , buf );
790+ jb .val .string .len = strlen (buf );
791+ jb .val .string .val = pstrdup (buf );
792+ }
782793 else
783794 ereport (ERROR ,
784795 (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
785796 errmsg ("timestamp out of range" )));
786-
787- jb .type = jbvString ;
788- jb .val .string .len = strlen (buf );
789- jb .val .string .val = pstrdup (buf );
790797 }
791798 break ;
792799 case JSONBTYPE_JSONCAST :
0 commit comments