/* * SQL function jsonb_typeof(jsonb) -> text * * This function is here because the analog json function is in json.c, since * it uses the json parser internals not exposed elsewhere. */ Datum jsonb_typeof(PG_FUNCTION_ARGS) { Jsonb *in = PG_GETARG_JSONB(0); JsonbIterator *it; JsonbValue v; char *result; if (JB_ROOT_IS_OBJECT(in)) result = "object"; else if (JB_ROOT_IS_ARRAY(in) && !JB_ROOT_IS_SCALAR(in)) result = "array"; else { Assert(JB_ROOT_IS_SCALAR(in)); it = JsonbIteratorInit(VARDATA_ANY(in)); /* * A root scalar is stored as an array of one element, so we get the * array and then its first (and only) member. */ (void) JsonbIteratorNext(&it, &v, true); Assert(v.type == jbvArray); (void) JsonbIteratorNext(&it, &v, true); switch (v.type) { case jbvNull: result = "null"; break; case jbvString: result = "string"; break; case jbvNumeric: result = "number"; break; case jbvBool: result = "boolean"; break; default: elog(ERROR, "unknown jsonb scalar type"); } } PG_RETURN_TEXT_P(cstring_to_text(result)); }
Datum jsonb_bool(PG_FUNCTION_ARGS) { Jsonb *j = PG_GETARG_JSONB(0); if (JB_ROOT_IS_SCALAR(j)) { JsonbValue *jv; jv = getIthJsonbValueFromContainer(&j->root, 0); switch (jv->type) { case jbvNull: PG_RETURN_NULL(); case jbvString: PG_RETURN_BOOL(jv->val.string.len > 0); case jbvNumeric: { Datum b; if (numeric_is_nan(jv->val.numeric)) PG_RETURN_BOOL(false); b = DirectFunctionCall2(numeric_ne, NumericGetDatum(jv->val.numeric), get_numeric_0_datum()); PG_RETURN_DATUM(b); } case jbvBool: PG_RETURN_BOOL(jv->val.boolean); default: elog(ERROR, "unknown jsonb scalar type"); } } Assert(JB_ROOT_IS_OBJECT(j) || JB_ROOT_IS_ARRAY(j)); PG_RETURN_BOOL(JB_ROOT_COUNT(j) > 0); }