Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4d212ba

Browse files
committed
json_typeof function.
Andrew Tipton.
1 parent4b7b9a7 commit4d212ba

File tree

8 files changed

+158
-4
lines changed

8 files changed

+158
-4
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10095,7 +10095,7 @@ table2-mapping
1009510095
</entry>
1009610096
<entry><type>json</type></entry>
1009710097
<entry>
10098-
Returns JSONobject pointed to by <parameter>path_elems</parameter>.
10098+
Returns JSONvalue pointed to by <parameter>path_elems</parameter>.
1009910099
</entry>
1010010100
<entry><literal>json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4')</literal></entry>
1010110101
<entry><literal>{"f5":99,"f6":"foo"}</literal></entry>
@@ -10109,7 +10109,7 @@ table2-mapping
1010910109
</entry>
1011010110
<entry><type>text</type></entry>
1011110111
<entry>
10112-
Returns JSONobject pointed to by <parameter>path_elems</parameter>.
10112+
Returns JSONvalue pointed to by <parameter>path_elems</parameter>.
1011310113
</entry>
1011410114
<entry><literal>json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4', 'f6')</literal></entry>
1011510115
<entry><literal>foo</literal></entry>
@@ -10192,7 +10192,7 @@ table2-mapping
1019210192
</entry>
1019310193
<entry><type>SETOF json</type></entry>
1019410194
<entry>
10195-
Expands a JSON array to a set of JSONelements.
10195+
Expands a JSON array to a set of JSONvalues.
1019610196
</entry>
1019710197
<entry><literal>json_array_elements('[1,true, [2,false]]')</literal></entry>
1019810198
<entry>
@@ -10205,6 +10205,23 @@ table2-mapping
1020510205
</programlisting>
1020610206
</entry>
1020710207
</row>
10208+
<row>
10209+
<entry>
10210+
<indexterm>
10211+
<primary>json_typeof</primary>
10212+
</indexterm>
10213+
<literal>json_typeof(json)</literal>
10214+
</entry>
10215+
<entry><type>text</type></entry>
10216+
<entry>
10217+
Returns the type of the outermost JSON value as a text string. The types are
10218+
<literal>object</>, <literal>array</>, <literal>string</>, <literal>number</>,
10219+
<literal>boolean</>, and <literal>null</>. (See note below regarding the
10220+
distinction between a JSON <literal>null</> and a SQL NULL.)
10221+
</entry>
10222+
<entry><literal>json_typeof('-123.4')</literal></entry>
10223+
<entry><literal>number</literal></entry>
10224+
</row>
1020810225
</tbody>
1020910226
</tgroup>
1021010227
</table>
@@ -10237,6 +10254,14 @@ table2-mapping
1023710254
</para>
1023810255
</note>
1023910256

10257+
<note>
10258+
<para>
10259+
The <literal>json_typeof</> function's <literal>null</> return value should not be confused
10260+
with a SQL NULL. While calling <literal>json_typeof('null'::json)</> will return <literal>null</>,
10261+
calling <literal>json_typeof(NULL::json)</> will return a SQL NULL.
10262+
</para>
10263+
</note>
10264+
1024010265
<para>
1024110266
See also <xref linkend="functions-aggregate"> about the aggregate
1024210267
function <function>json_agg</function> which aggregates record

‎src/backend/utils/adt/json.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,3 +1826,55 @@ escape_json(StringInfo buf, const char *str)
18261826
}
18271827
appendStringInfoCharMacro(buf,'\"');
18281828
}
1829+
1830+
/*
1831+
* SQL function json_typeof(json) -> text
1832+
*
1833+
* Returns the type of the outermost JSON value as TEXT. Possible types are
1834+
* "object", "array", "string", "number", "boolean", and "null".
1835+
*
1836+
* Performs a single call to json_lex() to get the first token of the supplied
1837+
* value. This initial token uniquely determines the value's type. As our
1838+
* input must already have been validated by json_in() or json_recv(), the
1839+
* initial token should never be JSON_TOKEN_OBJECT_END, JSON_TOKEN_ARRAY_END,
1840+
* JSON_TOKEN_COLON, JSON_TOKEN_COMMA, or JSON_TOKEN_END.
1841+
*/
1842+
Datum
1843+
json_typeof(PG_FUNCTION_ARGS)
1844+
{
1845+
text*json=PG_GETARG_TEXT_P(0);
1846+
1847+
JsonLexContext*lex=makeJsonLexContext(json, false);
1848+
JsonTokenTypetok;
1849+
char*type;
1850+
1851+
/* Lex exactly one token from the input and check its type. */
1852+
json_lex(lex);
1853+
tok=lex_peek(lex);
1854+
switch (tok)
1855+
{
1856+
caseJSON_TOKEN_OBJECT_START:
1857+
type="object";
1858+
break;
1859+
caseJSON_TOKEN_ARRAY_START:
1860+
type="array";
1861+
break;
1862+
caseJSON_TOKEN_STRING:
1863+
type="string";
1864+
break;
1865+
caseJSON_TOKEN_NUMBER:
1866+
type="number";
1867+
break;
1868+
caseJSON_TOKEN_TRUE:
1869+
caseJSON_TOKEN_FALSE:
1870+
type="boolean";
1871+
break;
1872+
caseJSON_TOKEN_NULL:
1873+
type="null";
1874+
break;
1875+
default:
1876+
elog(ERROR,"unexpected json token: %d",tok);
1877+
}
1878+
1879+
PG_RETURN_TEXT_P(cstring_to_text(type));
1880+
}

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO201310091
56+
#defineCATALOG_VERSION_NO201310101
5757

