On 11/04/2014 12:57 PM, Andrew Dunstan wrote:
here's a patch for a utility function to look up the cast function for a from/to pair of types, as recently suggested by Alvaro. Although it only contains one use (in json.c), the upcoming jsonb generators would also use it twice. I'd like to get this committed fairly quickly so I can prepare an updated patch for the jsonb generators.
This time with patch. cheers andrew
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c index d2bf640..fe9cf83 100644 --- a/src/backend/utils/adt/json.c +++ b/src/backend/utils/adt/json.c @@ -1299,22 +1299,12 @@ 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 = get_cast_func(typoid, JSONOID); - tuple = SearchSysCache2(CASTSOURCETARGET, - ObjectIdGetDatum(typoid), - ObjectIdGetDatum(JSONOID)); - if (HeapTupleIsValid(tuple)) + if (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; } } } diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 552e498..0da08fe 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -21,6 +21,7 @@ #include "bootstrap/bootstrap.h" #include "catalog/pg_amop.h" #include "catalog/pg_amproc.h" +#include "catalog/pg_cast.h" #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" #include "catalog/pg_namespace.h" @@ -2889,3 +2890,36 @@ get_range_subtype(Oid rangeOid) else return InvalidOid; } + +/* + * + * get_cast_func(fromtype, totype) -> funcoid + * + * find a cast function if any from fromtype to totype. + * + * return the Oid of the fucntion found or InvalidOid otherwise. + */ + +Oid +get_cast_func(Oid from_type, Oid to_type) +{ + HeapTuple tuple; + Oid castfunc = InvalidOid; + + tuple = SearchSysCache2(CASTSOURCETARGET, + ObjectIdGetDatum(from_type), + ObjectIdGetDatum(to_type)); + if (HeapTupleIsValid(tuple)) + { + Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple); + + if (castForm->castmethod == COERCION_METHOD_FUNCTION) + { + castfunc = castForm->castfunc; + } + + ReleaseSysCache(tuple); + } + + return castfunc; +} diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index 07d24d4..0291b96 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -151,6 +151,7 @@ extern void free_attstatsslot(Oid atttype, float4 *numbers, int nnumbers); extern char *get_namespace_name(Oid nspid); extern Oid get_range_subtype(Oid rangeOid); +extern Oid get_cast_func(Oid from_type, Oid to_type); #define type_is_array(typid) (get_element_type(typid) != InvalidOid) /* type_is_array_domain accepts both plain arrays and domains over arrays */
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers