aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/json.c
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2013-10-10 12:21:59 -0400
committerAndrew Dunstan <andrew@dunslane.net>2013-10-10 12:21:59 -0400
commit4d212bac1752e1bad6f3aa6242061c393ae93a0a (patch)
treeeed4e6beacab0e3af9dbcba309fd5f61a75b854b /src/backend/utils/adt/json.c
parent4b7b9a790405f5826ddfc7e9884805edd5396d75 (diff)
downloadpostgresql-4d212bac1752e1bad6f3aa6242061c393ae93a0a.tar.gz
postgresql-4d212bac1752e1bad6f3aa6242061c393ae93a0a.zip
json_typeof function.
Andrew Tipton.
Diffstat (limited to 'src/backend/utils/adt/json.c')
-rw-r--r--src/backend/utils/adt/json.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 9f3f5d4feb4..b6199fbf68d 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -1826,3 +1826,55 @@ escape_json(StringInfo buf, const char *str)
}
appendStringInfoCharMacro(buf, '\"');
}
+
+/*
+ * SQL function json_typeof(json) -> text
+ *
+ * Returns the type of the outermost JSON value as TEXT. Possible types are
+ * "object", "array", "string", "number", "boolean", and "null".
+ *
+ * Performs a single call to json_lex() to get the first token of the supplied
+ * value. This initial token uniquely determines the value's type. As our
+ * input must already have been validated by json_in() or json_recv(), the
+ * initial token should never be JSON_TOKEN_OBJECT_END, JSON_TOKEN_ARRAY_END,
+ * JSON_TOKEN_COLON, JSON_TOKEN_COMMA, or JSON_TOKEN_END.
+ */
+Datum
+json_typeof(PG_FUNCTION_ARGS)
+{
+ text *json = PG_GETARG_TEXT_P(0);
+
+ JsonLexContext *lex = makeJsonLexContext(json, false);
+ JsonTokenType tok;
+ char *type;
+
+ /* Lex exactly one token from the input and check its type. */
+ json_lex(lex);
+ tok = lex_peek(lex);
+ switch (tok)
+ {
+ case JSON_TOKEN_OBJECT_START:
+ type = "object";
+ break;
+ case JSON_TOKEN_ARRAY_START:
+ type = "array";
+ break;
+ case JSON_TOKEN_STRING:
+ type = "string";
+ break;
+ case JSON_TOKEN_NUMBER:
+ type = "number";
+ break;
+ case JSON_TOKEN_TRUE:
+ case JSON_TOKEN_FALSE:
+ type = "boolean";
+ break;
+ case JSON_TOKEN_NULL:
+ type = "null";
+ break;
+ default:
+ elog(ERROR, "unexpected json token: %d", tok);
+ }
+
+ PG_RETURN_TEXT_P(cstring_to_text(type));
+}