示例#1
0
/*
 * Turn an array into JSON.
 */
static void
array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
{
	ArrayType  *v = DatumGetArrayTypeP(array);
	Oid			element_type = ARR_ELEMTYPE(v);
	int		   *dim;
	int			ndim;
	int			nitems;
	int         count = 0;
	Datum	   *elements;
	bool       *nulls;

	int16		typlen;
	bool		typbyval;
	char		typalign,
				typdelim;
	Oid			typioparam;
	Oid			typoutputfunc;
	TYPCATEGORY tcategory;

	ndim = ARR_NDIM(v);
	dim = ARR_DIMS(v);
	nitems = ArrayGetNItems(ndim, dim);

	if (nitems <= 0)
	{
		appendStringInfoString(result,"[]");
		return;
	}

	get_type_io_data(element_type, IOFunc_output,
					 &typlen, &typbyval, &typalign,
					 &typdelim, &typioparam, &typoutputfunc);

	deconstruct_array(v, element_type, typlen, typbyval,
					  typalign, &elements, &nulls,
					  &nitems);

	if (element_type == RECORDOID)
		tcategory = TYPCATEGORY_COMPOSITE;
	else if (element_type == JSONOID)
		tcategory = TYPCATEGORY_JSON;
	else
		tcategory = TypeCategory(element_type);

	array_dim_to_json(result, 0, ndim, dim, elements, &count, tcategory,
					  typoutputfunc, use_line_feeds);

	pfree(elements);
	pfree(nulls);
}
示例#2
0
文件: json.c 项目: linusyang/postgres
/*
 * Process a single dimension of an array.
 * If it's the innermost dimension, output the values, otherwise call
 * ourselves recursively to process the next dimension.
 */
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)
{

	int i;
	char *sep;

	Assert(dim < ndims);

	sep = use_line_feeds ? ",\n " : ",";

	appendStringInfoChar(result, '[');

	for (i = 1; i <= dims[dim]; i++)
	{
		if (i > 1)
			appendStringInfoString(result,sep);

		if (dim + 1 == ndims)
		{
			datum_to_json(vals[*valcount], nulls[*valcount], result, tcategory,
						  typoutputfunc);
			(*valcount)++;
		}
		else
		{
			/*
			 * 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, nulls,
							  valcount, tcategory, typoutputfunc, false);
		}
	}

	appendStringInfoChar(result, ']');
}
示例#3
0
文件: json.c 项目: sqlparser/postgres
/*
 * Turn an array into JSON.
 */
static void
array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
{
	ArrayType  *v = DatumGetArrayTypeP(array);
	Oid			element_type = ARR_ELEMTYPE(v);
	int		   *dim;
	int			ndim;
	int			nitems;
	int			count = 0;
	Datum	   *elements;
	bool	   *nulls;
	int16		typlen;
	bool		typbyval;
	char		typalign,
				typdelim;
	Oid			typioparam;
	Oid			typoutputfunc;
	TYPCATEGORY tcategory;
	Oid			castfunc = InvalidOid;

	ndim = ARR_NDIM(v);
	dim = ARR_DIMS(v);
	nitems = ArrayGetNItems(ndim, dim);

	if (nitems <= 0)
	{
		appendStringInfoString(result, "[]");
		return;
	}

	get_type_io_data(element_type, IOFunc_output,
					 &typlen, &typbyval, &typalign,
					 &typdelim, &typioparam, &typoutputfunc);

	if (element_type > FirstNormalObjectId)
	{
		HeapTuple	tuple;
		Form_pg_cast castForm;

		tuple = SearchSysCache2(CASTSOURCETARGET,
								ObjectIdGetDatum(element_type),
								ObjectIdGetDatum(JSONOID));
		if (HeapTupleIsValid(tuple))
		{
			castForm = (Form_pg_cast) GETSTRUCT(tuple);

			if (castForm->castmethod == COERCION_METHOD_FUNCTION)
				castfunc = typoutputfunc = castForm->castfunc;

			ReleaseSysCache(tuple);
		}
	}

	deconstruct_array(v, element_type, typlen, typbyval,
					  typalign, &elements, &nulls,
					  &nitems);

	if (castfunc != InvalidOid)
		tcategory = TYPCATEGORY_JSON_CAST;
	else if (element_type == RECORDOID)
		tcategory = TYPCATEGORY_COMPOSITE;
	else if (element_type == JSONOID)
		tcategory = TYPCATEGORY_JSON;
	else
		tcategory = TypeCategory(element_type);

	array_dim_to_json(result, 0, ndim, dim, elements, nulls, &count, tcategory,
					  typoutputfunc, use_line_feeds);

	pfree(elements);
	pfree(nulls);
}