5858
#endif

‎src/include/catalog/pg_proc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4150,6 +4150,8 @@ DATA(insert OID = 3960 ( json_populate_record PGNSP PGUID 12 1 0 0 0 f f f f
41504150
DESCR("get record fields from a json object");
41514151
DATA(insertOID=3961 (json_populate_recordsetPGNSPPGUID12110000fffffts302283"2283 114 16"_null__null__null__null_json_populate_recordset_null__null__null_ ));
41524152
DESCR("get set of records with fields from a json array of objects");
4153+
DATA(insertOID=3968 (json_typeofPGNSPPGUID121000fffftfi1025"114"_null__null__null__null_json_typeof_null__null__null_ ));
4154+
DESCR("get the type of a json value");
41534155

41544156
/* uuid */
41554157
DATA(insertOID=2952 (uuid_inPGNSPPGUID121000fffftfi102950"2275"_null__null__null__null_uuid_in_null__null__null_ ));

‎src/include/utils/json.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ extern Datum json_agg_finalfn(PG_FUNCTION_ARGS);
3333

3434
externvoidescape_json(StringInfobuf,constchar*str);
3535

36+
externDatumjson_typeof(PG_FUNCTION_ARGS);
37+
3638
/* functions in jsonfuncs.c */
3739
externDatumjson_object_field(PG_FUNCTION_ARGS);
3840
externDatumjson_object_field_text(PG_FUNCTION_ARGS);

‎src/test/regress/expected/json.out

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,3 +962,32 @@ select json '{ "a": "null \u0000 escape" }' ->> 'a' as not_unescaped;
962962
null \u0000 escape
963963
(1 row)
964964

965+
--json_typeof() function
966+
select value, json_typeof(value)
967+
from (values (json '123.4'),
968+
(json '-1'),
969+
(json '"foo"'),
970+
(json 'true'),
971+
(json 'false'),
972+
(json 'null'),
973+
(json '[1, 2, 3]'),
974+
(json '[]'),
975+
(json '{"x":"foo", "y":123}'),
976+
(json '{}'),
977+
(NULL::json))
978+
as data(value);
979+
value | json_typeof
980+
----------------------+-------------
981+
123.4 | number
982+
-1 | number
983+
"foo" | string
984+
true | boolean
985+
false | boolean
986+
null | null
987+
[1, 2, 3] | array
988+
[] | array
989+
{"x":"foo", "y":123} | object
990+
{} | object
991+
|
992+
(11 rows)
993+

‎src/test/regress/expected/json_1.out

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,3 +958,32 @@ select json '{ "a": "null \u0000 escape" }' ->> 'a' as not_unescaped;
958958
null \u0000 escape
959959
(1 row)
960960

961+
--json_typeof() function
962+
select value, json_typeof(value)
963+
from (values (json '123.4'),
964+
(json '-1'),
965+
(json '"foo"'),
966+
(json 'true'),
967+
(json 'false'),
968+
(json 'null'),
969+
(json '[1, 2, 3]'),
970+
(json '[]'),
971+
(json '{"x":"foo", "y":123}'),
972+
(json '{}'),
973+
(NULL::json))
974+
as data(value);
975+
value | json_typeof
976+
----------------------+-------------
977+
123.4 | number
978+
-1 | number
979+
"foo" | string
980+
true | boolean
981+
false | boolean
982+
null | null
983+
[1, 2, 3] | array
984+
[] | array
985+
{"x":"foo", "y":123} | object
986+
{} | object
987+
|
988+
(11 rows)
989+

‎src/test/regress/sql/json.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,18 @@ select json '{ "a": "\ude04X" }' -> 'a'; -- orphan low surrogate
310310
select json'{ "a": "the Copyright\u00a9 sign" }'->>'a'as correct_in_utf8;
311311
select json'{ "a": "dollar\u0024 character" }'->>'a'as correct_everywhere;
312312
select json'{ "a": "null\u0000 escape" }'->>'a'as not_unescaped;
313+
314+
--json_typeof() function
315+
select value, json_typeof(value)
316+
from (values (json'123.4'),
317+
(json'-1'),
318+
(json'"foo"'),
319+
(json'true'),
320+
(json'false'),
321+
(json'null'),
322+
(json'[1, 2, 3]'),
323+
(json'[]'),
324+
(json'{"x":"foo", "y":123}'),
325+
(json'{}'),
326+
(NULL::json))
327+
as data(value);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp