@@ -1869,10 +1869,10 @@ json_object_agg_transfn(PG_FUNCTION_ARGS)
18691869if (PG_ARGISNULL (0 ))
18701870{
18711871/*
1872- * Makethis StringInfo in a context where it will persist for the
1873- * durationoff the aggregate call.It's only needed for this initial
1874- *piece , as the StringInfo routines make sure they use the right
1875- * context to enlarge the object if necessary.
1872+ * Makethe StringInfo in a context where it will persist for the
1873+ * durationof the aggregate call.Switching context is only needed
1874+ *for this initial step , as the StringInfo routines make sure they
1875+ *use the right context to enlarge the object if necessary.
18761876 */
18771877oldcontext = MemoryContextSwitchTo (aggcontext );
18781878state = makeStringInfo ();
@@ -1886,56 +1886,43 @@ json_object_agg_transfn(PG_FUNCTION_ARGS)
18861886appendStringInfoString (state ,", " );
18871887}
18881888
1889- if (PG_ARGISNULL (1 ))
1890- ereport (ERROR ,
1891- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1892- errmsg ("field name must not be null" )));
1893-
1894- val_type = get_fn_expr_argtype (fcinfo -> flinfo ,1 );
1895-
18961889/*
1897- * turn a constant (more or less literal) value that's of unknown type
1898- * into text. Unknowns come in as a cstring pointer.
1890+ * Note: since json_object_agg() is declared as taking type "any", the
1891+ * parser will not do any type conversion on unknown-type literals (that
1892+ * is, undecorated strings or NULLs). Such values will arrive here as
1893+ * type UNKNOWN, which fortunately does not matter to us, since
1894+ * unknownout() works fine.
18991895 */
1900- if (val_type == UNKNOWNOID && get_fn_expr_arg_stable (fcinfo -> flinfo ,1 ))
1901- {
1902- val_type = TEXTOID ;
1903- arg = CStringGetTextDatum (PG_GETARG_POINTER (1 ));
1904- }
1905- else
1906- {
1907- arg = PG_GETARG_DATUM (1 );
1908- }
1896+ val_type = get_fn_expr_argtype (fcinfo -> flinfo ,1 );
19091897
1910- if (val_type == InvalidOid || val_type == UNKNOWNOID )
1898+ if (val_type == InvalidOid )
19111899ereport (ERROR ,
19121900(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
19131901errmsg ("could not determine data type for argument %d" ,1 )));
19141902
1903+ if (PG_ARGISNULL (1 ))
1904+ ereport (ERROR ,
1905+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1906+ errmsg ("field name must not be null" )));
1907+
1908+ arg = PG_GETARG_DATUM (1 );
1909+
19151910add_json (arg , false,state ,val_type , true);
19161911
19171912appendStringInfoString (state ," : " );
19181913
19191914val_type = get_fn_expr_argtype (fcinfo -> flinfo ,2 );
1920- /* see comments above */
1921- if (val_type == UNKNOWNOID && get_fn_expr_arg_stable (fcinfo -> flinfo ,2 ))
1922- {
1923- val_type = TEXTOID ;
1924- if (PG_ARGISNULL (2 ))
1925- arg = (Datum )0 ;
1926- else
1927- arg = CStringGetTextDatum (PG_GETARG_POINTER (2 ));
1928- }
1929- else
1930- {
1931- arg = PG_GETARG_DATUM (2 );
1932- }
19331915
1934- if (val_type == InvalidOid || val_type == UNKNOWNOID )
1916+ if (val_type == InvalidOid )
19351917ereport (ERROR ,
19361918(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
19371919errmsg ("could not determine data type for argument %d" ,2 )));
19381920
1921+ if (PG_ARGISNULL (2 ))
1922+ arg = (Datum )0 ;
1923+ else
1924+ arg = PG_GETARG_DATUM (2 );
1925+
19391926add_json (arg ,PG_ARGISNULL (2 ),state ,val_type , false);
19401927
19411928PG_RETURN_POINTER (state );
@@ -1972,7 +1959,7 @@ json_build_object(PG_FUNCTION_ARGS)
19721959int nargs = PG_NARGS ();
19731960int i ;
19741961Datum arg ;
1975- char * sep = "" ;
1962+ const char * sep = "" ;
19761963StringInfo result ;
19771964Oid val_type ;
19781965
@@ -1988,60 +1975,51 @@ json_build_object(PG_FUNCTION_ARGS)
19881975
19891976for (i = 0 ;i < nargs ;i += 2 )
19901977{
1978+ /*
1979+ * Note: since json_build_object() is declared as taking type "any",
1980+ * the parser will not do any type conversion on unknown-type literals
1981+ * (that is, undecorated strings or NULLs). Such values will arrive
1982+ * here as type UNKNOWN, which fortunately does not matter to us,
1983+ * since unknownout() works fine.
1984+ */
1985+ appendStringInfoString (result ,sep );
1986+ sep = ", " ;
1987+
19911988/* process key */
1989+ val_type = get_fn_expr_argtype (fcinfo -> flinfo ,i );
1990+
1991+ if (val_type == InvalidOid )
1992+ ereport (ERROR ,
1993+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1994+ errmsg ("could not determine data type for argument %d" ,
1995+ i + 1 )));
19921996
19931997if (PG_ARGISNULL (i ))
19941998ereport (ERROR ,
19951999(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
19962000errmsg ("argument %d cannot be null" ,i + 1 ),
19972001errhint ("Object keys should be text." )));
1998- val_type = get_fn_expr_argtype (fcinfo -> flinfo ,i );
19992002
2000- /*
2001- * turn a constant (more or less literal) value that's of unknown type
2002- * into text. Unknowns come in as a cstring pointer.
2003- */
2004- if (val_type == UNKNOWNOID && get_fn_expr_arg_stable (fcinfo -> flinfo ,i ))
2005- {
2006- val_type = TEXTOID ;
2007- arg = CStringGetTextDatum (PG_GETARG_POINTER (i ));
2008- }
2009- else
2010- {
2011- arg = PG_GETARG_DATUM (i );
2012- }
2013- if (val_type == InvalidOid || val_type == UNKNOWNOID )
2014- ereport (ERROR ,
2015- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
2016- errmsg ("could not determine data type for argument %d" ,
2017- i + 1 )));
2018- appendStringInfoString (result ,sep );
2019- sep = ", " ;
2003+ arg = PG_GETARG_DATUM (i );
2004+
20202005add_json (arg , false,result ,val_type , true);
20212006
20222007appendStringInfoString (result ," : " );
20232008
20242009/* process value */
2025-
20262010val_type = get_fn_expr_argtype (fcinfo -> flinfo ,i + 1 );
2027- /* see comments above */
2028- if (val_type == UNKNOWNOID && get_fn_expr_arg_stable (fcinfo -> flinfo ,i + 1 ))
2029- {
2030- val_type = TEXTOID ;
2031- if (PG_ARGISNULL (i + 1 ))
2032- arg = (Datum )0 ;
2033- else
2034- arg = CStringGetTextDatum (PG_GETARG_POINTER (i + 1 ));
2035- }
2036- else
2037- {
2038- arg = PG_GETARG_DATUM (i + 1 );
2039- }
2040- if (val_type == InvalidOid || val_type == UNKNOWNOID )
2011+
2012+ if (val_type == InvalidOid )
20412013ereport (ERROR ,
20422014(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
20432015errmsg ("could not determine data type for argument %d" ,
20442016i + 2 )));
2017+
2018+ if (PG_ARGISNULL (i + 1 ))
2019+ arg = (Datum )0 ;
2020+ else
2021+ arg = PG_GETARG_DATUM (i + 1 );
2022+
20452023add_json (arg ,PG_ARGISNULL (i + 1 ),result ,val_type , false);
20462024}
20472025
@@ -2068,45 +2046,45 @@ json_build_array(PG_FUNCTION_ARGS)
20682046int nargs = PG_NARGS ();
20692047int i ;
20702048Datum arg ;
2071- char * sep = "" ;
2049+ const char * sep = "" ;
20722050StringInfo result ;
20732051Oid val_type ;
20742052
2075-
20762053result = makeStringInfo ();
20772054
20782055appendStringInfoChar (result ,'[' );
20792056
20802057for (i = 0 ;i < nargs ;i ++ )
20812058{
2059+ /*
2060+ * Note: since json_build_array() is declared as taking type "any",
2061+ * the parser will not do any type conversion on unknown-type literals
2062+ * (that is, undecorated strings or NULLs). Such values will arrive
2063+ * here as type UNKNOWN, which fortunately does not matter to us,
2064+ * since unknownout() works fine.
2065+ */
2066+ appendStringInfoString (result ,sep );
2067+ sep = ", " ;
2068+
20822069val_type = get_fn_expr_argtype (fcinfo -> flinfo ,i );
2083- arg = PG_GETARG_DATUM (i + 1 );
2084- /* see comments in json_build_object above */
2085- if (val_type == UNKNOWNOID && get_fn_expr_arg_stable (fcinfo -> flinfo ,i ))
2086- {
2087- val_type = TEXTOID ;
2088- if (PG_ARGISNULL (i ))
2089- arg = (Datum )0 ;
2090- else
2091- arg = CStringGetTextDatum (PG_GETARG_POINTER (i ));
2092- }
2093- else
2094- {
2095- arg = PG_GETARG_DATUM (i );
2096- }
2097- if (val_type == InvalidOid || val_type == UNKNOWNOID )
2070+
2071+ if (val_type == InvalidOid )
20982072ereport (ERROR ,
20992073(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
21002074errmsg ("could not determine data type for argument %d" ,
21012075i + 1 )));
2102- appendStringInfoString (result ,sep );
2103- sep = ", " ;
2076+
2077+ if (PG_ARGISNULL (i ))
2078+ arg = (Datum )0 ;
2079+ else
2080+ arg = PG_GETARG_DATUM (i );
2081+
21042082add_json (arg ,PG_ARGISNULL (i ),result ,val_type , false);
21052083}
2084+
21062085appendStringInfoChar (result ,']' );
21072086
21082087PG_RETURN_TEXT_P (cstring_to_text_with_len (result -> data ,result -> len ));
2109-
21102088}
21112089
21122090/*