@@ -1869,10 +1869,10 @@ json_object_agg_transfn(PG_FUNCTION_ARGS)
18691869 if (PG_ARGISNULL (0 ))
18701870 {
18711871 /*
1872- * Make this StringInfo in a context where it will persist for the
1873- * duration off 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+ * Make the StringInfo in a context where it will persist for the
1873+ * duration of 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 */
18771877 oldcontext = MemoryContextSwitchTo (aggcontext );
18781878 state = makeStringInfo ();
@@ -1886,56 +1886,43 @@ json_object_agg_transfn(PG_FUNCTION_ARGS)
18861886 appendStringInfoString (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 )
19111899 ereport (ERROR ,
19121900 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
19131901 errmsg ("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+
19151910 add_json (arg , false, state , val_type , true);
19161911
19171912 appendStringInfoString (state , " : " );
19181913
19191914 val_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 )
19351917 ereport (ERROR ,
19361918 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
19371919 errmsg ("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+
19391926 add_json (arg , PG_ARGISNULL (2 ), state , val_type , false);
19401927
19411928 PG_RETURN_POINTER (state );
@@ -1972,7 +1959,7 @@ json_build_object(PG_FUNCTION_ARGS)
19721959 int nargs = PG_NARGS ();
19731960 int i ;
19741961 Datum arg ;
1975- char * sep = "" ;
1962+ const char * sep = "" ;
19761963 StringInfo result ;
19771964 Oid val_type ;
19781965
@@ -1988,60 +1975,51 @@ json_build_object(PG_FUNCTION_ARGS)
19881975
19891976 for (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
19931997 if (PG_ARGISNULL (i ))
19941998 ereport (ERROR ,
19951999 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
19962000 errmsg ("argument %d cannot be null" , i + 1 ),
19972001 errhint ("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+
20202005 add_json (arg , false, result , val_type , true);
20212006
20222007 appendStringInfoString (result , " : " );
20232008
20242009 /* process value */
2025-
20262010 val_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 )
20412013 ereport (ERROR ,
20422014 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
20432015 errmsg ("could not determine data type for argument %d" ,
20442016 i + 2 )));
2017+
2018+ if (PG_ARGISNULL (i + 1 ))
2019+ arg = (Datum ) 0 ;
2020+ else
2021+ arg = PG_GETARG_DATUM (i + 1 );
2022+
20452023 add_json (arg , PG_ARGISNULL (i + 1 ), result , val_type , false);
20462024 }
20472025
@@ -2068,45 +2046,45 @@ json_build_array(PG_FUNCTION_ARGS)
20682046 int nargs = PG_NARGS ();
20692047 int i ;
20702048 Datum arg ;
2071- char * sep = "" ;
2049+ const char * sep = "" ;
20722050 StringInfo result ;
20732051 Oid val_type ;
20742052
2075-
20762053 result = makeStringInfo ();
20772054
20782055 appendStringInfoChar (result , '[' );
20792056
20802057 for (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+
20822069 val_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 )
20982072 ereport (ERROR ,
20992073 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
21002074 errmsg ("could not determine data type for argument %d" ,
21012075 i + 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+
21042082 add_json (arg , PG_ARGISNULL (i ), result , val_type , false);
21052083 }
2084+
21062085 appendStringInfoChar (result , ']' );
21072086
21082087 PG_RETURN_TEXT_P (cstring_to_text_with_len (result -> data , result -> len ));
2109-
21102088}
21112089
21122090/*
0 commit comments