mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Unify JSON categorize type API and export for external use
This essentially removes the JsonbTypeCategory enum and jsonb_categorize_type() and integrates any jsonb-specific logic that was in jsonb_categorize_type() into json_categorize_type(), now moved to jsonfuncs.c. The remaining JsonTypeCategory enum and json_categorize_type() cover the needs of the callers in both json.c and jsonb.c. json_categorize_type() has grown a new parameter named is_jsonb for callers to engage the jsonb-specific behavior of json_categorize_type(). One notable change in the now exported API of json_categorize_type() is that it now always returns *outfuncoid even though a caller may have no need currently to see one. This is in preparation of later commits to implement additional SQL/JSON functions. Co-authored-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
This commit is contained in:
@ -26,6 +26,7 @@
|
||||
#include "mb/pg_wchar.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/miscnodes.h"
|
||||
#include "parser/parse_coerce.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgroids.h"
|
||||
@ -5685,3 +5686,113 @@ json_get_first_token(text *json, bool throw_error)
|
||||
|
||||
return JSON_TOKEN_INVALID; /* invalid json */
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine how we want to print values of a given type in datum_to_json(b).
|
||||
*
|
||||
* Given the datatype OID, return its JsonTypeCategory, as well as the type's
|
||||
* output function OID. If the returned category is JSONTYPE_CAST, we return
|
||||
* the OID of the type->JSON cast function instead.
|
||||
*/
|
||||
void
|
||||
json_categorize_type(Oid typoid, bool is_jsonb,
|
||||
JsonTypeCategory *tcategory, Oid *outfuncoid)
|
||||
{
|
||||
bool typisvarlena;
|
||||
|
||||
/* Look through any domain */
|
||||
typoid = getBaseType(typoid);
|
||||
|
||||
*outfuncoid = InvalidOid;
|
||||
|
||||
switch (typoid)
|
||||
{
|
||||
case BOOLOID:
|
||||
*outfuncoid = F_BOOLOUT;
|
||||
*tcategory = JSONTYPE_BOOL;
|
||||
break;
|
||||
|
||||
case INT2OID:
|
||||
case INT4OID:
|
||||
case INT8OID:
|
||||
case FLOAT4OID:
|
||||
case FLOAT8OID:
|
||||
case NUMERICOID:
|
||||
getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
|
||||
*tcategory = JSONTYPE_NUMERIC;
|
||||
break;
|
||||
|
||||
case DATEOID:
|
||||
*outfuncoid = F_DATE_OUT;
|
||||
*tcategory = JSONTYPE_DATE;
|
||||
break;
|
||||
|
||||
case TIMESTAMPOID:
|
||||
*outfuncoid = F_TIMESTAMP_OUT;
|
||||
*tcategory = JSONTYPE_TIMESTAMP;
|
||||
break;
|
||||
|
||||
case TIMESTAMPTZOID:
|
||||
*outfuncoid = F_TIMESTAMPTZ_OUT;
|
||||
*tcategory = JSONTYPE_TIMESTAMPTZ;
|
||||
break;
|
||||
|
||||
case JSONOID:
|
||||
getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
|
||||
*tcategory = JSONTYPE_JSON;
|
||||
break;
|
||||
|
||||
case JSONBOID:
|
||||
getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
|
||||
*tcategory = is_jsonb ? JSONTYPE_JSONB : JSONTYPE_JSON;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Check for arrays and composites */
|
||||
if (OidIsValid(get_element_type(typoid)) || typoid == ANYARRAYOID
|
||||
|| typoid == ANYCOMPATIBLEARRAYOID || typoid == RECORDARRAYOID)
|
||||
{
|
||||
*outfuncoid = F_ARRAY_OUT;
|
||||
*tcategory = JSONTYPE_ARRAY;
|
||||
}
|
||||
else if (type_is_rowtype(typoid)) /* includes RECORDOID */
|
||||
{
|
||||
*outfuncoid = F_RECORD_OUT;
|
||||
*tcategory = JSONTYPE_COMPOSITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* It's probably the general case. But let's look for a cast
|
||||
* to json (note: not to jsonb even if is_jsonb is true), if
|
||||
* it's not built-in.
|
||||
*/
|
||||
*tcategory = JSONTYPE_OTHER;
|
||||
if (typoid >= FirstNormalObjectId)
|
||||
{
|
||||
Oid castfunc;
|
||||
CoercionPathType ctype;
|
||||
|
||||
ctype = find_coercion_pathway(JSONOID, typoid,
|
||||
COERCION_EXPLICIT,
|
||||
&castfunc);
|
||||
if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc))
|
||||
{
|
||||
*outfuncoid = castfunc;
|
||||
*tcategory = JSONTYPE_CAST;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* non builtin type with no cast */
|
||||
getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* any other builtin type */
|
||||
getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user