Esempio n. 1
0
/*
 * 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));
}
Esempio n. 2
0
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);
}