From 7e354ab9fe9e7c3b0a7a40f226c76bd5cf6438d0 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Fri, 12 Dec 2014 15:31:14 -0500 Subject: Add several generator functions for jsonb that exist for json. The functions are: to_jsonb() jsonb_object() jsonb_build_object() jsonb_build_array() jsonb_agg() jsonb_object_agg() Also along the way some better logic is implemented in json_categorize_type() to match that in the newly implemented jsonb_categorize_type(). Andrew Dunstan, reviewed by Pavel Stehule and Alvaro Herrera. --- src/backend/utils/adt/json.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'src/backend/utils/adt/json.c') diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c index 1d6b752a28b..2a9aeec8061 100644 --- a/src/backend/utils/adt/json.c +++ b/src/backend/utils/adt/json.c @@ -15,7 +15,6 @@ #include "access/htup_details.h" #include "access/transam.h" -#include "catalog/pg_cast.h" #include "catalog/pg_type.h" #include "executor/spi.h" #include "lib/stringinfo.h" @@ -1281,10 +1280,14 @@ json_categorize_type(Oid typoid, /* Look through any domain */ typoid = getBaseType(typoid); - /* We'll usually need to return the type output function */ - getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); + *outfuncoid = InvalidOid; + + /* + * We need to get the output function for everything except date and + * timestamp types, array and composite types, booleans, + * and non-builtin types where there's a cast to json. + */ - /* Check for known types */ switch (typoid) { case BOOLOID: @@ -1297,6 +1300,7 @@ json_categorize_type(Oid typoid, case FLOAT4OID: case FLOAT8OID: case NUMERICOID: + getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); *tcategory = JSONTYPE_NUMERIC; break; @@ -1314,6 +1318,7 @@ json_categorize_type(Oid typoid, case JSONOID: case JSONBOID: + getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); *tcategory = JSONTYPE_JSON; break; @@ -1330,23 +1335,26 @@ json_categorize_type(Oid typoid, /* but let's look for a cast to json, if it's not built-in */ if (typoid >= FirstNormalObjectId) { - HeapTuple tuple; + Oid castfunc; + CoercionPathType ctype; - tuple = SearchSysCache2(CASTSOURCETARGET, - ObjectIdGetDatum(typoid), - ObjectIdGetDatum(JSONOID)); - if (HeapTupleIsValid(tuple)) + ctype = find_coercion_pathway(JSONOID, typoid, + COERCION_EXPLICIT, &castfunc); + if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc)) { - Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple); - - if (castForm->castmethod == COERCION_METHOD_FUNCTION) - { - *tcategory = JSONTYPE_CAST; - *outfuncoid = castForm->castfunc; - } - - ReleaseSysCache(tuple); + *tcategory = JSONTYPE_CAST; + *outfuncoid = castfunc; } + else + { + /* non builtin type with no cast */ + getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); + } + } + else + { + /* any other builtin type */ + getTypeOutputInfo(typoid, outfuncoid, &typisvarlena); } } break; -- cgit v1.2.3