/* * Turn a scalar Datum into JSON, appending the string to "result". * * Hand off a non-scalar datum to composite_to_json or array_to_json_internal * as appropriate. */ static void datum_to_json(Datum val, bool is_null, StringInfo result, TYPCATEGORY tcategory, Oid typoutputfunc) { char *outputstr; if (is_null) { appendStringInfoString(result, "null"); return; } switch (tcategory) { case TYPCATEGORY_ARRAY: array_to_json_internal(val, result, false); break; case TYPCATEGORY_COMPOSITE: composite_to_json(val, result, false); break; case TYPCATEGORY_BOOLEAN: if (DatumGetBool(val)) appendStringInfoString(result, "true"); else appendStringInfoString(result, "false"); break; case TYPCATEGORY_NUMERIC: outputstr = OidOutputFunctionCall(typoutputfunc, val); /* * Don't call escape_json here if it's a valid JSON number. * Numeric output should usually be a valid JSON number and JSON * numbers shouldn't be quoted. Quote cases like "Nan" and * "Infinity", however. */ if (strpbrk(outputstr, NON_NUMERIC_LETTER) == NULL) appendStringInfoString(result, outputstr); else escape_json(result, outputstr); pfree(outputstr); break; case TYPCATEGORY_JSON: /* JSON will already be escaped */ outputstr = OidOutputFunctionCall(typoutputfunc, val); appendStringInfoString(result, outputstr); pfree(outputstr); break; default: outputstr = OidOutputFunctionCall(typoutputfunc, val); escape_json(result, outputstr); pfree(outputstr); break; } }
/* * SQL function row_to_json(row) */ extern Datum row_to_json(PG_FUNCTION_ARGS) { Datum array = PG_GETARG_DATUM(0); StringInfo result; result = makeStringInfo(); composite_to_json(array, result, false); PG_RETURN_TEXT_P(cstring_to_text(result->data)); };
/* * SQL function row_to_json(row, prettybool) */ extern Datum row_to_json_pretty(PG_FUNCTION_ARGS) { Datum array = PG_GETARG_DATUM(0); bool use_line_feeds = PG_GETARG_BOOL(1); StringInfo result; result = makeStringInfo(); composite_to_json(array, result, use_line_feeds); PG_RETURN_TEXT_P(cstring_to_text(result->data)); };
/* * Turn a scalar Datum into JSON. Hand off a non-scalar datum to * composite_to_json or array_to_json_internal as appropriate. */ static inline void datum_to_json(Datum val, StringInfo result, TYPCATEGORY tcategory, Oid typoutputfunc) { char *outputstr; if (val == (Datum) NULL) { appendStringInfoString(result,"null"); return; } switch (tcategory) { case TYPCATEGORY_ARRAY: array_to_json_internal(val, result, false); break; case TYPCATEGORY_COMPOSITE: composite_to_json(val, result, false); break; case TYPCATEGORY_BOOLEAN: if (DatumGetBool(val)) appendStringInfoString(result,"true"); else appendStringInfoString(result,"false"); break; case TYPCATEGORY_NUMERIC: outputstr = OidOutputFunctionCall(typoutputfunc, val); /* * Don't call escape_json here. Numeric output should * be a valid JSON number and JSON numbers shouldn't * be quoted. */ appendStringInfoString(result, outputstr); pfree(outputstr); break; default: outputstr = OidOutputFunctionCall(typoutputfunc, val); escape_json(result, outputstr); pfree(outputstr); } }