@ -28,6 +28,14 @@
# include "utils/syscache.h"
# include "utils/typcache.h"
/*
* String to output for infinite dates and timestamps .
* Note the we don ' t use embedded quotes , unlike for json , because
* we store jsonb strings dequoted .
*/
# define DT_INFINITY "infinity"
typedef struct JsonbInState
{
JsonbParseState * parseState ;
@ -714,23 +722,21 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
char buf [ MAXDATELEN + 1 ] ;
date = DatumGetDateADT ( val ) ;
jb . type = jbvString ;
/* 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. " ) ) ) ;
{
jb . val . string . len = strlen ( DT_INFINITY ) ;
jb . val . string . val = pstrdup ( DT_INFINITY ) ;
}
else
{
j2date ( date + POSTGRES_EPOCH_JDATE ,
& ( tm . tm_year ) , & ( tm . tm_mon ) , & ( tm . tm_mday ) ) ;
EncodeDateOnly ( & tm , USE_XSD_DATES , buf ) ;
jb . val . string . len = strlen ( buf ) ;
jb . val . string . val = pstrdup ( buf ) ;
}
jb . type = jbvString ;
jb . val . string . len = strlen ( buf ) ;
jb . val . string . val = pstrdup ( buf ) ;
}
break ;
case JSONBTYPE_TIMESTAMP :
@ -741,23 +747,24 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
char buf [ MAXDATELEN + 1 ] ;
timestamp = DatumGetTimestamp ( val ) ;
jb . type = jbvString ;
/* XSD doesn't support infinite values */
if ( TIMESTAMP_NOT_FINITE ( timestamp ) )
ereport ( ERROR ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
errmsg ( " timestamp out of range " ) ,
errdetail ( " JSON does not support infinite timestamp values. " ) ) ) ;
{
jb . val . string . len = strlen ( DT_INFINITY ) ;
jb . val . string . val = pstrdup ( DT_INFINITY ) ;
}
else if ( timestamp2tm ( timestamp , NULL , & tm , & fsec , NULL , NULL ) = = 0 )
{
EncodeDateTime ( & tm , fsec , false , 0 , NULL , USE_XSD_DATES , buf ) ;
jb . val . string . len = strlen ( buf ) ;
jb . val . string . val = pstrdup ( buf ) ;
}
else
ereport ( ERROR ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
errmsg ( " timestamp out of range " ) ) ) ;
jb . type = jbvString ;
jb . val . string . len = strlen ( buf ) ;
jb . val . string . val = pstrdup ( buf ) ;
}
break ;
case JSONBTYPE_TIMESTAMPTZ :
@ -770,23 +777,23 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
char buf [ MAXDATELEN + 1 ] ;
timestamp = DatumGetTimestamp ( val ) ;
jb . type = jbvString ;
/* XSD doesn't support infinite values */
if ( TIMESTAMP_NOT_FINITE ( timestamp ) )
ereport ( ERROR ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
errmsg ( " timestamp out of range " ) ,
errdetail ( " JSON does not support infinite timestamp values. " ) ) ) ;
{
jb . val . string . len = strlen ( DT_INFINITY ) ;
jb . val . string . val = pstrdup ( DT_INFINITY ) ;
}
else if ( timestamp2tm ( timestamp , & tz , & tm , & fsec , & tzn , NULL ) = = 0 )
{
EncodeDateTime ( & tm , fsec , true , tz , tzn , USE_XSD_DATES , buf ) ;
jb . val . string . len = strlen ( buf ) ;
jb . val . string . val = pstrdup ( buf ) ;
}
else
ereport ( ERROR ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
errmsg ( " timestamp out of range " ) ) ) ;
jb . type = jbvString ;
jb . val . string . len = strlen ( buf ) ;
jb . val . string . val = pstrdup ( buf ) ;
}
break ;
case JSONBTYPE_JSONCAST :