mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-08-26 07:58:47 +00:00
4dd92c774e
* feat: add json_object scalar function Builds a JSONB object from interleaved (key, value, ...) arguments, like MySQL's JSON_OBJECT. Values are written into the binary directly, so JSON-hostile characters (quotes, backslashes, control characters) need no text-level escaping. Keys must be non-NULL strings; values may be strings, numbers, booleans, or NULL (JSON null). Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix: build entity-graph JSON objects with json_object The derivation assembled entity_id_attrs and descriptive by concatenating a JSON text and parsing it, escaping only backslash and double quote in runtime values. A label containing a control character (e.g. a newline) produced unparseable text and failed the whole semantic_entities scan instead of one attribute. json_object assembles the JSONB binary directly from the value columns, so no text escaping is involved; NULL-to-'' stays at the call site. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * chore: trim comments and fold duplicate test coverage Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix: json_object() returns an empty object; narrow values to integers and floats MySQL's JSON_OBJECT allows an empty pair list, so the signature accepts zero arguments and the row count falls back to number_rows. Decimals stay rejected instead of casting to Float64: JSONB numbers (i64/u64/f64) cannot represent them exactly and a silent precision loss is worse than an explicit cast. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * chore: document key-to-string conversion and align test naming Keys follow MySQL JSON_OBJECT: any castable type is converted to string. Rustdoc and the cast-failure message now say so, with a numeric-key test. Test names take the module-conventional test_ prefix. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> --------- Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
218 lines
9.9 KiB
Plaintext
218 lines
9.9 KiB
Plaintext
--- json_object_keys ---
|
|
SELECT json_object_keys(parse_json('{"a": 1, "b": {"c": 2}}'));
|
|
|
|
+---------------------------------------------------------------+
|
|
| json_object_keys(parse_json(Utf8("{"a": 1, "b": {"c": 2}}"))) |
|
|
+---------------------------------------------------------------+
|
|
| [a, b] |
|
|
+---------------------------------------------------------------+
|
|
|
|
SELECT json_object_keys(parse_json('{}'));
|
|
|
|
+------------------------------------------+
|
|
| json_object_keys(parse_json(Utf8("{}"))) |
|
|
+------------------------------------------+
|
|
| [] |
|
|
+------------------------------------------+
|
|
|
|
SELECT json_object_keys(parse_json('[1, 2]'));
|
|
|
|
+----------------------------------------------+
|
|
| json_object_keys(parse_json(Utf8("[1, 2]"))) |
|
|
+----------------------------------------------+
|
|
| |
|
|
+----------------------------------------------+
|
|
|
|
SELECT json_object_keys(parse_json('null'));
|
|
|
|
+--------------------------------------------+
|
|
| json_object_keys(parse_json(Utf8("null"))) |
|
|
+--------------------------------------------+
|
|
| |
|
|
+--------------------------------------------+
|
|
|
|
SELECT json_object_keys(NULL);
|
|
|
|
+------------------------+
|
|
| json_object_keys(NULL) |
|
|
+------------------------+
|
|
| |
|
|
+------------------------+
|
|
|
|
--- json_path_exists ---
|
|
SELECT json_path_exists(parse_json('{"a": 1, "b": 2}'), '$.a');
|
|
|
|
+--------------------------------------------------------------------+
|
|
| json_path_exists(parse_json(Utf8("{"a": 1, "b": 2}")),Utf8("$.a")) |
|
|
+--------------------------------------------------------------------+
|
|
| true |
|
|
+--------------------------------------------------------------------+
|
|
|
|
SELECT json_path_exists(parse_json('{"a": 1, "b": 2}'), '$.c');
|
|
|
|
+--------------------------------------------------------------------+
|
|
| json_path_exists(parse_json(Utf8("{"a": 1, "b": 2}")),Utf8("$.c")) |
|
|
+--------------------------------------------------------------------+
|
|
| false |
|
|
+--------------------------------------------------------------------+
|
|
|
|
SELECT json_path_exists(parse_json('[1, 2]'), '[0]');
|
|
|
|
+----------------------------------------------------------+
|
|
| json_path_exists(parse_json(Utf8("[1, 2]")),Utf8("[0]")) |
|
|
+----------------------------------------------------------+
|
|
| true |
|
|
+----------------------------------------------------------+
|
|
|
|
SELECT json_path_exists(parse_json('[1, 2]'), '[2]');
|
|
|
|
+----------------------------------------------------------+
|
|
| json_path_exists(parse_json(Utf8("[1, 2]")),Utf8("[2]")) |
|
|
+----------------------------------------------------------+
|
|
| false |
|
|
+----------------------------------------------------------+
|
|
|
|
SELECT json_path_exists(parse_json('[1, 2]'), 'null');
|
|
|
|
+-----------------------------------------------------------+
|
|
| json_path_exists(parse_json(Utf8("[1, 2]")),Utf8("null")) |
|
|
+-----------------------------------------------------------+
|
|
| false |
|
|
+-----------------------------------------------------------+
|
|
|
|
SELECT json_path_exists(parse_json('null'), '$.a');
|
|
|
|
+--------------------------------------------------------+
|
|
| json_path_exists(parse_json(Utf8("null")),Utf8("$.a")) |
|
|
+--------------------------------------------------------+
|
|
| false |
|
|
+--------------------------------------------------------+
|
|
|
|
SELECT json_path_exists(NULL, '$.a');
|
|
|
|
+------------------------------------+
|
|
| json_path_exists(NULL,Utf8("$.a")) |
|
|
+------------------------------------+
|
|
| |
|
|
+------------------------------------+
|
|
|
|
SELECT json_path_exists(parse_json('{}'), NULL);
|
|
|
|
+-----------------------------------------------+
|
|
| json_path_exists(parse_json(Utf8("{}")),NULL) |
|
|
+-----------------------------------------------+
|
|
| |
|
|
+-----------------------------------------------+
|
|
|
|
--- json_path_match ---
|
|
SELECT json_path_match(parse_json('{"a": 1, "b": 2}'), '$.a == 1');
|
|
|
|
+------------------------------------------------------------------------+
|
|
| json_path_match(parse_json(Utf8("{"a": 1, "b": 2}")),Utf8("$.a == 1")) |
|
|
+------------------------------------------------------------------------+
|
|
| true |
|
|
+------------------------------------------------------------------------+
|
|
|
|
SELECT json_path_match(parse_json('{"a":1,"b":[1,2,3]}'), '$.b[0] > 1');
|
|
|
|
+-----------------------------------------------------------------------------+
|
|
| json_path_match(parse_json(Utf8("{"a":1,"b":[1,2,3]}")),Utf8("$.b[0] > 1")) |
|
|
+-----------------------------------------------------------------------------+
|
|
| false |
|
|
+-----------------------------------------------------------------------------+
|
|
|
|
SELECT json_path_match(parse_json('{"a":1,"b":[1,2,3]}'), '$.b[1 to last] >= 2');
|
|
|
|
+--------------------------------------------------------------------------------------+
|
|
| json_path_match(parse_json(Utf8("{"a":1,"b":[1,2,3]}")),Utf8("$.b[1 to last] >= 2")) |
|
|
+--------------------------------------------------------------------------------------+
|
|
| true |
|
|
+--------------------------------------------------------------------------------------+
|
|
|
|
SELECT json_path_match(parse_json('{"a":1,"b":[1,2,3]}'), 'null');
|
|
|
|
+-----------------------------------------------------------------------+
|
|
| json_path_match(parse_json(Utf8("{"a":1,"b":[1,2,3]}")),Utf8("null")) |
|
|
+-----------------------------------------------------------------------+
|
|
| |
|
|
+-----------------------------------------------------------------------+
|
|
|
|
SELECT json_path_match(parse_json('null'), '$.a == 1');
|
|
|
|
+------------------------------------------------------------+
|
|
| json_path_match(parse_json(Utf8("null")),Utf8("$.a == 1")) |
|
|
+------------------------------------------------------------+
|
|
| |
|
|
+------------------------------------------------------------+
|
|
|
|
--- json_object ---
|
|
SELECT json_to_string(json_object('a', 1, 'b', 'text', 'c', true, 'd', 1.5));
|
|
|
|
+-----------------------------------------------------------------------------------------------------------------------+
|
|
| json_to_string(json_object(Utf8("a"),Int64(1),Utf8("b"),Utf8("text"),Utf8("c"),Boolean(true),Utf8("d"),Float64(1.5))) |
|
|
+-----------------------------------------------------------------------------------------------------------------------+
|
|
| {"a":1,"b":"text","c":true,"d":1.5} |
|
|
+-----------------------------------------------------------------------------------------------------------------------+
|
|
|
|
SELECT json_to_string(json_object());
|
|
|
|
+-------------------------------+
|
|
| json_to_string(json_object()) |
|
|
+-------------------------------+
|
|
| {} |
|
|
+-------------------------------+
|
|
|
|
SELECT json_to_string(json_object('nul', NULL));
|
|
|
|
+-----------------------------------------------+
|
|
| json_to_string(json_object(Utf8("nul"),NULL)) |
|
|
+-----------------------------------------------+
|
|
| {"nul":null} |
|
|
+-----------------------------------------------+
|
|
|
|
SELECT json_to_string(json_object('nl', concat('line1', chr(10), 'line2'), 'q', 'quote"back\slash'));
|
|
|
|
+-------------------------------------------------------------------------------------------------------------------------------+
|
|
| json_to_string(json_object(Utf8("nl"),concat(Utf8("line1"),chr(Int64(10)),Utf8("line2")),Utf8("q"),Utf8("quote"back\slash"))) |
|
|
+-------------------------------------------------------------------------------------------------------------------------------+
|
|
| {"nl":"line1\nline2","q":"quote\"back\\slash"} |
|
|
+-------------------------------------------------------------------------------------------------------------------------------+
|
|
|
|
SELECT json_object('a');
|
|
|
|
Error: 3001(EngineExecuteQuery), Execution error: json_object expects (key, value) argument pairs, got 1 arguments
|
|
|
|
SELECT json_object(NULL, 1);
|
|
|
|
Error: 3001(EngineExecuteQuery), Execution error: json_object does not allow NULL keys
|
|
|
|
SELECT json_object('ts', to_timestamp(0));
|
|
|
|
Error: 3001(EngineExecuteQuery), Execution error: json_object does not support values of type Timestamp(ns); cast the value to a string
|
|
|
|
SELECT json_object('price', CAST('12.34' AS DECIMAL(10, 2)));
|
|
|
|
Error: 3001(EngineExecuteQuery), Execution error: json_object does not support values of type Decimal128(10, 2); cast the value to a string
|
|
|
|
CREATE TABLE json_object_src (ts TIMESTAMP TIME INDEX, host STRING, pid BIGINT);
|
|
|
|
Affected Rows: 0
|
|
|
|
INSERT INTO json_object_src VALUES (0, 'h1', 42), (1, NULL, 7);
|
|
|
|
Affected Rows: 2
|
|
|
|
SELECT json_to_string(json_object('host', host, 'pid', pid)) FROM json_object_src ORDER BY ts;
|
|
|
|
+------------------------------------------------------------------------------------------------+
|
|
| json_to_string(json_object(Utf8("host"),json_object_src.host,Utf8("pid"),json_object_src.pid)) |
|
|
+------------------------------------------------------------------------------------------------+
|
|
| {"host":"h1","pid":42} |
|
|
| {"host":null,"pid":7} |
|
|
+------------------------------------------------------------------------------------------------+
|
|
|
|
DROP TABLE json_object_src;
|
|
|
|
Affected Rows: 0
|
|
|