Correctly handle NULLs in JSON output.
authorAndrew Dunstan
Fri, 24 Feb 2012 04:44:16 +0000 (23:44 -0500)
committerAndrew Dunstan
Fri, 24 Feb 2012 04:44:16 +0000 (23:44 -0500)
Error reported by David Wheeler.

src/backend/utils/adt/json.c

index d7db4cf0cf93534d5173d5c338cf67063258d674..2968c57e3f88e15e3ff1026d5dc1985b09a3b63a 100644 (file)
@@ -79,9 +79,10 @@ static void report_parse_error(JsonParseStack *stack, JsonLexContext *lex);
 static void report_invalid_token(JsonLexContext *lex);
 static char *extract_mb_char(char *s);
 static void composite_to_json(Datum composite, StringInfo result, bool use_line_feeds);
-static void array_dim_to_json(StringInfo result, int dim, int ndims,int * dims,
-                             Datum *vals, int * valcount, TYPCATEGORY tcategory,
-                             Oid typoutputfunc, bool use_line_feeds);
+static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims,
+                             Datum *vals, bool *nulls, int *valcount, 
+                             TYPCATEGORY tcategory, Oid typoutputfunc, 
+                             bool use_line_feeds);
 static void array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds);
 
 /* fake type category for JSON so we can distinguish it in datum_to_json */
@@ -682,13 +683,13 @@ extract_mb_char(char *s)
  * composite_to_json or array_to_json_internal as appropriate.
  */
 static inline void
-datum_to_json(Datum val, StringInfo result, TYPCATEGORY tcategory,
+datum_to_json(Datum val, bool is_null, StringInfo result, TYPCATEGORY tcategory,
              Oid typoutputfunc)
 {
 
    char *outputstr;
 
-   if (val == (Datum) NULL)
+   if (is_null)
    {
        appendStringInfoString(result,"null");
        return;
@@ -742,8 +743,8 @@ datum_to_json(Datum val, StringInfo result, TYPCATEGORY tcategory,
  */
 static void
 array_dim_to_json(StringInfo result, int dim, int ndims,int * dims, Datum *vals,
-                 int * valcount, TYPCATEGORY tcategory, Oid typoutputfunc,
-                 bool use_line_feeds)
+                 bool *nulls, int * valcount, TYPCATEGORY tcategory, 
+                 Oid typoutputfunc, bool use_line_feeds)
 {
 
    int i;
@@ -762,7 +763,8 @@ array_dim_to_json(StringInfo result, int dim, int ndims,int * dims, Datum *vals,
 
        if (dim + 1 == ndims)
        {
-           datum_to_json(vals[*valcount],result,tcategory,typoutputfunc);
+           datum_to_json(vals[*valcount], nulls[*valcount], result, tcategory,
+                         typoutputfunc);
            (*valcount)++;
        }
        else
@@ -771,8 +773,8 @@ array_dim_to_json(StringInfo result, int dim, int ndims,int * dims, Datum *vals,
             * Do we want line feeds on inner dimensions of arrays?
             * For now we'll say no.
             */
-           array_dim_to_json(result, dim+1, ndims, dims, vals, valcount,
-                             tcategory,typoutputfunc,false);
+           array_dim_to_json(result, dim+1, ndims, dims, vals, nulls,
+                             valcount, tcategory, typoutputfunc, false);
        }
    }
 
@@ -827,7 +829,7 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
    else
        tcategory = TypeCategory(element_type);
 
-   array_dim_to_json(result, 0, ndim, dim, elements, &count, tcategory,
+   array_dim_to_json(result, 0, ndim, dim, elements, nulls, &count, tcategory,
                      typoutputfunc, use_line_feeds);
 
    pfree(elements);
@@ -908,7 +910,7 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
        else
            val = origval;
 
-       datum_to_json(val, result, tcategory, typoutput);
+       datum_to_json(val, isnull, result, tcategory, typoutput);
 
        /* Clean up detoasted copy, if any */
        if (val != origval)