32
32
#include "utils/typcache.h"
33
33
#include "utils/syscache.h"
34
34
35
- /* String to output for infinite dates and timestamps */
36
- #define DT_INFINITY "\"infinity\""
37
-
38
35
/*
39
36
* The context of the parser is maintained by the recursive descent
40
37
* mechanism, but is passed explicitly to the error reporting routine
@@ -70,11 +67,11 @@ typedef enum /* type categories for datum_to_json */
70
67
71
68
typedef struct JsonAggState
72
69
{
73
- StringInfo str ;
74
- JsonTypeCategory key_category ;
75
- Oid key_output_func ;
76
- JsonTypeCategory val_category ;
77
- Oid val_output_func ;
70
+ StringInfo str ;
71
+ JsonTypeCategory key_category ;
72
+ Oid key_output_func ;
73
+ JsonTypeCategory val_category ;
74
+ Oid val_output_func ;
78
75
} JsonAggState ;
79
76
80
77
static inline void json_lex (JsonLexContext * lex );
@@ -360,16 +357,16 @@ pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
360
357
int
361
358
json_count_array_elements (JsonLexContext * lex )
362
359
{
363
- JsonLexContext copylex ;
364
- int count ;
360
+ JsonLexContext copylex ;
361
+ int count ;
365
362
366
363
/*
367
364
* It's safe to do this with a shallow copy because the lexical routines
368
- * don't scribble on the input. They do scribble on the other pointers etc,
369
- * so doing this with a copy makes that safe.
365
+ * don't scribble on the input. They do scribble on the other pointers
366
+ * etc, so doing this with a copy makes that safe.
370
367
*/
371
368
memcpy (& copylex , lex , sizeof (JsonLexContext ));
372
- copylex .strval = NULL ; /* not interested in values here */
369
+ copylex .strval = NULL ; /* not interested in values here */
373
370
copylex .lex_level ++ ;
374
371
375
372
count = 0 ;
@@ -1492,19 +1489,16 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
1492
1489
char buf [MAXDATELEN + 1 ];
1493
1490
1494
1491
date = DatumGetDateADT (val );
1495
-
1492
+ /* Same as date_out(), but forcing DateStyle */
1496
1493
if (DATE_NOT_FINITE (date ))
1497
- {
1498
- /* we have to format infinity ourselves */
1499
- appendStringInfoString (result , DT_INFINITY );
1500
- }
1494
+ EncodeSpecialDate (date , buf );
1501
1495
else
1502
1496
{
1503
1497
j2date (date + POSTGRES_EPOCH_JDATE ,
1504
1498
& (tm .tm_year ), & (tm .tm_mon ), & (tm .tm_mday ));
1505
1499
EncodeDateOnly (& tm , USE_XSD_DATES , buf );
1506
- appendStringInfo (result , "\"%s\"" , buf );
1507
1500
}
1501
+ appendStringInfo (result , "\"%s\"" , buf );
1508
1502
}
1509
1503
break ;
1510
1504
case JSONTYPE_TIMESTAMP :
@@ -1515,21 +1509,16 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
1515
1509
char buf [MAXDATELEN + 1 ];
1516
1510
1517
1511
timestamp = DatumGetTimestamp (val );
1518
-
1512
+ /* Same as timestamp_out(), but forcing DateStyle */
1519
1513
if (TIMESTAMP_NOT_FINITE (timestamp ))
1520
- {
1521
- /* we have to format infinity ourselves */
1522
- appendStringInfoString (result , DT_INFINITY );
1523
- }
1514
+ EncodeSpecialTimestamp (timestamp , buf );
1524
1515
else if (timestamp2tm (timestamp , NULL , & tm , & fsec , NULL , NULL ) == 0 )
1525
- {
1526
1516
EncodeDateTime (& tm , fsec , false, 0 , NULL , USE_XSD_DATES , buf );
1527
- appendStringInfo (result , "\"%s\"" , buf );
1528
- }
1529
1517
else
1530
1518
ereport (ERROR ,
1531
1519
(errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
1532
1520
errmsg ("timestamp out of range" )));
1521
+ appendStringInfo (result , "\"%s\"" , buf );
1533
1522
}
1534
1523
break ;
1535
1524
case JSONTYPE_TIMESTAMPTZ :
@@ -1541,22 +1530,17 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
1541
1530
const char * tzn = NULL ;
1542
1531
char buf [MAXDATELEN + 1 ];
1543
1532
1544
- timestamp = DatumGetTimestamp (val );
1545
-
1533
+ timestamp = DatumGetTimestampTz (val );
1534
+ /* Same as timestamptz_out(), but forcing DateStyle */
1546
1535
if (TIMESTAMP_NOT_FINITE (timestamp ))
1547
- {
1548
- /* we have to format infinity ourselves */
1549
- appendStringInfoString (result , DT_INFINITY );
1550
- }
1536
+ EncodeSpecialTimestamp (timestamp , buf );
1551
1537
else if (timestamp2tm (timestamp , & tz , & tm , & fsec , & tzn , NULL ) == 0 )
1552
- {
1553
1538
EncodeDateTime (& tm , fsec , true, tz , tzn , USE_XSD_DATES , buf );
1554
- appendStringInfo (result , "\"%s\"" , buf );
1555
- }
1556
1539
else
1557
1540
ereport (ERROR ,
1558
1541
(errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
1559
1542
errmsg ("timestamp out of range" )));
1543
+ appendStringInfo (result , "\"%s\"" , buf );
1560
1544
}
1561
1545
break ;
1562
1546
case JSONTYPE_JSON :
@@ -1875,7 +1859,7 @@ json_agg_transfn(PG_FUNCTION_ARGS)
1875
1859
{
1876
1860
MemoryContext aggcontext ,
1877
1861
oldcontext ;
1878
- JsonAggState * state ;
1862
+ JsonAggState * state ;
1879
1863
Datum val ;
1880
1864
1881
1865
if (!AggCheckCallContext (fcinfo , & aggcontext ))
@@ -1886,7 +1870,7 @@ json_agg_transfn(PG_FUNCTION_ARGS)
1886
1870
1887
1871
if (PG_ARGISNULL (0 ))
1888
1872
{
1889
- Oid arg_type = get_fn_expr_argtype (fcinfo -> flinfo , 1 );
1873
+ Oid arg_type = get_fn_expr_argtype (fcinfo -> flinfo , 1 );
1890
1874
1891
1875
if (arg_type == InvalidOid )
1892
1876
ereport (ERROR ,
@@ -1905,7 +1889,7 @@ json_agg_transfn(PG_FUNCTION_ARGS)
1905
1889
MemoryContextSwitchTo (oldcontext );
1906
1890
1907
1891
appendStringInfoChar (state -> str , '[' );
1908
- json_categorize_type (arg_type ,& state -> val_category ,
1892
+ json_categorize_type (arg_type , & state -> val_category ,
1909
1893
& state -> val_output_func );
1910
1894
}
1911
1895
else
@@ -1949,7 +1933,7 @@ json_agg_transfn(PG_FUNCTION_ARGS)
1949
1933
Datum
1950
1934
json_agg_finalfn (PG_FUNCTION_ARGS )
1951
1935
{
1952
- JsonAggState * state ;
1936
+ JsonAggState * state ;
1953
1937
1954
1938
/* cannot be called directly because of internal-type argument */
1955
1939
Assert (AggCheckCallContext (fcinfo , NULL ));
@@ -1976,7 +1960,7 @@ json_object_agg_transfn(PG_FUNCTION_ARGS)
1976
1960
{
1977
1961
MemoryContext aggcontext ,
1978
1962
oldcontext ;
1979
- JsonAggState * state ;
1963
+ JsonAggState * state ;
1980
1964
Datum arg ;
1981
1965
1982
1966
if (!AggCheckCallContext (fcinfo , & aggcontext ))
@@ -2007,7 +1991,7 @@ json_object_agg_transfn(PG_FUNCTION_ARGS)
2007
1991
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
2008
1992
errmsg ("could not determine data type for argument 1" )));
2009
1993
2010
- json_categorize_type (arg_type ,& state -> key_category ,
1994
+ json_categorize_type (arg_type , & state -> key_category ,
2011
1995
& state -> key_output_func );
2012
1996
2013
1997
arg_type = get_fn_expr_argtype (fcinfo -> flinfo , 2 );
@@ -2017,7 +2001,7 @@ json_object_agg_transfn(PG_FUNCTION_ARGS)
2017
2001
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
2018
2002
errmsg ("could not determine data type for argument 2" )));
2019
2003
2020
- json_categorize_type (arg_type ,& state -> val_category ,
2004
+ json_categorize_type (arg_type , & state -> val_category ,
2021
2005
& state -> val_output_func );
2022
2006
2023
2007
appendStringInfoString (state -> str , "{ " );
@@ -2065,7 +2049,7 @@ json_object_agg_transfn(PG_FUNCTION_ARGS)
2065
2049
Datum
2066
2050
json_object_agg_finalfn (PG_FUNCTION_ARGS )
2067
2051
{
2068
- JsonAggState * state ;
2052
+ JsonAggState * state ;
2069
2053
2070
2054
/* cannot be called directly because of internal-type argument */
2071
2055
Assert (AggCheckCallContext (fcinfo , NULL ));
0 commit comments