From b5e19ef3b0cd2ceb629b51c2ebe5d1fa9eaf1415 Mon Sep 17 00:00:00 2001 From: Tim Stack Date: Thu, 13 Jul 2023 21:56:11 -0700 Subject: [PATCH] [tests] add some tests for recent additions Add missing SQLite JSON functions to the help Fix some DB UI issues --- .github/workflows/bins.yml | 1 + NEWS.md | 8 + src/base/attr_line.hh | 10 +- src/base/attr_line.tests.cc | 9 + src/base/lnav.console.cc | 3 + src/curl_looper.hh | 4 + src/db_sub_source.cc | 25 +- src/db_sub_source.hh | 1 + src/help_text_formatter.cc | 4 +- src/internals/sql-ref.rst | 518 +++++++++++++++++- src/lnav.cc | 14 +- src/sql_util.cc | 20 +- src/sqlite-extension-func.cc | 204 ++++++- src/themes/monocai.json | 3 +- src/view_helpers.cc | 5 +- test/expected/expected.am | 14 + ...9c835a3c43210225cf62564b3e9584c899af20.out | 2 +- ...e41555f1a5f40f54ce241207af602ed1503a2b.out | 2 +- ...a3bb78e9d60e5e1f5ce5b18e40d2f1662707ab.out | 374 ++++++++++++- ...8ecb88b4753010c4264b3ac351260b4811612f.out | 2 +- ...40b674cd65936a72bd64b1dac1524d16fe44c3.out | 10 +- ...5128169049bd88d5eaf8b84a7f617e5ae5d936.out | 2 +- ...429aed81d7edfd47b57e9cdb8a25c43aff35c4.out | 2 +- ...bb81cfe40ee16332c5c775a74d06b945aa65c2.out | 2 +- ...15b8a38673ac4db45dc6ed2eafe609c332575b.out | 2 +- ...e288f1508eaab0367e465e9f382e848f3282aa.out | 2 +- ...e9cdc4898df5c4e112c13dfe3db6dc089c0d7c.out | 2 +- ...85d26043f9661d70f82cb90ecb3c5245d25eac.out | 2 +- ...d03a996c0750733ab99c592b9011851f521a69.out | 4 +- ...53ef036c505b75996252138fbd4c8d22e8149c.out | 2 +- ...b8da04734fadf3b9eea80e0af997e38e0fb811.out | 2 +- ...98146cf8b4f074ec8b9752f021cf47d011bebc.err | 0 ...98146cf8b4f074ec8b9752f021cf47d011bebc.out | 9 + ...14ebb5e2e83bab11023354dea8a0885ddf64b4.out | 4 +- ...1a8e35f34a206e340a3880128b6ce137847872.out | 6 +- ...a1497c13a5e09bc8f95ef02552b2835ebea6e5.out | 2 +- ...fd19d56a8cd1fc9c7eb9351270eabb491f8233.out | 6 +- ...707b6e856dbaab6f95e7e89b98dc3652021f85.out | 4 +- ...15b6737b1e0d383c8ce4a1db56332f11dbc158.out | 2 +- ...b07d8de7728752ae938a174468d75e85f3ae7e.out | 2 +- ...681c234d4f60df16c997a05163aeb058c52870.out | 6 +- ...257c56e85558aa0cc925b68d3af962afc25125.out | 2 +- ...293df041b6969ccecc60204dce3676d0fb006d.out | 2 +- ...d1128cf61a9af8f9dc937b46217443f42e1a7a.out | 2 +- ...1af17ff19d640ddfc879460910991825eedd05.out | 2 +- ...6e9f13f178def009ee58c2aeea8c3c70fdb580.out | 2 +- ...0d872ebc492fcecb2e79a0993170d5fc771a5b.out | 2 +- ...5f74863d065418bca5a000e6ad3d9344635164.out | 16 +- ...aae556ecb1661602f176215e28f661d3404032.out | 4 +- ...0fd242f57a96d40f466493938cda0789a094fa.out | 34 +- ...9373a76853f345d06234f6e0fe11b5d40da27b.out | 8 +- ...363f89638cb968584afc1ca0a4f52b2cf7a2ae.err | 0 ...363f89638cb968584afc1ca0a4f52b2cf7a2ae.out | 2 + ...1e07b6f72bce5402037761fa8afd66c05b4c34.err | 1 + ...1e07b6f72bce5402037761fa8afd66c05b4c34.out | 0 ...fc889eefb98571ecf3892ad670646613bf13a3.err | 1 + ...fc889eefb98571ecf3892ad670646613bf13a3.out | 0 ...860c50e91cd6c1f2004ee0414a6e930ed42c87.err | 1 + ...860c50e91cd6c1f2004ee0414a6e930ed42c87.out | 0 ...ebe81c4881f704624a65ec91be0868c310f6ed.err | 0 ...ebe81c4881f704624a65ec91be0868c310f6ed.out | 2 + ...c7b869132c33cae3c2565806c2396e1b4d6253.err | 0 ...c7b869132c33cae3c2565806c2396e1b4d6253.out | 2 + ...d15cb9d5a9259f198aa01ca8ed200d6da38d68.out | 4 +- ...dc3eb51ec4dc3066a2365524001242c423a9cf.out | 2 +- ...c0f0e51b3f85ea2a05ecdcacaad962b4fe5d4f.out | 2 +- ...2cd055e6a1db2ed9b2af2a917f8556395fa653.out | 2 +- test/test_sql_anno.sh | 2 + test/test_sql_str_func.sh | 24 + 69 files changed, 1275 insertions(+), 140 deletions(-) create mode 100644 test/expected/test_sql_anno.sh_1398146cf8b4f074ec8b9752f021cf47d011bebc.err create mode 100644 test/expected/test_sql_anno.sh_1398146cf8b4f074ec8b9752f021cf47d011bebc.out create mode 100644 test/expected/test_sql_str_func.sh_00363f89638cb968584afc1ca0a4f52b2cf7a2ae.err create mode 100644 test/expected/test_sql_str_func.sh_00363f89638cb968584afc1ca0a4f52b2cf7a2ae.out create mode 100644 test/expected/test_sql_str_func.sh_1a1e07b6f72bce5402037761fa8afd66c05b4c34.err create mode 100644 test/expected/test_sql_str_func.sh_1a1e07b6f72bce5402037761fa8afd66c05b4c34.out create mode 100644 test/expected/test_sql_str_func.sh_57fc889eefb98571ecf3892ad670646613bf13a3.err create mode 100644 test/expected/test_sql_str_func.sh_57fc889eefb98571ecf3892ad670646613bf13a3.out create mode 100644 test/expected/test_sql_str_func.sh_68860c50e91cd6c1f2004ee0414a6e930ed42c87.err create mode 100644 test/expected/test_sql_str_func.sh_68860c50e91cd6c1f2004ee0414a6e930ed42c87.out create mode 100644 test/expected/test_sql_str_func.sh_b8ebe81c4881f704624a65ec91be0868c310f6ed.err create mode 100644 test/expected/test_sql_str_func.sh_b8ebe81c4881f704624a65ec91be0868c310f6ed.out create mode 100644 test/expected/test_sql_str_func.sh_cdc7b869132c33cae3c2565806c2396e1b4d6253.err create mode 100644 test/expected/test_sql_str_func.sh_cdc7b869132c33cae3c2565806c2396e1b4d6253.out diff --git a/.github/workflows/bins.yml b/.github/workflows/bins.yml index 8d0d9876..3809811a 100644 --- a/.github/workflows/bins.yml +++ b/.github/workflows/bins.yml @@ -6,6 +6,7 @@ on: - master paths-ignore: - 'docs/**' + - 'test/**' - README.md - NEWS.md - .github/actions/muslbuilder/Dockerfile diff --git a/NEWS.md b/NEWS.md index f275a52e..60120244 100644 --- a/NEWS.md +++ b/NEWS.md @@ -30,6 +30,7 @@ Features: the logs for a container (e.g. `docker://my-container`) or files within a container (e.g. `docker://my-serv/var/log/dpkg.log`). +* Added the SQLite JSON functions to the online help. Bug Fixes: * When piping data into **lnav**'s stdin, the input used to @@ -40,6 +41,13 @@ Bug Fixes: * Binary data piped into stdin should now be treated the same as if it was in a file that was passed on the command-line. +Interface changes: +* The DB view now uses the "alt-text" theme style to draw + alternating rows instead of being hard-coded to bold. The + alternation is also now done in groups of two rows instead + of only a single row. Numbers are also rendered using the + "number" theme style as well. + Breaking changes: * Removed the `-w` command-line option. This option was useful when stdin was not automatically preserved. Since diff --git a/src/base/attr_line.hh b/src/base/attr_line.hh index c9cb6a80..57324fd1 100644 --- a/src/base/attr_line.hh +++ b/src/base/attr_line.hh @@ -133,10 +133,16 @@ struct line_range { return false; } - if (this->lr_end < rhs.lr_end) { + // When the start is the same, the longer range has a lower priority + // than the shorter range. + if (rhs.lr_end == -1) { return false; } - return true; + + if ((this->lr_end == -1) || (this->lr_end > rhs.lr_end)) { + return true; + } + return false; } bool operator==(const struct line_range& rhs) const diff --git a/src/base/attr_line.tests.cc b/src/base/attr_line.tests.cc index 53b338ea..4a19d07e 100644 --- a/src/base/attr_line.tests.cc +++ b/src/base/attr_line.tests.cc @@ -36,6 +36,15 @@ using namespace lnav::roles::literals; +TEST_CASE("line_range") +{ + line_range lr1{0, 95}; + line_range lr2{0, -1}; + + CHECK(lr2 < lr1); + CHECK(!(lr1 < lr2)); +} + TEST_CASE("attr_line_t::basic-wrapping") { text_wrap_settings tws = {3, 21}; diff --git a/src/base/lnav.console.cc b/src/base/lnav.console.cc index a34ebac0..94251d46 100644 --- a/src/base/lnav.console.cc +++ b/src/base/lnav.console.cc @@ -349,6 +349,9 @@ println(FILE* file, const attr_line_t& al) case role_t::VCR_TEXT: case role_t::VCR_IDENTIFIER: break; + case role_t::VCR_ALT_ROW: + line_style |= fmt::emphasis::bold; + break; case role_t::VCR_SEARCH: line_style |= fmt::emphasis::reverse; break; diff --git a/src/curl_looper.hh b/src/curl_looper.hh index 163e22ca..1f4b7df6 100644 --- a/src/curl_looper.hh +++ b/src/curl_looper.hh @@ -94,6 +94,10 @@ public: } } + curl_request(const curl_request&) = delete; + curl_request(curl_request&&) = delete; + void operator=(curl_request&&) = delete; + virtual ~curl_request() = default; const std::string& get_name() const { return this->cr_name; } diff --git a/src/db_sub_source.cc b/src/db_sub_source.cc index 795bda8d..48f4e92d 100644 --- a/src/db_sub_source.cc +++ b/src/db_sub_source.cc @@ -40,7 +40,6 @@ const char db_label_source::NULL_STR[] = ""; -constexpr size_t MAX_COLUMN_WIDTH = 120; constexpr size_t MAX_JSON_WIDTH = 16 * 1024; void @@ -59,11 +58,11 @@ db_label_source::text_value_for_line(textview_curses& tc, return; } for (int lpc = 0; lpc < (int) this->dls_rows[row].size(); lpc++) { - auto actual_col_size - = std::min(MAX_COLUMN_WIDTH, this->dls_headers[lpc].hm_column_size); + auto actual_col_size = std::min(this->dls_max_column_width, + this->dls_headers[lpc].hm_column_size); auto cell_str = scrub_ws(this->dls_rows[row][lpc]); - truncate_to(cell_str, MAX_COLUMN_WIDTH); + truncate_to(cell_str, this->dls_max_column_width); auto cell_length = utf8_string_length(cell_str).unwrapOr(actual_col_size); @@ -91,9 +90,16 @@ db_label_source::text_attrs_for_line(textview_curses& tc, if (row >= (int) this->dls_rows.size()) { return; } + auto alt_row_index = row % 4; + if (alt_row_index == 2 || alt_row_index == 3) { + sa.emplace_back(lr2, VC_ROLE.value(role_t::VCR_ALT_ROW)); + } for (size_t lpc = 0; lpc < this->dls_headers.size() - 1; lpc++) { - if (row % 2 == 0) { - sa.emplace_back(lr2, VC_STYLE.value(text_attrs{A_BOLD})); + const auto& hm = this->dls_headers[lpc]; + + if (hm.hm_graphable) { + lr.lr_end += this->dls_cell_width[lpc]; + sa.emplace_back(lr, VC_ROLE.value(role_t::VCR_NUMBER)); } lr.lr_start += this->dls_cell_width[lpc]; lr.lr_end = lr.lr_start + 1; @@ -412,11 +418,12 @@ db_overlay_source::list_value_for_overlay(const listview_curses& lv, for (size_t lpc = 0; lpc < this->dos_labels->dls_headers.size(); lpc++) { - auto actual_col_size = std::min( - MAX_COLUMN_WIDTH, dls->dls_headers[lpc].hm_column_size); + auto actual_col_size + = std::min(dls->dls_max_column_width, + dls->dls_headers[lpc].hm_column_size); std::string cell_title = dls->dls_headers[lpc].hm_name; - truncate_to(cell_title, MAX_COLUMN_WIDTH); + truncate_to(cell_title, dls->dls_max_column_width); auto cell_length = utf8_string_length(cell_title).unwrapOr(actual_col_size); diff --git a/src/db_sub_source.hh b/src/db_sub_source.hh index d7279893..0078b00e 100644 --- a/src/db_sub_source.hh +++ b/src/db_sub_source.hh @@ -114,6 +114,7 @@ public: text_attrs hm_title_attrs; }; + size_t dls_max_column_width{120}; stacked_bar_chart dls_chart; std::vector dls_headers; std::vector> dls_rows; diff --git a/src/help_text_formatter.cc b/src/help_text_formatter.cc index 0564ba2a..36ad82f0 100644 --- a/src/help_text_formatter.cc +++ b/src/help_text_formatter.cc @@ -500,6 +500,8 @@ format_example_text_for_term(const help_text& ht, ex_line.pad_to(50).with_attr_for_all( VC_ROLE.value(role_t::VCR_QUOTED_CODE)); + auto ex_result + = eval(ht, ex).with_attr_for_all(SA_PREFORMATTED.value()); alb.append("#") .append(fmt::to_string(count)) .append(" ") @@ -510,7 +512,7 @@ format_example_text_for_term(const help_text& ht, .append(ex_line, &tws.with_indent(3).with_padding_indent(3)) .append("\n") .indent(3) - .append(eval(ht, ex), &tws.with_indent(3)) + .append(ex_result, &tws.with_indent(0)) .append("\n"); count += 1; diff --git a/src/internals/sql-ref.rst b/src/internals/sql-ref.rst index 41ff28f1..68e0123a 100644 --- a/src/internals/sql-ref.rst +++ b/src/internals/sql-ref.rst @@ -159,8 +159,8 @@ expr COLLATE *collation-name* .. code-block:: custsqlite ;SELECT ('a2' < 'a10'), ('a2' < 'a10' COLLATE naturalnocase) - ('a2' < 'a10') ('a2' < 'a10' COLLATE naturalnocase) - 0 1 + ('a2' < 'a10') ('a2' <⋯nocase) + 0 1 ---- @@ -677,9 +677,9 @@ avg(*X*) .. code-block:: custsqlite ;SELECT ex_procname, avg(ex_duration) FROM lnav_example_log GROUP BY ex_procname - ex_procname avg(ex_duration) - gw 5 - hw 2 + ex_procname avg(ex_⋯ration) + gw 5 + hw 2 **See Also** :ref:`abs`, :ref:`acos`, :ref:`acosh`, :ref:`asin`, :ref:`asinh`, :ref:`atan2`, :ref:`atan`, :ref:`atanh`, :ref:`atn2`, :ref:`ceil`, :ref:`degrees`, :ref:`exp`, :ref:`floor`, :ref:`log10`, :ref:`log`, :ref:`max`, :ref:`min`, :ref:`pi`, :ref:`power`, :ref:`radians`, :ref:`round`, :ref:`sign`, :ref:`square`, :ref:`sum`, :ref:`total` @@ -1654,7 +1654,7 @@ jget(*json*, *ptr*, *\[default\]*) Hello **See Also** - :ref:`json_concat`, :ref:`json_contains`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`yaml_to_json` + :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` ---- @@ -1704,6 +1704,85 @@ joinpath(*path*) ---- +.. _json: + +json(*X*) +^^^^^^^^^ + + Verifies that its argument is valid JSON and returns a minified version or throws an error. + + **Parameters** + * **X\*** --- The string to interpret as JSON. + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`yaml_to_json` + +---- + + +.. _json_array: + +json_array(*X*) +^^^^^^^^^^^^^^^ + + Constructs a JSON array from its arguments. + + **Parameters** + * **X** --- The values of the JSON array + + **Examples** + To create an array of all types: + + .. code-block:: custsqlite + + ;SELECT json_array(NULL, 1, 2.1, 'three', json_array(4), json_object('five', 'six')) + [null,1,2.1,"three",[4],{"five":"six"}] + + To create an empty array: + + .. code-block:: custsqlite + + ;SELECT json_array() + [] + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_array_length: + +json_array_length(*X*, *\[P\]*) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Returns the length of a JSON array. + + **Parameters** + * **X\*** --- The JSON object. + * **P** --- The path to the array in 'X'. + + **Examples** + To get the length of an array: + + .. code-block:: custsqlite + + ;SELECT json_array_length('[1, 2, 3]') + 3 + + To get the length of a nested array: + + .. code-block:: custsqlite + + ;SELECT json_array_length('{"arr": [1, 2, 3]}', '$.arr') + 3 + + **See Also** + :ref:`jget`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + .. _json_concat: json_concat(*json*, *value*) @@ -1738,7 +1817,7 @@ json_concat(*json*, *value*) [1,2,3,4,5] **See Also** - :ref:`jget`, :ref:`json_contains`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`yaml_to_json` + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` ---- @@ -1770,7 +1849,89 @@ json_contains(*json*, *value*) 1 **See Also** - :ref:`jget`, :ref:`json_concat`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`yaml_to_json` + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_each: + +json_each(*X*, *\[P\]*) +^^^^^^^^^^^^^^^^^^^^^^^ + + A table-valued-function that returns the children of the top-level JSON value + + **Parameters** + * **X\*** --- The JSON value to query + * **P** --- The path to the value to query + + **Examples** + To iterate over an array: + + .. code-block:: custsqlite + + ;SELECT * FROM json_each('[null,1,"two",{"three":4.5}]') + key value type atom id parent fullkey path + 0 null 1 $[0] $ + 1 1 integer 1 2 $[1] $ + 2 two text two 3 $[2] $ + 3 {"three":4.5} object 4 $[3] $ + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_extract: + +json_extract(*X*, *P*) +^^^^^^^^^^^^^^^^^^^^^^ + + Returns the value(s) from the given JSON at the given path(s). + + **Parameters** + * **X\*** --- The JSON value. + * **P** --- The path to extract. + + **Examples** + To get a number: + + .. code-block:: custsqlite + + ;SELECT json_extract('{"num": 1}', '$.num') + 1 + + To get two numbers: + + .. code-block:: custsqlite + + ;SELECT json_extract('{"num": 1, "val": 2}', '$.num', '$.val') + [1,2] + + To get an object: + + .. code-block:: custsqlite + + ;SELECT json_extract('{"obj": {"sub": 1}}', '$.obj') + {"sub":1} + + To get a JSON value using the short-hand: + + .. code-block:: custsqlite + + ;SELECT '{"a":"b"}' -> '$.a' + "b" + + To get a SQL value using the short-hand: + + .. code-block:: custsqlite + + ;SELECT '{"a":"b"}' ->> '$.a' + b + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` ---- @@ -1801,7 +1962,7 @@ json_group_array(*value*) [1,2,3] **See Also** - :ref:`jget`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_group_object`, :ref:`yaml_to_json` + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` ---- @@ -1833,7 +1994,316 @@ json_group_object(*name*, *value*) {"a":1,"b":2} **See Also** - :ref:`jget`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_group_array`, :ref:`yaml_to_json` + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_insert: + +json_insert(*X*, *P*, *Y*) +^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Inserts values into a JSON object/array at the given locations, if it does not already exist + + **Parameters** + * **X\*** --- The JSON value to update + * **P\*** --- The path to the insertion point. A '#' array index means append the value + * **Y\*** --- The value to insert + + **Examples** + To append to an array: + + .. code-block:: custsqlite + + ;SELECT json_insert('[1, 2]', '$[#]', 3) + [1,2,3] + + To update an object: + + .. code-block:: custsqlite + + ;SELECT json_insert('{"a": 1}', '$.b', 2) + {"a":1,"b":2} + + To ensure a value is set: + + .. code-block:: custsqlite + + ;SELECT json_insert('{"a": 1}', '$.a', 2) + {"a":1} + + To update multiple values: + + .. code-block:: custsqlite + + ;SELECT json_insert('{"a": 1}', '$.b', 2, '$.c', 3) + {"a":1,"b":2,"c":3} + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_object: + +json_object(*N*, *V*) +^^^^^^^^^^^^^^^^^^^^^ + + Create a JSON object from the given arguments + + **Parameters** + * **N\*** --- The property name + * **V\*** --- The property value + + **Examples** + To create an object: + + .. code-block:: custsqlite + + ;SELECT json_object('a', 1, 'b', 'c') + {"a":1,"b":"c"} + + To create an empty object: + + .. code-block:: custsqlite + + ;SELECT json_object() + {} + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_quote: + +json_quote(*X*) +^^^^^^^^^^^^^^^ + + Returns the JSON representation of the given value, if it is not already JSON + + **Parameters** + * **X\*** --- The value to convert + + **Examples** + To convert a string: + + .. code-block:: custsqlite + + ;SELECT json_quote('Hello, World!') + "Hello, World!" + + To pass through an existing JSON value: + + .. code-block:: custsqlite + + ;SELECT json_quote(json('"Hello, World!"')) + "Hello, World!" + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_remove: + +json_remove(*X*, *P*) +^^^^^^^^^^^^^^^^^^^^^ + + Removes paths from a JSON value + + **Parameters** + * **X\*** --- The JSON value to update + * **P** --- The paths to remove + + **Examples** + To remove elements of an array: + + .. code-block:: custsqlite + + ;SELECT json_remove('[1,2,3]', '$[1]', '$[1]') + [1] + + To remove object properties: + + .. code-block:: custsqlite + + ;SELECT json_remove('{"a":1,"b":2}', '$.b') + {"a":1} + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_replace: + +json_replace(*X*, *P*, *Y*) +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Replaces existing values in a JSON object/array at the given locations + + **Parameters** + * **X\*** --- The JSON value to update + * **P\*** --- The path to replace + * **Y\*** --- The new value for the property + + **Examples** + To replace an existing value: + + .. code-block:: custsqlite + + ;SELECT json_replace('{"a": 1}', '$.a', 2) + {"a":2} + + To replace a value without creating a new property: + + .. code-block:: custsqlite + + ;SELECT json_replace('{"a": 1}', '$.a', 2, '$.b', 3) + {"a":2} + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_set: + +json_set(*X*, *P*, *Y*) +^^^^^^^^^^^^^^^^^^^^^^^ + + Inserts or replaces existing values in a JSON object/array at the given locations + + **Parameters** + * **X\*** --- The JSON value to update + * **P\*** --- The path to the insertion point. A '#' array index means append the value + * **Y\*** --- The value to set + + **Examples** + To replace an existing array element: + + .. code-block:: custsqlite + + ;SELECT json_set('[1, 2]', '$[1]', 3) + [1,3] + + To replace a value and create a new property: + + .. code-block:: custsqlite + + ;SELECT json_set('{"a": 1}', '$.a', 2, '$.b', 3) + {"a":2,"b":3} + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_tree: + +json_tree(*X*, *\[P\]*) +^^^^^^^^^^^^^^^^^^^^^^^ + + A table-valued-function that recursively descends through a JSON value + + **Parameters** + * **X\*** --- The JSON value to query + * **P** --- The path to the value to query + + **Examples** + To iterate over an array: + + .. code-block:: custsqlite + + ;SELECT key,value,type,atom,fullkey,path FROM json_tree('[null,1,"two",{"three":4.5}]') + key value type atom fullkey path + [null,1⋯":4.5}] array $ $ + 0 null $[0] $ + 1 1 integer 1 $[1] $ + 2 two text two $[2] $ + 3 {"three":4.5} object $[3] $ + three 4.5 real 4.5 $[3].three $[3] + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_type`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_type: + +json_type(*X*, *\[P\]*) +^^^^^^^^^^^^^^^^^^^^^^^ + + Returns the type of a JSON value + + **Parameters** + * **X\*** --- The JSON value to query + * **P** --- The path to the value + + **Examples** + To get the type of a value: + + .. code-block:: custsqlite + + ;SELECT json_type('[null,1,2.1,"three",{"four":5}]') + array + + To get the type of an array element: + + .. code-block:: custsqlite + + ;SELECT json_type('[null,1,2.1,"three",{"four":5}]', '$[0]') + null + + To get the type of a string: + + .. code-block:: custsqlite + + ;SELECT json_type('[null,1,2.1,"three",{"four":5}]', '$[3]') + text + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_valid`, :ref:`json`, :ref:`yaml_to_json` + +---- + + +.. _json_valid: + +json_valid(*X*) +^^^^^^^^^^^^^^^ + + Tests if the given value is valid JSON + + **Parameters** + * **X\*** --- The value to check + + **Examples** + To check an empty string: + + .. code-block:: custsqlite + + ;SELECT json_valid('') + 0 + + To check a string: + + .. code-block:: custsqlite + + ;SELECT json_valid('"a"') + 1 + + **See Also** + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json`, :ref:`yaml_to_json` ---- @@ -2817,9 +3287,9 @@ regexp_capture_into_json(*string*, *pattern*, *\[options\]*) .. code-block:: custsqlite ;SELECT * FROM regexp_capture_into_json('a=1; b=2', '(\w+)=(\d+)') - match_index content - 0 {"col_0":"a","col_1":1} - 1 {"col_0":"b","col_1":2} + match_index content + 0 {"col_0⋯l_1":1} + 1 {"col_0⋯l_1":2} **See Also** :ref:`anonymize`, :ref:`char`, :ref:`charindex`, :ref:`decode`, :ref:`encode`, :ref:`endswith`, :ref:`extract`, :ref:`group_concat`, :ref:`group_spooky_hash_agg`, :ref:`gunzip`, :ref:`gzip`, :ref:`humanize_duration`, :ref:`humanize_file_size`, :ref:`instr`, :ref:`leftstr`, :ref:`length`, :ref:`logfmt2json`, :ref:`lower`, :ref:`ltrim`, :ref:`padc`, :ref:`padl`, :ref:`padr`, :ref:`parse_url`, :ref:`printf`, :ref:`proper`, :ref:`regexp_capture`, :ref:`regexp_match`, :ref:`regexp_replace`, :ref:`replace`, :ref:`replicate`, :ref:`reverse`, :ref:`rightstr`, :ref:`rtrim`, :ref:`sparkline`, :ref:`spooky_hash`, :ref:`startswith`, :ref:`strfilter`, :ref:`substr`, :ref:`trim`, :ref:`unicode`, :ref:`unparse_url`, :ref:`upper`, :ref:`xpath` @@ -3590,19 +4060,19 @@ timeslice(*time*, *slice*) ;SELECT timeslice(log_time_msecs, '5m') AS slice, count(1) FROM lnav_example_log GROUP BY slice - slice count(1) - 2017-02-03 04:05:00.000 2 - 2017-02-03 04:25:00.000 1 - 2017-02-03 04:55:00.000 1 + slice count(1) + 2017-02⋯:00.000 2 + 2017-02⋯:00.000 1 + 2017-02⋯:00.000 1 To group log messages by those before 4:30am and after: .. code-block:: custsqlite ;SELECT timeslice(log_time_msecs, 'before 4:30am') AS slice, count(1) FROM lnav_example_log GROUP BY slice - slice count(1) - 1 - 2017-02-03 00:00:00.000 3 + slice count(1) + 1 + 2017-02⋯:00.000 3 **See Also** :ref:`date`, :ref:`datetime`, :ref:`humanize_duration`, :ref:`julianday`, :ref:`strftime`, :ref:`time`, :ref:`timediff` @@ -3809,9 +4279,9 @@ xpath(*xpath*, *xmldoc*) .. code-block:: custsqlite ;SELECT * FROM xpath('/abc/def', 'HelloBye') - result node_path node_attr node_text - Hello␊ /abc/def[1] {"a":"b"} Hello - Bye␊ /abc/def[2] {} Bye + result node_path node_attr node_text + ␊ /abc/def[1] {"a":"b"} Hello + Bye␊ /abc/def[2] {} Bye To select all 'a' attributes on the path '/abc/def': @@ -3854,7 +4324,7 @@ yaml_to_json(*yaml*) {"abc": "def"} **See Also** - :ref:`jget`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_group_array`, :ref:`json_group_object` + :ref:`jget`, :ref:`json_array_length`, :ref:`json_array`, :ref:`json_concat`, :ref:`json_contains`, :ref:`json_each`, :ref:`json_extract`, :ref:`json_group_array`, :ref:`json_group_object`, :ref:`json_insert`, :ref:`json_object`, :ref:`json_quote`, :ref:`json_remove`, :ref:`json_replace`, :ref:`json_set`, :ref:`json_tree`, :ref:`json_type`, :ref:`json_valid`, :ref:`json` ---- diff --git a/src/lnav.cc b/src/lnav.cc index 6721d437..6ae208aa 100644 --- a/src/lnav.cc +++ b/src/lnav.cc @@ -202,21 +202,23 @@ const std::vector lnav_zoom_strings = { }; static const std::vector DEFAULT_DB_KEY_NAMES = { - "match_index", - "capture_index", "capture_count", - "range_start", - "range_stop", - "inode", + "capture_index", "device", + "id", "inode", + "key", + "match_index", + "parent", + "range_start", + "range_stop", "rowid", "st_dev", + "st_gid", "st_ino", "st_mode", "st_rdev", "st_uid", - "st_gid", }; static auto bound_pollable_supervisor diff --git a/src/sql_util.cc b/src/sql_util.cc index 82e78e45..76b3f734 100644 --- a/src/sql_util.cc +++ b/src/sql_util.cc @@ -462,14 +462,15 @@ schema_foreign_key_list(void* ptr, int ncols, char** colvalues, char** colnames) void dump_sqlite_schema(sqlite3* db, std::string& schema_out) { - struct sqlite_metadata_callbacks schema_sql_meta_callbacks - = {schema_collation_list, - schema_db_list, - schema_table_list, - schema_table_info, - schema_foreign_key_list, - &schema_out, - {}}; + struct sqlite_metadata_callbacks schema_sql_meta_callbacks = { + schema_collation_list, + schema_db_list, + schema_table_list, + schema_table_info, + schema_foreign_key_list, + &schema_out, + {}, + }; walk_sqlite_metadata(db, schema_sql_meta_callbacks); } @@ -1038,7 +1039,8 @@ annotate_sql_statement(attr_line_t& al) &SQL_COMMENT_ATTR, }, { - lnav::pcre2pp::code::from_const(R"(\A(\*|<|>|=|!|\-|\+|\|\|))"), + lnav::pcre2pp::code::from_const( + R"(\A(\*|\->{1,2}|<|>|=|!|\-|\+|\|\|))"), &SQL_OPERATOR_ATTR, }, { diff --git a/src/sqlite-extension-func.cc b/src/sqlite-extension-func.cc index 9d9f2078..fb1e2cf8 100644 --- a/src/sqlite-extension-func.cc +++ b/src/sqlite-extension-func.cc @@ -749,7 +749,209 @@ register_sqlite_funcs(sqlite3* db, sqlite_registration_func_t* reg_funcs) "SELECT value FROM generate_series(10, 14, 2)", }) .with_example({"To count down from five to 1", - "SELECT value FROM generate_series(1, 5, -1)"})}; + "SELECT value FROM generate_series(1, 5, -1)"}), + + help_text("json", + "Verifies that its argument is valid JSON and returns a " + "minified version or throws an error.") + .sql_function() + .with_parameter({"X", "The string to interpret as JSON."}) + .with_tags({"json"}), + + help_text("json_array", "Constructs a JSON array from its arguments.") + .sql_function() + .with_parameter( + help_text{"X", "The values of the JSON array"}.zero_or_more()) + .with_tags({"json"}) + .with_example({"To create an array of all types", + "SELECT json_array(NULL, 1, 2.1, 'three', " + "json_array(4), json_object('five', 'six'))"}) + .with_example({"To create an empty array", "SELECT json_array()"}), + + help_text("json_array_length", "Returns the length of a JSON array.") + .sql_function() + .with_parameter({"X", "The JSON object."}) + .with_parameter( + help_text{"P", "The path to the array in 'X'."}.optional()) + .with_tags({"json"}) + .with_example({"To get the length of an array", + "SELECT json_array_length('[1, 2, 3]')"}) + .with_example( + {"To get the length of a nested array", + "SELECT json_array_length('{\"arr\": [1, 2, 3]}', '$.arr')"}), + + help_text( + "json_extract", + "Returns the value(s) from the given JSON at the given path(s).") + .sql_function() + .with_parameter({"X", "The JSON value."}) + .with_parameter( + help_text{"P", "The path to extract."}.one_or_more()) + .with_tags({"json"}) + .with_example({"To get a number", + R"(SELECT json_extract('{"num": 1}', '$.num'))"}) + .with_example( + {"To get two numbers", + R"(SELECT json_extract('{"num": 1, "val": 2}', '$.num', '$.val'))"}) + .with_example( + {"To get an object", + R"(SELECT json_extract('{"obj": {"sub": 1}}', '$.obj'))"}) +#if SQLITE_VERSION_NUMBER >= 3038000 + .with_example({"To get a JSON value using the short-hand", + R"(SELECT '{"a":"b"}' -> '$.a')"}) + .with_example({"To get a SQL value using the short-hand", + R"(SELECT '{"a":"b"}' ->> '$.a')"}) +#endif + , + + help_text("json_insert", + "Inserts values into a JSON object/array at the given " + "locations, if it does not already exist") + .sql_function() + .with_parameter({"X", "The JSON value to update"}) + .with_parameter({"P", + "The path to the insertion point. A '#' array " + "index means append the value"}) + .with_parameter({"Y", "The value to insert"}) + .with_tags({"json"}) + .with_example({"To append to an array", + R"(SELECT json_insert('[1, 2]', '$[#]', 3))"}) + .with_example({"To update an object", + R"(SELECT json_insert('{"a": 1}', '$.b', 2))"}) + .with_example({"To ensure a value is set", + R"(SELECT json_insert('{"a": 1}', '$.a', 2))"}) + .with_example( + {"To update multiple values", + R"(SELECT json_insert('{"a": 1}', '$.b', 2, '$.c', 3))"}), + + help_text("json_replace", + "Replaces existing values in a JSON object/array at the " + "given locations") + .sql_function() + .with_parameter({"X", "The JSON value to update"}) + .with_parameter({"P", "The path to replace"}) + .with_parameter({"Y", "The new value for the property"}) + .with_tags({"json"}) + .with_example({"To replace an existing value", + R"(SELECT json_replace('{"a": 1}', '$.a', 2))"}) + .with_example( + {"To replace a value without creating a new property", + R"(SELECT json_replace('{"a": 1}', '$.a', 2, '$.b', 3))"}), + + help_text("json_set", + "Inserts or replaces existing values in a JSON object/array " + "at the given locations") + .sql_function() + .with_parameter({"X", "The JSON value to update"}) + .with_parameter({"P", + "The path to the insertion point. A '#' array " + "index means append the value"}) + .with_parameter({"Y", "The value to set"}) + .with_tags({"json"}) + .with_example({"To replace an existing array element", + R"(SELECT json_set('[1, 2]', '$[1]', 3))"}) + .with_example( + {"To replace a value and create a new property", + R"(SELECT json_set('{"a": 1}', '$.a', 2, '$.b', 3))"}), + + help_text("json_object", + "Create a JSON object from the given arguments") + .sql_function() + .with_parameter({"N", "The property name"}) + .with_parameter({"V", "The property value"}) + .with_tags({"json"}) + .with_example( + {"To create an object", "SELECT json_object('a', 1, 'b', 'c')"}) + .with_example( + {"To create an empty object", "SELECT json_object()"}), + + help_text("json_remove", "Removes paths from a JSON value") + .sql_function() + .with_parameter({"X", "The JSON value to update"}) + .with_parameter(help_text{"P", "The paths to remove"}.one_or_more()) + .with_tags({"json"}) + .with_example({"To remove elements of an array", + "SELECT json_remove('[1,2,3]', '$[1]', '$[1]')"}) + .with_example({"To remove object properties", + R"(SELECT json_remove('{"a":1,"b":2}', '$.b'))"}), + + help_text("json_type", "Returns the type of a JSON value") + .sql_function() + .with_parameter({"X", "The JSON value to query"}) + .with_parameter(help_text{"P", "The path to the value"}.optional()) + .with_tags({"json"}) + .with_example( + {"To get the type of a value", + R"(SELECT json_type('[null,1,2.1,"three",{"four":5}]'))"}) + .with_example( + {"To get the type of an array element", + R"(SELECT json_type('[null,1,2.1,"three",{"four":5}]', '$[0]'))"}) + .with_example( + {"To get the type of a string", + R"(SELECT json_type('[null,1,2.1,"three",{"four":5}]', '$[3]'))"}), + + help_text("json_valid", "Tests if the given value is valid JSON") + .sql_function() + .with_parameter({"X", "The value to check"}) + .with_tags({"json"}) + .with_example({"To check an empty string", "SELECT json_valid('')"}) + .with_example({"To check a string", R"(SELECT json_valid('"a"'))"}), + + help_text("json_quote", + "Returns the JSON representation of the given value, if it " + "is not already JSON") + .sql_function() + .with_parameter({"X", "The value to convert"}) + .with_tags({"json"}) + .with_example( + {"To convert a string", "SELECT json_quote('Hello, World!')"}) + .with_example({"To pass through an existing JSON value", + R"(SELECT json_quote(json('"Hello, World!"')))"}), + + help_text("json_each", + "A table-valued-function that returns the children of the " + "top-level JSON value") + .sql_table_valued_function() + .with_parameter({"X", "The JSON value to query"}) + .with_parameter( + help_text{"P", "The path to the value to query"}.optional()) + .with_result({"key", + "The array index for elements of an array or " + "property names of the object"}) + .with_result({"value", "The value for the current element"}) + .with_result({"type", "The type of the current element"}) + .with_result( + {"atom", + "The SQL value of the element, if it is a primitive type"}) + .with_result({"fullkey", "The path to the current element"}) + .with_tags({"json"}) + .with_example( + {"To iterate over an array", + R"(SELECT * FROM json_each('[null,1,"two",{"three":4.5}]'))"}), + + help_text("json_tree", + "A table-valued-function that recursively descends through a " + "JSON value") + .sql_table_valued_function() + .with_parameter({"X", "The JSON value to query"}) + .with_parameter( + help_text{"P", "The path to the value to query"}.optional()) + .with_result({"key", + "The array index for elements of an array or " + "property names of the object"}) + .with_result({"value", "The value for the current element"}) + .with_result({"type", "The type of the current element"}) + .with_result( + {"atom", + "The SQL value of the element, if it is a primitive type"}) + .with_result({"fullkey", "The path to the current element"}) + .with_result({"path", "The path to the container of this element"}) + .with_tags({"json"}) + .with_example( + {"To iterate over an array", + R"(SELECT key,value,type,atom,fullkey,path FROM json_tree('[null,1,"two",{"three":4.5}]'))"}) + + }; if (!help_registration_done) { for (auto& ht : builtin_funcs) { diff --git a/src/themes/monocai.json b/src/themes/monocai.json index 6edb5abc..9f3c50c9 100644 --- a/src/themes/monocai.json +++ b/src/themes/monocai.json @@ -24,8 +24,7 @@ }, "alt-text": { "color": "#f6f6f6", - "background-color": "$black", - "bold": true + "background-color": "#1c1c1c" }, "ok": { "color": "$green", diff --git a/src/view_helpers.cc b/src/view_helpers.cc index a93c04d6..ddb93b77 100644 --- a/src/view_helpers.cc +++ b/src/view_helpers.cc @@ -823,8 +823,10 @@ execute_examples() db_overlay_source& dos = lnav_data.ld_db_overlay; textview_curses& db_tc = lnav_data.ld_views[LNV_DB]; + auto old_width = dls.dls_max_column_width; + dls.dls_max_column_width = 15; for (auto& help_iter : sqlite_function_help) { - struct help_text& ht = *(help_iter.second); + auto& ht = *(help_iter.second); for (auto& ex : ht.ht_example) { std::string alt_msg; @@ -878,6 +880,7 @@ execute_examples() } } } + dls.dls_max_column_width = old_width; dls.clear(); } diff --git a/test/expected/expected.am b/test/expected/expected.am index b92c5612..24548116 100644 --- a/test/expected/expected.am +++ b/test/expected/expected.am @@ -552,6 +552,8 @@ EXPECTED_FILES = \ $(srcdir)/%reldir%/test_sql_anno.sh_0a37c43350ddd7a2d0d75695be32fac083ad04a4.out \ $(srcdir)/%reldir%/test_sql_anno.sh_1151e5b727f6b57070bf2c8f047f1d7e02b803a6.err \ $(srcdir)/%reldir%/test_sql_anno.sh_1151e5b727f6b57070bf2c8f047f1d7e02b803a6.out \ + $(srcdir)/%reldir%/test_sql_anno.sh_1398146cf8b4f074ec8b9752f021cf47d011bebc.err \ + $(srcdir)/%reldir%/test_sql_anno.sh_1398146cf8b4f074ec8b9752f021cf47d011bebc.out \ $(srcdir)/%reldir%/test_sql_anno.sh_1b29488b949c294479aa6054f80a35bc106b454b.err \ $(srcdir)/%reldir%/test_sql_anno.sh_1b29488b949c294479aa6054f80a35bc106b454b.out \ $(srcdir)/%reldir%/test_sql_anno.sh_331a152080d2e278b7cc0a37728eca1ded36ed72.err \ @@ -774,6 +776,8 @@ EXPECTED_FILES = \ $(srcdir)/%reldir%/test_sql_search_table.sh_df0fd242f57a96d40f466493938cda0789a094fa.out \ $(srcdir)/%reldir%/test_sql_search_table.sh_ef9373a76853f345d06234f6e0fe11b5d40da27b.err \ $(srcdir)/%reldir%/test_sql_search_table.sh_ef9373a76853f345d06234f6e0fe11b5d40da27b.out \ + $(srcdir)/%reldir%/test_sql_str_func.sh_00363f89638cb968584afc1ca0a4f52b2cf7a2ae.err \ + $(srcdir)/%reldir%/test_sql_str_func.sh_00363f89638cb968584afc1ca0a4f52b2cf7a2ae.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_005b9365ac99596e539f47c9fe432668c209b21f.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_005b9365ac99596e539f47c9fe432668c209b21f.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_04712488fe50554eb36d3ced80f9a033602f3daa.err \ @@ -788,6 +792,8 @@ EXPECTED_FILES = \ $(srcdir)/%reldir%/test_sql_str_func.sh_129e58679e72f3cc5864812026e49a7917baf3d0.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_151a0fd71ef6837c8cbd8a67e315019b5812b079.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_151a0fd71ef6837c8cbd8a67e315019b5812b079.out \ + $(srcdir)/%reldir%/test_sql_str_func.sh_1a1e07b6f72bce5402037761fa8afd66c05b4c34.err \ + $(srcdir)/%reldir%/test_sql_str_func.sh_1a1e07b6f72bce5402037761fa8afd66c05b4c34.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_1e7362ac3d9690b1b2cfbd320b6129c46ecfbb8a.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_1e7362ac3d9690b1b2cfbd320b6129c46ecfbb8a.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_211c5428db0590795072c31cb116ef35281e02b5.err \ @@ -810,6 +816,8 @@ EXPECTED_FILES = \ $(srcdir)/%reldir%/test_sql_str_func.sh_51766b600fd158a9e0677f6b0fa31b83537b2e5b.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_5203db1a4a81e43a693f339fd26e1ed635da9d5a.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_5203db1a4a81e43a693f339fd26e1ed635da9d5a.out \ + $(srcdir)/%reldir%/test_sql_str_func.sh_57fc889eefb98571ecf3892ad670646613bf13a3.err \ + $(srcdir)/%reldir%/test_sql_str_func.sh_57fc889eefb98571ecf3892ad670646613bf13a3.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_5abe3717393fba14ec510a37b4b94fedc67aae8e.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_5abe3717393fba14ec510a37b4b94fedc67aae8e.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_5e436fbd4efb140600999c5208886a5a57b8a30e.err \ @@ -822,6 +830,8 @@ EXPECTED_FILES = \ $(srcdir)/%reldir%/test_sql_str_func.sh_660288b48d9b30244621d873944938f7ef043976.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_6607c0dd8baff16930eb3e0daf6354af5b50052b.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_6607c0dd8baff16930eb3e0daf6354af5b50052b.out \ + $(srcdir)/%reldir%/test_sql_str_func.sh_68860c50e91cd6c1f2004ee0414a6e930ed42c87.err \ + $(srcdir)/%reldir%/test_sql_str_func.sh_68860c50e91cd6c1f2004ee0414a6e930ed42c87.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_69f5d49e62da48e188bd9d6af4bd3adeb21eb7d1.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_69f5d49e62da48e188bd9d6af4bd3adeb21eb7d1.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_6ac7ab1f90c064944ff66bef5974f050c8227d4b.err \ @@ -878,6 +888,8 @@ EXPECTED_FILES = \ $(srcdir)/%reldir%/test_sql_str_func.sh_b2aafbcaa7befe426d3f9df71c24f16fdc9d2856.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_b81b27abfafbd357d41c407428d41ae0f4bb75e2.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_b81b27abfafbd357d41c407428d41ae0f4bb75e2.out \ + $(srcdir)/%reldir%/test_sql_str_func.sh_b8ebe81c4881f704624a65ec91be0868c310f6ed.err \ + $(srcdir)/%reldir%/test_sql_str_func.sh_b8ebe81c4881f704624a65ec91be0868c310f6ed.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_bac7f6531a2adf70cd1871fb13eab26dff133b7c.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_bac7f6531a2adf70cd1871fb13eab26dff133b7c.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_bfb7088916412360f77683009058b0747784630a.err \ @@ -890,6 +902,8 @@ EXPECTED_FILES = \ $(srcdir)/%reldir%/test_sql_str_func.sh_c9e2f41431bef879364dc37a472ab01f64d89f89.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_cc53348c585ee71a7456157ad6b125689813bafe.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_cc53348c585ee71a7456157ad6b125689813bafe.out \ + $(srcdir)/%reldir%/test_sql_str_func.sh_cdc7b869132c33cae3c2565806c2396e1b4d6253.err \ + $(srcdir)/%reldir%/test_sql_str_func.sh_cdc7b869132c33cae3c2565806c2396e1b4d6253.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_ce9db1dbc2e5fee87247135d17787ff3af014d77.err \ $(srcdir)/%reldir%/test_sql_str_func.sh_ce9db1dbc2e5fee87247135d17787ff3af014d77.out \ $(srcdir)/%reldir%/test_sql_str_func.sh_d3367527118052081a541a660b091f6f495b1c0d.err \ diff --git a/test/expected/test_cli.sh_c69c835a3c43210225cf62564b3e9584c899af20.out b/test/expected/test_cli.sh_c69c835a3c43210225cf62564b3e9584c899af20.out index 8534914d..280d4384 100644 --- a/test/expected/test_cli.sh_c69c835a3c43210225cf62564b3e9584c899af20.out +++ b/test/expected/test_cli.sh_c69c835a3c43210225cf62564b3e9584c899af20.out @@ -1,4 +1,4 @@ +Feb 25 16:20:12 192.168.4.2 haproxy[7]: 87.183.41.77:50187 [25/Feb/2019:16:20:12.325] prod_http_in~ bk_ktest_sonst/nginx_sonst 0/0/1/0/1 200 1859 - - ---- 9/9/0/0/0 0/0 {Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0} {} "GET /media/pi_popup/1.1.0/magnific-popup.css?1550939704 HTTP/1.1" Feb 25 16:20:12 192.168.4.2 haproxy[7]: 95.216.197.33:56224 [25/Feb/2019:16:20:10.111] prod_http_in/sktst2: SSL handshake failure Feb 25 16:20:12 192.168.4.2 haproxy[7]: 87.183.41.77:50189 [25/Feb/2019:16:20:12.331] prod_http_in~ bk_ktest_sonst/nginx_sonst 0/0/1/0/1 200 2496 - - ---- 9/9/0/0/0 0/0 {Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0} {} "GET /media/core/core.css?1550939640 HTTP/1.1" -Feb 25 16:20:12 192.168.4.2 haproxy[7]: 87.183.41.77:50187 [25/Feb/2019:16:20:12.325] prod_http_in~ bk_ktest_sonst/nginx_sonst 0/0/1/0/1 200 1859 - - ---- 9/9/0/0/0 0/0 {Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0} {} "GET /media/pi_popup/1.1.0/magnific-popup.css?1550939704 HTTP/1.1" Feb 25 16:20:12 192.168.4.2 haproxy[7]: 87.183.41.77:50188 [25/Feb/2019:16:20:12.321] prod_http_in~ bk_ktest_sonst/nginx_sonst 0/0/1/0/1 200 5959 - - ---- 9/9/0/0/0 0/0 {Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0} {} "GET /media/pi_fontawesome/css/font-awesome.css?1550939694 HTTP/1.1" diff --git a/test/expected/test_cli.sh_f2e41555f1a5f40f54ce241207af602ed1503a2b.out b/test/expected/test_cli.sh_f2e41555f1a5f40f54ce241207af602ed1503a2b.out index 751c83b4..a32baf64 100644 --- a/test/expected/test_cli.sh_f2e41555f1a5f40f54ce241207af602ed1503a2b.out +++ b/test/expected/test_cli.sh_f2e41555f1a5f40f54ce241207af602ed1503a2b.out @@ -1,2 +1,2 @@ filepath lines  -stdin   4  +stdin   4 diff --git a/test/expected/test_cmds.sh_b6a3bb78e9d60e5e1f5ce5b18e40d2f1662707ab.out b/test/expected/test_cmds.sh_b6a3bb78e9d60e5e1f5ce5b18e40d2f1662707ab.out index 34f7a36a..38f2f79f 100644 --- a/test/expected/test_cmds.sh_b6a3bb78e9d60e5e1f5ce5b18e40d2f1662707ab.out +++ b/test/expected/test_cmds.sh_b6a3bb78e9d60e5e1f5ce5b18e40d2f1662707ab.out @@ -2669,8 +2669,11 @@ For support questions, email: ptr The JSON-Pointer to lookup in the object. default The default value if the value was not found See Also - json_concat(), json_contains(), json_group_array(), - json_group_object(), yaml_to_json() + json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_quote(), + json_remove(), json_replace(), json_set(), json_tree(), json_type(), + json_valid(), yaml_to_json() Examples #1 To get the root of a JSON value: ;SELECT jget('1', '')  @@ -2713,6 +2716,62 @@ For support questions, email: +json(X) +══════════════════════════════════════════════════════════════════════ + Verifies that its argument is valid JSON and returns a minified + version or throws an error. +Parameter + X The string to interpret as JSON. +See Also + jget(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_quote(), + json_remove(), json_replace(), json_set(), json_tree(), json_type(), + json_valid(), yaml_to_json() + +json_array(X, ...) +══════════════════════════════════════════════════════════════════════ + Constructs a JSON array from its arguments. +Parameter + X The values of the JSON array +See Also + jget(), json(), json_array_length(), json_concat(), json_contains(), + json_each(), json_extract(), json_group_array(), json_group_object(), + json_insert(), json_object(), json_quote(), json_remove(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), + yaml_to_json() +Examples +#1 To create an array of all types: + ;SELECT json_array(NULL, 1, 2.1, 'three', json_array(4), json_object('five', 'six')) + + +#2 To create an empty array: + ;SELECT json_array()  + + + +json_array_length(X, [P]) +══════════════════════════════════════════════════════════════════════ + Returns the length of a JSON array. +Parameters + X The JSON object. + P The path to the array in 'X'. +See Also + jget(), json(), json_array(), json_concat(), json_contains(), + json_each(), json_extract(), json_group_array(), json_group_object(), + json_insert(), json_object(), json_quote(), json_remove(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), + yaml_to_json() +Examples +#1 To get the length of an array: + ;SELECT json_array_length('[1, 2, 3]')  + + +#2 To get the length of a nested array: + ;SELECT json_array_length('{"arr": [1, 2, 3]}', '$.arr') + + + json_concat(json, value, ...) ══════════════════════════════════════════════════════════════════════ Returns an array with the given values concatenated onto the end. @@ -2725,7 +2784,10 @@ For support questions, email: json The initial JSON value. value The value(s) to add to the end of the array. See Also - jget(), json_contains(), json_group_array(), json_group_object(), + jget(), json(), json_array(), json_array_length(), json_contains(), + json_each(), json_extract(), json_group_array(), json_group_object(), + json_insert(), json_object(), json_quote(), json_remove(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), yaml_to_json() Examples #1 To append the number 4 to null: @@ -2748,7 +2810,10 @@ For support questions, email: json The JSON value to query. value The value to look for in the first argument See Also - jget(), json_concat(), json_group_array(), json_group_object(), + jget(), json(), json_array(), json_array_length(), json_concat(), + json_each(), json_extract(), json_group_array(), json_group_object(), + json_insert(), json_object(), json_quote(), json_remove(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), yaml_to_json() Examples #1 To test if a JSON array contains the number 4: @@ -2760,13 +2825,77 @@ For support questions, email: +json_each(X, [P]) +══════════════════════════════════════════════════════════════════════ + A table-valued-function that returns the children of the top-level + JSON value +Parameters + X The JSON value to query + P The path to the value to query +Results + key The array index for elements of an array or + property names of the object + value The value for the current element + type The type of the current element + atom The SQL value of the element, if it is a + primitive type + fullkey The path to the current element +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_quote(), + json_remove(), json_replace(), json_set(), json_tree(), json_type(), + json_valid(), yaml_to_json() +Example +#1 To iterate over an array: + ;SELECT * FROM json_each('[null,1,"two",{"three":4.5}]') + + + +json_extract(X, P, ...) +══════════════════════════════════════════════════════════════════════ + Returns the value(s) from the given JSON at the given path(s). +Parameters + X The JSON value. + P The path to extract. +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_group_array(), json_group_object(), + json_insert(), json_object(), json_quote(), json_remove(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), + yaml_to_json() +Examples +#1 To get a number: + ;SELECT json_extract('{"num": 1}', '$.num')  + + +#2 To get two numbers: + ;SELECT json_extract('{"num": 1, "val": 2}', '$.num', '$.val') + + +#3 To get an object: + ;SELECT json_extract('{"obj": {"sub": 1}}', '$.obj') + + +#4 To get a JSON value using the short-hand: + ;SELECT '{"a":"b"}' -> '$.a'  + + +#5 To get a SQL value using the short-hand: + ;SELECT '{"a":"b"}' ->> '$.a'  + + + json_group_array(value, ...) ══════════════════════════════════════════════════════════════════════ Collect the given values from a query into a JSON array Parameter value The values to append to the array See Also - jget(), json_concat(), json_contains(), json_group_object(), + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_object(), + json_insert(), json_object(), json_quote(), json_remove(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), yaml_to_json() Examples #1 To create an array from arguments: @@ -2785,7 +2914,10 @@ For support questions, email: name The property name for the value value The value to add to the object See Also - jget(), json_concat(), json_contains(), json_group_array(), + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_insert(), json_object(), json_quote(), json_remove(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), yaml_to_json() Examples #1 To create an object from arguments: @@ -2797,6 +2929,229 @@ For support questions, email: +json_insert(X, P, Y) +══════════════════════════════════════════════════════════════════════ + Inserts values into a JSON object/array at the given locations, if + it does not already exist +Parameters + X The JSON value to update + P The path to the insertion point. A '#' array index means + append the value + Y The value to insert +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_object(), json_quote(), json_remove(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), + yaml_to_json() +Examples +#1 To append to an array: + ;SELECT json_insert('[1, 2]', '$[#]', 3)  + + +#2 To update an object: + ;SELECT json_insert('{"a": 1}', '$.b', 2)  + + +#3 To ensure a value is set: + ;SELECT json_insert('{"a": 1}', '$.a', 2)  + + +#4 To update multiple values: + ;SELECT json_insert('{"a": 1}', '$.b', 2, '$.c', 3) + + + +json_object(N, V) +══════════════════════════════════════════════════════════════════════ + Create a JSON object from the given arguments +Parameters + N The property name + V The property value +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_quote(), json_remove(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), + yaml_to_json() +Examples +#1 To create an object: + ;SELECT json_object('a', 1, 'b', 'c')  + + +#2 To create an empty object: + ;SELECT json_object()  + + + +json_quote(X) +══════════════════════════════════════════════════════════════════════ + Returns the JSON representation of the given value, if it is not + already JSON +Parameter + X The value to convert +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_remove(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), + yaml_to_json() +Examples +#1 To convert a string: + ;SELECT json_quote('Hello, World!')  + + +#2 To pass through an existing JSON value: + ;SELECT json_quote(json('"Hello, World!"'))  + + + +json_remove(X, P, ...) +══════════════════════════════════════════════════════════════════════ + Removes paths from a JSON value +Parameters + X The JSON value to update + P The paths to remove +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_quote(), + json_replace(), json_set(), json_tree(), json_type(), json_valid(), + yaml_to_json() +Examples +#1 To remove elements of an array: + ;SELECT json_remove('[1,2,3]', '$[1]', '$[1]')  + + +#2 To remove object properties: + ;SELECT json_remove('{"a":1,"b":2}', '$.b')  + + + +json_replace(X, P, Y) +══════════════════════════════════════════════════════════════════════ + Replaces existing values in a JSON object/array at the given + locations +Parameters + X The JSON value to update + P The path to replace + Y The new value for the property +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_quote(), + json_remove(), json_set(), json_tree(), json_type(), json_valid(), + yaml_to_json() +Examples +#1 To replace an existing value: + ;SELECT json_replace('{"a": 1}', '$.a', 2)  + + +#2 To replace a value without creating a new property: + ;SELECT json_replace('{"a": 1}', '$.a', 2, '$.b', 3) + + + +json_set(X, P, Y) +══════════════════════════════════════════════════════════════════════ + Inserts or replaces existing values in a JSON object/array at the + given locations +Parameters + X The JSON value to update + P The path to the insertion point. A '#' array index means + append the value + Y The value to set +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_quote(), + json_remove(), json_replace(), json_tree(), json_type(), json_valid(), + yaml_to_json() +Examples +#1 To replace an existing array element: + ;SELECT json_set('[1, 2]', '$[1]', 3)  + + +#2 To replace a value and create a new property: + ;SELECT json_set('{"a": 1}', '$.a', 2, '$.b', 3)  + + + +json_tree(X, [P]) +══════════════════════════════════════════════════════════════════════ + A table-valued-function that recursively descends through a JSON + value +Parameters + X The JSON value to query + P The path to the value to query +Results + key The array index for elements of an array or + property names of the object + value The value for the current element + type The type of the current element + atom The SQL value of the element, if it is a + primitive type + fullkey The path to the current element + path The path to the container of this element +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_quote(), + json_remove(), json_replace(), json_set(), json_type(), json_valid(), + yaml_to_json() +Example +#1 To iterate over an array: + ;SELECT key,value,type,atom,fullkey,path FROM json_tree('[null,1,"two",{"three":4.5}]') + + + +json_type(X, [P]) +══════════════════════════════════════════════════════════════════════ + Returns the type of a JSON value +Parameters + X The JSON value to query + P The path to the value +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_quote(), + json_remove(), json_replace(), json_set(), json_tree(), json_valid(), + yaml_to_json() +Examples +#1 To get the type of a value: + ;SELECT json_type('[null,1,2.1,"three",{"four":5}]') + + +#2 To get the type of an array element: + ;SELECT json_type('[null,1,2.1,"three",{"four":5}]', '$[0]') + + +#3 To get the type of a string: + ;SELECT json_type('[null,1,2.1,"three",{"four":5}]', '$[3]') + + + +json_valid(X) +══════════════════════════════════════════════════════════════════════ + Tests if the given value is valid JSON +Parameter + X The value to check +See Also + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_quote(), + json_remove(), json_replace(), json_set(), json_tree(), json_type(), + yaml_to_json() +Examples +#1 To check an empty string: + ;SELECT json_valid('')  + + +#2 To check a string: + ;SELECT json_valid('"a"')  + + + julianday(timestring, modifier, ...) ══════════════════════════════════════════════════════════════════════ Returns the number of days since noon in Greenwich on November 24, @@ -4306,8 +4661,11 @@ For support questions, email: Parameter yaml The YAML value to convert to JSON. See Also - jget(), json_concat(), json_contains(), json_group_array(), - json_group_object() + jget(), json(), json_array(), json_array_length(), json_concat(), + json_contains(), json_each(), json_extract(), json_group_array(), + json_group_object(), json_insert(), json_object(), json_quote(), + json_remove(), json_replace(), json_set(), json_tree(), json_type(), + json_valid() Example #1 To convert the document "abc: def": ;SELECT yaml_to_json('abc: def')  diff --git a/test/expected/test_logfile.sh_218ecb88b4753010c4264b3ac351260b4811612f.out b/test/expected/test_logfile.sh_218ecb88b4753010c4264b3ac351260b4811612f.out index 4ed341d9..1a8cc2fb 100644 --- a/test/expected/test_logfile.sh_218ecb88b4753010c4264b3ac351260b4811612f.out +++ b/test/expected/test_logfile.sh_218ecb88b4753010c4264b3ac351260b4811612f.out @@ -1,2 +1,2 @@ basename(filepath)  descriptor  mimetype  content  -logfile_syslog.1.gz net.zlib.gzip.header application/json {"name":"logfile_syslog.1","mtime":"2007-11-03T09:23:00.000","comment":""}  +logfile_syslog.1.gz net.zlib.gzip.header application/json {"name":"logfile_syslog.1","mtime":"2007-11-03T09:23:00.000","comment":""} diff --git a/test/expected/test_logfile.sh_e840b674cd65936a72bd64b1dac1524d16fe44c3.out b/test/expected/test_logfile.sh_e840b674cd65936a72bd64b1dac1524d16fe44c3.out index 9de987f4..a706db24 100644 --- a/test/expected/test_logfile.sh_e840b674cd65936a72bd64b1dac1524d16fe44c3.out +++ b/test/expected/test_logfile.sh_e840b674cd65936a72bd64b1dac1524d16fe44c3.out @@ -1,11 +1,11 @@  log_time  log_body  -2022-09-19 09:24:04.000 tid:1d1f - Mux ID not found in mapping dictionary  +2022-09-19 09:24:04.000 tid:1d1f - Mux ID not found in mapping dictionary 2022-09-19 09:24:04.000 tid:1d1f - Can't handle disconnect with invalid ecid 2022-09-19 09:24:20.000 Entered:_AMMuxedDeviceDisconnected, mux-device:1003  -2022-09-19 09:24:20.000 Entered:_AMMuxedDeviceDisconnected, mux-device:1003 -2022-09-19 09:24:20.000 Entered:__thr_AMMuxedDeviceDisconnected, mux-device:1003  +2022-09-19 09:24:20.000 Entered:_AMMuxedDeviceDisconnected, mux-device:1003  +2022-09-19 09:24:20.000 Entered:__thr_AMMuxedDeviceDisconnected, mux-device:1003 2022-09-19 09:24:20.000 Entered:__thr_AMMuxedDeviceDisconnected, mux-device:1003 2022-09-19 09:24:20.000 tid:191f - Mux ID not found in mapping dictionary  -2022-09-19 09:24:20.000 tid:1d1f - Mux ID not found in mapping dictionary -2022-09-19 09:24:20.000 tid:191f - Can't handle disconnect with invalid ecid  +2022-09-19 09:24:20.000 tid:1d1f - Mux ID not found in mapping dictionary  +2022-09-19 09:24:20.000 tid:191f - Can't handle disconnect with invalid ecid 2022-09-19 09:24:20.000 tid:1d1f - Can't handle disconnect with invalid ecid diff --git a/test/expected/test_meta.sh_c75128169049bd88d5eaf8b84a7f617e5ae5d936.out b/test/expected/test_meta.sh_c75128169049bd88d5eaf8b84a7f617e5ae5d936.out index 8462ae33..f7f674dc 100644 --- a/test/expected/test_meta.sh_c75128169049bd88d5eaf8b84a7f617e5ae5d936.out +++ b/test/expected/test_meta.sh_c75128169049bd88d5eaf8b84a7f617e5ae5d936.out @@ -1,4 +1,4 @@ log_line  log_comment log_tags  - 0 Hello, World! ["#foo"]  + 0 Hello, World! ["#foo"] 1  2 <NULL>  <NULL>  diff --git a/test/expected/test_sql.sh_13429aed81d7edfd47b57e9cdb8a25c43aff35c4.out b/test/expected/test_sql.sh_13429aed81d7edfd47b57e9cdb8a25c43aff35c4.out index 4acb940c..d726804a 100644 --- a/test/expected/test_sql.sh_13429aed81d7edfd47b57e9cdb8a25c43aff35c4.out +++ b/test/expected/test_sql.sh_13429aed81d7edfd47b57e9cdb8a25c43aff35c4.out @@ -1,2 +1,2 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters  c_ip cs_bytes cs_method cs_uri_query  cs_uri_stem cs_username cs_vars cs_version s_app s_core s_pid s_req s_runtime s_switches s_worker_reqs sc_bytes sc_header_bytes sc_headers sc_status  - 0   2016-03-13 22:49:12.000  0 info   0       127.0.0.1  696 POST    /update_metrics     38 HTTP/1.1  0   3  88185  1  0.129  1  1  47  378  9    200  + 0   2016-03-13 22:49:12.000  0 info   0       127.0.0.1  696 POST    /update_metrics     38 HTTP/1.1  0   3  88185  1  0.129  1  1  47  378  9    200 diff --git a/test/expected/test_sql.sh_1cbb81cfe40ee16332c5c775a74d06b945aa65c2.out b/test/expected/test_sql.sh_1cbb81cfe40ee16332c5c775a74d06b945aa65c2.out index df0e6d78..33dc71f3 100644 --- a/test/expected/test_sql.sh_1cbb81cfe40ee16332c5c775a74d06b945aa65c2.out +++ b/test/expected/test_sql.sh_1cbb81cfe40ee16332c5c775a74d06b945aa65c2.out @@ -1,3 +1,3 @@ id first_name last_name age  - 0 Phil  Myman   30  + 0 Phil Myman 30  1 Lem  Hewitt   35 diff --git a/test/expected/test_sql.sh_2f15b8a38673ac4db45dc6ed2eafe609c332575b.out b/test/expected/test_sql.sh_2f15b8a38673ac4db45dc6ed2eafe609c332575b.out index df0e6d78..33dc71f3 100644 --- a/test/expected/test_sql.sh_2f15b8a38673ac4db45dc6ed2eafe609c332575b.out +++ b/test/expected/test_sql.sh_2f15b8a38673ac4db45dc6ed2eafe609c332575b.out @@ -1,3 +1,3 @@ id first_name last_name age  - 0 Phil  Myman   30  + 0 Phil Myman 30  1 Lem  Hewitt   35 diff --git a/test/expected/test_sql.sh_8ee288f1508eaab0367e465e9f382e848f3282aa.out b/test/expected/test_sql.sh_8ee288f1508eaab0367e465e9f382e848f3282aa.out index b21f574e..fcd872b0 100644 --- a/test/expected/test_sql.sh_8ee288f1508eaab0367e465e9f382e848f3282aa.out +++ b/test/expected/test_sql.sh_8ee288f1508eaab0367e465e9f382e848f3282aa.out @@ -1,4 +1,4 @@  log_time  2009-07-20 22:59:26.000 2009-07-20 22:59:29.000 -2009-07-20 22:59:29.000 +2009-07-20 22:59:29.000  diff --git a/test/expected/test_sql.sh_afe9cdc4898df5c4e112c13dfe3db6dc089c0d7c.out b/test/expected/test_sql.sh_afe9cdc4898df5c4e112c13dfe3db6dc089c0d7c.out index 43828023..475b78eb 100644 --- a/test/expected/test_sql.sh_afe9cdc4898df5c4e112c13dfe3db6dc089c0d7c.out +++ b/test/expected/test_sql.sh_afe9cdc4898df5c4e112c13dfe3db6dc089c0d7c.out @@ -1,4 +1,4 @@  log_body  lookup(file): lookup for foobar failed attempting to mount entry /auto/opt -lookup(file): lookup for opt failed +lookup(file): lookup for opt failed  diff --git a/test/expected/test_sql.sh_b085d26043f9661d70f82cb90ecb3c5245d25eac.out b/test/expected/test_sql.sh_b085d26043f9661d70f82cb90ecb3c5245d25eac.out index b21f574e..fcd872b0 100644 --- a/test/expected/test_sql.sh_b085d26043f9661d70f82cb90ecb3c5245d25eac.out +++ b/test/expected/test_sql.sh_b085d26043f9661d70f82cb90ecb3c5245d25eac.out @@ -1,4 +1,4 @@  log_time  2009-07-20 22:59:26.000 2009-07-20 22:59:29.000 -2009-07-20 22:59:29.000 +2009-07-20 22:59:29.000  diff --git a/test/expected/test_sql.sh_bad03a996c0750733ab99c592b9011851f521a69.out b/test/expected/test_sql.sh_bad03a996c0750733ab99c592b9011851f521a69.out index 85a13033..eb543d54 100644 --- a/test/expected/test_sql.sh_bad03a996c0750733ab99c592b9011851f521a69.out +++ b/test/expected/test_sql.sh_bad03a996c0750733ab99c592b9011851f521a69.out @@ -1,5 +1,5 @@ match_index  content  case match_index when 2 then replicate('abc', 1000) else '' end  -  0 {"col_0":10}   +  0 {"col_0":10}  1 {"col_0":50}    2 {"col_0":50} abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc⋯bcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc  - 3 {"col_0":50}   + 3 {"col_0":50}   diff --git a/test/expected/test_sql.sh_c353ef036c505b75996252138fbd4c8d22e8149c.out b/test/expected/test_sql.sh_c353ef036c505b75996252138fbd4c8d22e8149c.out index b21f574e..fcd872b0 100644 --- a/test/expected/test_sql.sh_c353ef036c505b75996252138fbd4c8d22e8149c.out +++ b/test/expected/test_sql.sh_c353ef036c505b75996252138fbd4c8d22e8149c.out @@ -1,4 +1,4 @@  log_time  2009-07-20 22:59:26.000 2009-07-20 22:59:29.000 -2009-07-20 22:59:29.000 +2009-07-20 22:59:29.000  diff --git a/test/expected/test_sql.sh_c5b8da04734fadf3b9eea80e0af997e38e0fb811.out b/test/expected/test_sql.sh_c5b8da04734fadf3b9eea80e0af997e38e0fb811.out index 86a4d5ad..8baf896a 100644 --- a/test/expected/test_sql.sh_c5b8da04734fadf3b9eea80e0af997e38e0fb811.out +++ b/test/expected/test_sql.sh_c5b8da04734fadf3b9eea80e0af997e38e0fb811.out @@ -1,3 +1,3 @@ log_line  col_0  - 0 eth0.IPv4  + 0 eth0.IPv4 7 eth0.IPv4 diff --git a/test/expected/test_sql_anno.sh_1398146cf8b4f074ec8b9752f021cf47d011bebc.err b/test/expected/test_sql_anno.sh_1398146cf8b4f074ec8b9752f021cf47d011bebc.err new file mode 100644 index 00000000..e69de29b diff --git a/test/expected/test_sql_anno.sh_1398146cf8b4f074ec8b9752f021cf47d011bebc.out b/test/expected/test_sql_anno.sh_1398146cf8b4f074ec8b9752f021cf47d011bebc.out new file mode 100644 index 00000000..7d0d0833 --- /dev/null +++ b/test/expected/test_sql_anno.sh_1398146cf8b4f074ec8b9752f021cf47d011bebc.out @@ -0,0 +1,9 @@ + SELECT json_object('abc', 'def') ->> '$.abc' + sql_keyword ------ + sql_func ------------------------ + sql_ident ----------- + sql_string ----- + sql_comma - + sql_string ----- + sql_oper --- + sql_string ------- diff --git a/test/expected/test_sql_indexes.sh_1614ebb5e2e83bab11023354dea8a0885ddf64b4.out b/test/expected/test_sql_indexes.sh_1614ebb5e2e83bab11023354dea8a0885ddf64b4.out index 71790218..f41df2b4 100644 --- a/test/expected/test_sql_indexes.sh_1614ebb5e2e83bab11023354dea8a0885ddf64b4.out +++ b/test/expected/test_sql_indexes.sh_1614ebb5e2e83bab11023354dea8a0885ddf64b4.out @@ -1,3 +1,3 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters log_msg_format  -  1  <NULL> 2009-07-20 22:59:29.000  3000 error   0  <NULL>  <NULL>  <NULL>   - 3   2013-02-15 06:00:31.000  112777262000 error   0         +  1 2009-07-20 22:59:29.000  3000 error 0 + 3   2013-02-15 06:00:31.000  112777262000 error   0         diff --git a/test/expected/test_sql_indexes.sh_541a8e35f34a206e340a3880128b6ce137847872.out b/test/expected/test_sql_indexes.sh_541a8e35f34a206e340a3880128b6ce137847872.out index 54677790..d7d1a39a 100644 --- a/test/expected/test_sql_indexes.sh_541a8e35f34a206e340a3880128b6ce137847872.out +++ b/test/expected/test_sql_indexes.sh_541a8e35f34a206e340a3880128b6ce137847872.out @@ -1,5 +1,5 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters  c_ip cs_method cs_referer cs_uri_query  cs_uri_stem cs_user_agent cs_username cs_version sc_bytes sc_status cs_host  log_unique_path  -  0  <NULL> 2009-07-20 22:59:26.000  0 info   0  <NULL>  <NULL>  <NULL> 192.168.202.254 GET  -   <NULL> /vmw/cgi/tramp  gPXE/0.9.7  -  HTTP/1.0   134  200  <NULL> logfile_access_log.0  -   1 2009-07-20 22:59:29.000 3000 error 0 192.168.202.254 GET - /vmw/vSphere/default/vmkboot.gz gPXE/0.9.7 - HTTP/1.0 46210 404 logfile_access_log.0 +  0 2009-07-20 22:59:26.000  0 info 0 192.168.202.254 GET - /vmw/cgi/tramp gPXE/0.9.7 - HTTP/1.0  134 200 logfile_access_log.0 +   1 2009-07-20 22:59:29.000  3000 error 0 192.168.202.254 GET - /vmw/vSphere/default/vmkboot.gz gPXE/0.9.7 - HTTP/1.0  46210 404 logfile_access_log.0   2  <NULL> 2009-07-20 22:59:29.000  0 info   0  <NULL>  <NULL>  <NULL> 192.168.202.254 GET  -   <NULL> /vmw/vSphere/default/vmkernel.gz gPXE/0.9.7  -  HTTP/1.0   78929  200  <NULL> logfile_access_log.0  - 3   2013-02-15 06:00:31.000  112777262000 error   0       10.112.81.15    -      -  -     0  400   logfile_access_log.1 + 3   2013-02-15 06:00:31.000  112777262000 error   0       10.112.81.15    -      -  -     0  400   logfile_access_log.1  diff --git a/test/expected/test_sql_indexes.sh_59a1497c13a5e09bc8f95ef02552b2835ebea6e5.out b/test/expected/test_sql_indexes.sh_59a1497c13a5e09bc8f95ef02552b2835ebea6e5.out index 823c4d06..69652847 100644 --- a/test/expected/test_sql_indexes.sh_59a1497c13a5e09bc8f95ef02552b2835ebea6e5.out +++ b/test/expected/test_sql_indexes.sh_59a1497c13a5e09bc8f95ef02552b2835ebea6e5.out @@ -1,2 +1,2 @@ $id $parent $notused  replace($detail, 'SCAN TABLE', 'SCAN')  - 2  0  0 SCAN all_logs VIRTUAL TABLE INDEX 1:SEARCH all_logs USING log_level < ?  + 2  0  0 SCAN all_logs VIRTUAL TABLE INDEX 1:SEARCH all_logs USING log_level < ? diff --git a/test/expected/test_sql_indexes.sh_69fd19d56a8cd1fc9c7eb9351270eabb491f8233.out b/test/expected/test_sql_indexes.sh_69fd19d56a8cd1fc9c7eb9351270eabb491f8233.out index cb2aac6e..71c1cd1a 100644 --- a/test/expected/test_sql_indexes.sh_69fd19d56a8cd1fc9c7eb9351270eabb491f8233.out +++ b/test/expected/test_sql_indexes.sh_69fd19d56a8cd1fc9c7eb9351270eabb491f8233.out @@ -1,5 +1,5 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters log_msg_format log_format  - 0  <NULL> 2009-07-20 22:59:26.000  0 info   0  <NULL>  <NULL>  <NULL>   access_log  -  1 2009-07-20 22:59:29.000 3000 error 0 access_log + 0 2009-07-20 22:59:26.000  0 info 0 access_log +  1 2009-07-20 22:59:29.000  3000 error 0 access_log  2  <NULL> 2009-07-20 22:59:29.000  0 info   0  <NULL>  <NULL>  <NULL>   access_log  - 3   2013-02-15 06:00:31.000  112777262000 error   0         access_log + 3   2013-02-15 06:00:31.000  112777262000 error   0         access_log  diff --git a/test/expected/test_sql_indexes.sh_6f707b6e856dbaab6f95e7e89b98dc3652021f85.out b/test/expected/test_sql_indexes.sh_6f707b6e856dbaab6f95e7e89b98dc3652021f85.out index ee488053..80b16e57 100644 --- a/test/expected/test_sql_indexes.sh_6f707b6e856dbaab6f95e7e89b98dc3652021f85.out +++ b/test/expected/test_sql_indexes.sh_6f707b6e856dbaab6f95e7e89b98dc3652021f85.out @@ -1,3 +1,3 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters log_msg_format  - 0  <NULL> 2009-07-20 22:59:26.000  0 info   0  <NULL>  <NULL>  <NULL>   - 2 2009-07-20 22:59:29.000 0 info 0 + 0 2009-07-20 22:59:26.000  0 info 0 + 2 2009-07-20 22:59:29.000  0 info 0 diff --git a/test/expected/test_sql_indexes.sh_b615b6737b1e0d383c8ce4a1db56332f11dbc158.out b/test/expected/test_sql_indexes.sh_b615b6737b1e0d383c8ce4a1db56332f11dbc158.out index 2a919853..4fd7768f 100644 --- a/test/expected/test_sql_indexes.sh_b615b6737b1e0d383c8ce4a1db56332f11dbc158.out +++ b/test/expected/test_sql_indexes.sh_b615b6737b1e0d383c8ce4a1db56332f11dbc158.out @@ -1,2 +1,2 @@ $id $parent $notused  replace($detail, 'SCAN TABLE', 'SCAN')  - 2  0  0 SCAN all_logs VIRTUAL TABLE INDEX 1:SEARCH all_logs USING log_format = ?  + 2  0  0 SCAN all_logs VIRTUAL TABLE INDEX 1:SEARCH all_logs USING log_format = ? diff --git a/test/expected/test_sql_indexes.sh_dab07d8de7728752ae938a174468d75e85f3ae7e.out b/test/expected/test_sql_indexes.sh_dab07d8de7728752ae938a174468d75e85f3ae7e.out index 82958af0..4365b627 100644 --- a/test/expected/test_sql_indexes.sh_dab07d8de7728752ae938a174468d75e85f3ae7e.out +++ b/test/expected/test_sql_indexes.sh_dab07d8de7728752ae938a174468d75e85f3ae7e.out @@ -1,2 +1,2 @@ $id $parent $notused  replace($detail, 'SCAN TABLE', 'SCAN')  - 2  0  0 SCAN access_log VIRTUAL TABLE INDEX 1:SEARCH access_log USING log_path GLOB ?  + 2  0  0 SCAN access_log VIRTUAL TABLE INDEX 1:SEARCH access_log USING log_path GLOB ? diff --git a/test/expected/test_sql_indexes.sh_f7681c234d4f60df16c997a05163aeb058c52870.out b/test/expected/test_sql_indexes.sh_f7681c234d4f60df16c997a05163aeb058c52870.out index 16c7c375..219fbe6f 100644 --- a/test/expected/test_sql_indexes.sh_f7681c234d4f60df16c997a05163aeb058c52870.out +++ b/test/expected/test_sql_indexes.sh_f7681c234d4f60df16c997a05163aeb058c52870.out @@ -1,5 +1,5 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters log_msg_format  - 0  <NULL> 2009-07-20 22:59:26.000  0 info   0  <NULL>  <NULL>  <NULL>   -  1 2009-07-20 22:59:29.000 3000 error 0 + 0 2009-07-20 22:59:26.000  0 info 0 +  1 2009-07-20 22:59:29.000  3000 error 0  2  <NULL> 2009-07-20 22:59:29.000  0 info   0  <NULL>  <NULL>  <NULL>   - 3   2013-02-15 06:00:31.000  112777262000 error   0         + 3   2013-02-15 06:00:31.000  112777262000 error   0          diff --git a/test/expected/test_sql_regexp.sh_03257c56e85558aa0cc925b68d3af962afc25125.out b/test/expected/test_sql_regexp.sh_03257c56e85558aa0cc925b68d3af962afc25125.out index 19aa1c4a..ec3e6da0 100644 --- a/test/expected/test_sql_regexp.sh_03257c56e85558aa0cc925b68d3af962afc25125.out +++ b/test/expected/test_sql_regexp.sh_03257c56e85558aa0cc925b68d3af962afc25125.out @@ -1,4 +1,4 @@ match_index capture_index capture_name capture_count range_start range_stop content  - 0  0  <NULL>  3  1  9 abc=def;  + 0 0 3 1 9 abc=def; 0 1 3 1 4 abc  0  2  <NULL>  3  5  8 def  diff --git a/test/expected/test_sql_regexp.sh_51293df041b6969ccecc60204dce3676d0fb006d.out b/test/expected/test_sql_regexp.sh_51293df041b6969ccecc60204dce3676d0fb006d.out index 49171831..41755254 100644 --- a/test/expected/test_sql_regexp.sh_51293df041b6969ccecc60204dce3676d0fb006d.out +++ b/test/expected/test_sql_regexp.sh_51293df041b6969ccecc60204dce3676d0fb006d.out @@ -1,2 +1,2 @@ match_index  content  - 0 {"key":"foo","value":4670}  + 0 {"key":"foo","value":4670} diff --git a/test/expected/test_sql_regexp.sh_bbd1128cf61a9af8f9dc937b46217443f42e1a7a.out b/test/expected/test_sql_regexp.sh_bbd1128cf61a9af8f9dc937b46217443f42e1a7a.out index 655ce134..bd9b924b 100644 --- a/test/expected/test_sql_regexp.sh_bbd1128cf61a9af8f9dc937b46217443f42e1a7a.out +++ b/test/expected/test_sql_regexp.sh_bbd1128cf61a9af8f9dc937b46217443f42e1a7a.out @@ -1,2 +1,2 @@ match_index  content  - 0 {"key":"foo","value":"123e"}  + 0 {"key":"foo","value":"123e"} diff --git a/test/expected/test_sql_regexp.sh_d61af17ff19d640ddfc879460910991825eedd05.out b/test/expected/test_sql_regexp.sh_d61af17ff19d640ddfc879460910991825eedd05.out index 6e952fb6..44e3b675 100644 --- a/test/expected/test_sql_regexp.sh_d61af17ff19d640ddfc879460910991825eedd05.out +++ b/test/expected/test_sql_regexp.sh_d61af17ff19d640ddfc879460910991825eedd05.out @@ -1,2 +1,2 @@ match_index  content  - 0 {"col_0":"abc","col_1":"def"}  + 0 {"col_0":"abc","col_1":"def"} diff --git a/test/expected/test_sql_regexp.sh_ed6e9f13f178def009ee58c2aeea8c3c70fdb580.out b/test/expected/test_sql_regexp.sh_ed6e9f13f178def009ee58c2aeea8c3c70fdb580.out index fef8e264..170662d1 100644 --- a/test/expected/test_sql_regexp.sh_ed6e9f13f178def009ee58c2aeea8c3c70fdb580.out +++ b/test/expected/test_sql_regexp.sh_ed6e9f13f178def009ee58c2aeea8c3c70fdb580.out @@ -1,2 +1,2 @@ match_index  content  - 0 {"key":"foo","value":"0x123e"}  + 0 {"key":"foo","value":"0x123e"} diff --git a/test/expected/test_sql_search_table.sh_1a0d872ebc492fcecb2e79a0993170d5fc771a5b.out b/test/expected/test_sql_search_table.sh_1a0d872ebc492fcecb2e79a0993170d5fc771a5b.out index d56bc20e..4f98b588 100644 --- a/test/expected/test_sql_search_table.sh_1a0d872ebc492fcecb2e79a0993170d5fc771a5b.out +++ b/test/expected/test_sql_search_table.sh_1a0d872ebc492fcecb2e79a0993170d5fc771a5b.out @@ -1,2 +1,2 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters  comp  opid  tid  user  item prc reason  req  sid  src  sub vpxa_update  line  file match_index  lro_id  entity  operation  SessionId  SessionSubId  - 2   2022-06-02 11:58:12.376  182 info   0        e3979f6 45709   vpxd    Originator@6876 vpxLro      0 lro-846064 SessionManager vim.SessionManager.sessionIsActive 52626140-422b-6287-b4e4-344192c6a01d 523e0a4b-6e83-6bcd-9342-22502dd89866  + 2   2022-06-02 11:58:12.376  182 info   0        e3979f6 45709   vpxd    Originator@6876 vpxLro      0 lro-846064 SessionManager vim.SessionManager.sessionIsActive 52626140-422b-6287-b4e4-344192c6a01d 523e0a4b-6e83-6bcd-9342-22502dd89866 diff --git a/test/expected/test_sql_search_table.sh_3f5f74863d065418bca5a000e6ad3d9344635164.out b/test/expected/test_sql_search_table.sh_3f5f74863d065418bca5a000e6ad3d9344635164.out index c92cf49d..de8fa5ca 100644 --- a/test/expected/test_sql_search_table.sh_3f5f74863d065418bca5a000e6ad3d9344635164.out +++ b/test/expected/test_sql_search_table.sh_3f5f74863d065418bca5a000e6ad3d9344635164.out @@ -1,12 +1,12 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters match_index  name  - 2   2022-08-16 00:32:15.000  199000 info   0        0 com.apple.cdscheduler  - 5 2022-08-16 00:32:15.000 0 info 0 0 com.apple.install + 2   2022-08-16 00:32:15.000  199000 info   0        0 com.apple.cdscheduler + 5 2022-08-16 00:32:15.000  0 info 0 0 com.apple.install  8  <NULL> 2022-08-16 00:32:15.000  0 info   0  <NULL>  <NULL>  <NULL>  0 com.apple.authd  - 8 2022-08-16 00:32:15.000 0 info 0 1 com.apple.asl - 8  <NULL> 2022-08-16 00:32:15.000  0 info   0  <NULL>  <NULL>  <NULL>  2 com.apple.asl  - 8 2022-08-16 00:32:15.000 0 info 0 3 com.apple.authd + 8  <NULL> 2022-08-16 00:32:15.000  0 info   0  <NULL>  <NULL>  <NULL>  1 com.apple.asl  + 8 2022-08-16 00:32:15.000  0 info 0 2 com.apple.asl + 8 2022-08-16 00:32:15.000  0 info 0 3 com.apple.authd  11  <NULL> 2022-08-16 00:32:15.000  0 info   0  <NULL>  <NULL>  <NULL>  0 com.apple.authd  - 11 2022-08-16 00:32:15.000 0 info 0 1 com.apple.asl - 11  <NULL> 2022-08-16 00:32:15.000  0 info   0  <NULL>  <NULL>  <NULL>  2 com.apple.asl  - 11 2022-08-16 00:32:15.000 0 info 0 3 com.apple.authd + 11  <NULL> 2022-08-16 00:32:15.000  0 info   0  <NULL>  <NULL>  <NULL>  1 com.apple.asl  + 11 2022-08-16 00:32:15.000  0 info 0 2 com.apple.asl + 11 2022-08-16 00:32:15.000  0 info 0 3 com.apple.authd  14  <NULL> 2022-08-16 00:32:15.000  0 info   0  <NULL>  <NULL>  <NULL>  0 com.apple.authd  diff --git a/test/expected/test_sql_search_table.sh_5aaae556ecb1661602f176215e28f661d3404032.out b/test/expected/test_sql_search_table.sh_5aaae556ecb1661602f176215e28f661d3404032.out index 738eab3c..57c09f16 100644 --- a/test/expected/test_sql_search_table.sh_5aaae556ecb1661602f176215e28f661d3404032.out +++ b/test/expected/test_sql_search_table.sh_5aaae556ecb1661602f176215e28f661d3404032.out @@ -1,4 +1,4 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters match_index user pid cpu_pct mem_pct vsz rss tty stat start_time cpu_time  cmd  cmd_name cmd_args  - 0  <NULL> 2022-06-02 00:01:01.000  0 info   0  <NULL>  <NULL>  <NULL>  1 root  2  0  0  0  0 ?  S  Jun01  0:00  [kthreadd] [kthreadd]  <NULL>  - 12   2022-06-02 00:02:01.000  60000 info   0        1 root  2  0  0  0  0 ?  S  Jun01  0:00  [kthreadd] [kthreadd]  + 0 2022-06-02 00:01:01.000  0 info 0 1 root 2  0  0  0  0 ? S Jun01 0:00 [kthreadd] [kthreadd] + 12   2022-06-02 00:02:01.000  60000 info   0        1 root  2  0  0  0  0 ?  S  Jun01  0:00  [kthreadd] [kthreadd]   30   2022-06-02 00:03:01.000  60000 info   0        1 root  2  0  0  0  0 ?  S  Jun01  0:00  [kthreadd] [kthreadd]   diff --git a/test/expected/test_sql_search_table.sh_df0fd242f57a96d40f466493938cda0789a094fa.out b/test/expected/test_sql_search_table.sh_df0fd242f57a96d40f466493938cda0789a094fa.out index 326fcbda..c19446b6 100644 --- a/test/expected/test_sql_search_table.sh_df0fd242f57a96d40f466493938cda0789a094fa.out +++ b/test/expected/test_sql_search_table.sh_df0fd242f57a96d40f466493938cda0789a094fa.out @@ -1,24 +1,24 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters match_index user pid cpu_pct mem_pct  vsz rss tty stat start_time cpu_time  cmd  cmd_name  cmd_args  - 0   2022-06-02 00:01:01.000  0 info   0        0 root  1  0  0 158392 7792 ?  Ss  Jun01  0:14  /lib/systemd/systemd --switched-root --system --deserialize 16 /lib/systemd/systemd  --switched-root --system --deserialize 16  - 0 2022-06-02 00:01:01.000 0 info 0 1 root 2 0 0 0 0 ? S Jun01 0:00 [kthreadd] [kthreadd] + 0   2022-06-02 00:01:01.000  0 info   0        0 root  1  0  0 158392 7792 ?  Ss  Jun01  0:14  /lib/systemd/systemd --switched-root --system --deserialize 16 /lib/systemd/systemd --switched-root --system --deserialize 16 + 0 2022-06-02 00:01:01.000  0 info 0 1 root 2  0  0  0  0 ? S Jun01 0:00 [kthreadd] [kthreadd]  0  <NULL> 2022-06-02 00:01:01.000  0 info   0  <NULL>  <NULL>  <NULL>  2 root  3  0  0  0  0 ?  I<  Jun01  0:00  [rcu_gp]  [rcu_gp]  <NULL>  - 0 2022-06-02 00:01:01.000 0 info 0 3 root 4 0 0 0 0 ? I< Jun01 0:00 [rcu_par_gp] [rcu_par_gp] - 0  <NULL> 2022-06-02 00:01:01.000  0 info   0  <NULL>  <NULL>  <NULL>  4 root  6  0  0  0  0 ?  I<  Jun01  0:00  [kworker/0:0H-kblockd]  [kworker/0:0H-kblockd] <NULL>  - 12   2022-06-02 00:02:01.000  60000 info   0  <NULL>      0 root  1  0  0 158392 7792 ?  Ss  Jun01  0:14  /lib/systemd/systemd --switched-root --system --deserialize 16 /lib/systemd/systemd  --switched-root --system --deserialize 16 + 0  <NULL> 2022-06-02 00:01:01.000  0 info   0  <NULL>  <NULL>  <NULL>  3 root  4  0  0  0  0 ?  I<  Jun01  0:00  [rcu_par_gp]  [rcu_par_gp]  <NULL>  + 0 2022-06-02 00:01:01.000  0 info 0 4 root 6  0  0  0  0 ? I< Jun01 0:00 [kworker/0:0H-kblockd] [kworker/0:0H-kblockd] + 12   2022-06-02 00:02:01.000  60000 info   0  <NULL>      0 root  1  0  0 158392 7792 ?  Ss  Jun01  0:14  /lib/systemd/systemd --switched-root --system --deserialize 16 /lib/systemd/systemd  --switched-root --system --deserialize 16  12   2022-06-02 00:02:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  1 root  2  0  0  0  0 ?  S  Jun01  0:00  [kthreadd]  [kthreadd]  <NULL>  - 12   2022-06-02 00:02:01.000  60000 info   0  <NULL> 2 root 3 0 0 0 0 ? I< Jun01 0:00 [rcu_gp] [rcu_gp] - 12   2022-06-02 00:02:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  3 root  4  0  0  0  0 ?  I<  Jun01  0:00  [rcu_par_gp]  [rcu_par_gp]  <NULL>  - 12   2022-06-02 00:02:01.000  60000 info   0  <NULL> 4 root 6 0 0 0 0 ? I< Jun01 0:00 [kworker/0:0H-kblockd] [kworker/0:0H-kblockd] + 12   2022-06-02 00:02:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  2 root  3  0  0  0  0 ?  I<  Jun01  0:00  [rcu_gp]  [rcu_gp]  <NULL>  + 12   2022-06-02 00:02:01.000  60000 info   0  <NULL> 3 root 4  0  0  0  0 ? I< Jun01 0:00 [rcu_par_gp] [rcu_par_gp] + 12   2022-06-02 00:02:01.000  60000 info   0  <NULL> 4 root 6  0  0  0  0 ? I< Jun01 0:00 [kworker/0:0H-kblockd] [kworker/0:0H-kblockd]  12   2022-06-02 00:02:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  5 root  8  0  0  0  0 ?  I<  Jun01  0:00  [mm_percpu_wq]  [mm_percpu_wq]  <NULL>  - 12   2022-06-02 00:02:01.000  60000 info   0  <NULL> 6 root 9 0 0 0 0 ? S Jun01 0:00 [ksoftirqd/0] [ksoftirqd/0] - 12   2022-06-02 00:02:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  7 root  10  0  0  0  0 ?  I  Jun01  0:23  [rcu_sched]  [rcu_sched]  <NULL>  - 12   2022-06-02 00:02:01.000  60000 info   0  <NULL> 8 root 11 0 0 0 0 ? I Jun01 0:00 [rcu_bh] [rcu_bh] + 12   2022-06-02 00:02:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  6 root  9  0  0  0  0 ?  S  Jun01  0:00  [ksoftirqd/0]  [ksoftirqd/0]  <NULL>  + 12   2022-06-02 00:02:01.000  60000 info   0  <NULL> 7 root 10  0  0  0  0 ? I Jun01 0:23 [rcu_sched] [rcu_sched] + 12   2022-06-02 00:02:01.000  60000 info   0  <NULL> 8 root 11  0  0  0  0 ? I Jun01 0:00 [rcu_bh] [rcu_bh]  12   2022-06-02 00:02:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  9 root  12  0  0  0  0 ?  S  Jun01  0:00  [migration/0]  [migration/0]  <NULL>  - 12   2022-06-02 00:02:01.000  60000 info   0  <NULL> 10 root 14 0 0 0 0 ? S Jun01 0:00 [cpuhp/0] [cpuhp/0] - 30   2022-06-02 00:03:01.000  60000 info   0  <NULL>      0 root  1  0  0 158392 7792 ?  Ss  Jun01  0:14  /lib/systemd/systemd --switched-root --system --deserialize 16 /lib/systemd/systemd  --switched-root --system --deserialize 16  - 30   2022-06-02 00:03:01.000  60000 info   0  <NULL> 1 root 2 0 0 0 0 ? S Jun01 0:00 [kthreadd] [kthreadd] + 12   2022-06-02 00:02:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  10 root  14  0  0  0  0 ?  S  Jun01  0:00  [cpuhp/0]  [cpuhp/0]  <NULL>  + 30   2022-06-02 00:03:01.000  60000 info   0  <NULL>      0 root  1  0  0 158392 7792 ?  Ss  Jun01  0:14  /lib/systemd/systemd --switched-root --system --deserialize 16 /lib/systemd/systemd  --switched-root --system --deserialize 16 + 30   2022-06-02 00:03:01.000  60000 info   0  <NULL> 1 root 2  0  0  0  0 ? S Jun01 0:00 [kthreadd] [kthreadd]  30   2022-06-02 00:03:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  2 root  3  0  0  0  0 ?  I<  Jun01  0:00  [rcu_gp]  [rcu_gp]  <NULL>  - 30   2022-06-02 00:03:01.000  60000 info   0  <NULL> 3 root 4 0 0 0 0 ? I< Jun01 0:00 [rcu_par_gp] [rcu_par_gp] - 30   2022-06-02 00:03:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  4 root  6  0  0  0  0 ?  I<  Jun01  0:00  [kworker/0:0H-kblockd]  [kworker/0:0H-kblockd] <NULL>  - 30   2022-06-02 00:03:01.000  60000 info   0  <NULL> 5 root 8 0 0 0 0 ? I< Jun01 0:00 [mm_percpu_wq] [mm_percpu_wq] + 30   2022-06-02 00:03:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  3 root  4  0  0  0  0 ?  I<  Jun01  0:00  [rcu_par_gp]  [rcu_par_gp]  <NULL>  + 30   2022-06-02 00:03:01.000  60000 info   0  <NULL> 4 root 6  0  0  0  0 ? I< Jun01 0:00 [kworker/0:0H-kblockd] [kworker/0:0H-kblockd] + 30   2022-06-02 00:03:01.000  60000 info   0  <NULL> 5 root 8  0  0  0  0 ? I< Jun01 0:00 [mm_percpu_wq] [mm_percpu_wq]  30   2022-06-02 00:03:01.000  60000 info   0  <NULL>  <NULL>  <NULL>  6 root  9  0  0  0  0 ?  S  Jun01  0:00  [ksoftirqd/0]  [ksoftirqd/0]  <NULL>  diff --git a/test/expected/test_sql_search_table.sh_ef9373a76853f345d06234f6e0fe11b5d40da27b.out b/test/expected/test_sql_search_table.sh_ef9373a76853f345d06234f6e0fe11b5d40da27b.out index 767d7855..1f72be6c 100644 --- a/test/expected/test_sql_search_table.sh_ef9373a76853f345d06234f6e0fe11b5d40da27b.out +++ b/test/expected/test_sql_search_table.sh_ef9373a76853f345d06234f6e0fe11b5d40da27b.out @@ -1,6 +1,6 @@ log_line log_part  log_time log_idle_msecs log_level log_mark log_comment log_tags log_filters  comp  opid  tid  user  item prc reason  req  sid  src  sub vpxa_update  line  file match_index  lro_id  entity  operation  SessionId  SessionSubId  log_body  - 0  <NULL> 2022-06-02 11:58:12.193  0 info   0  <NULL>  <NULL>  <NULL> <NULL> 7e1280cf  45715 <NULL> <NULL> vpxd <NULL> <NULL> <NULL> Originator@6876 vpxLro  <NULL> <NULL> <NULL>  0 lro-846063 SessionManager  vim.SessionManager.sessionIsActive  528e6e0c-246d-58b5-3234-278c6e0c5d0d 52c289ac-2563-48d5-8a8e-f178da022c0d [VpxLRO] -- BEGIN lro-846063 -- SessionManager -- vim.Sessio⋯8b5-3234-278c6e0c5d0d(52c289ac-2563-48d5-8a8e-f178da022c0d)  - 2   2022-06-02 11:58:12.376  182 info   0        e3979f6  45709   vpxd    Originator@6876 vpxLro      0 lro-846064 SessionManager  vim.SessionManager.sessionIsActive  52626140-422b-6287-b4e4-344192c6a01d 523e0a4b-6e83-6bcd-9342-22502dd89866 [VpxLRO] -- BEGIN lro-846064 -- SessionManager -- vim.Sessio⋯287-b4e4-344192c6a01d(523e0a4b-6e83-6bcd-9342-22502dd89866) + 0 2022-06-02 11:58:12.193  0 info 0 7e1280cf 45715 vpxd Originator@6876 vpxLro 0 lro-846063 SessionManager vim.SessionManager.sessionIsActive 528e6e0c-246d-58b5-3234-278c6e0c5d0d 52c289ac-2563-48d5-8a8e-f178da022c0d [VpxLRO] -- BEGIN lro-846063 -- SessionManager -- vim.Sessio⋯8b5-3234-278c6e0c5d0d(52c289ac-2563-48d5-8a8e-f178da022c0d) + 2   2022-06-02 11:58:12.376  182 info   0        e3979f6  45709   vpxd    Originator@6876 vpxLro      0 lro-846064 SessionManager  vim.SessionManager.sessionIsActive  52626140-422b-6287-b4e4-344192c6a01d 523e0a4b-6e83-6bcd-9342-22502dd89866 [VpxLRO] -- BEGIN lro-846064 -- SessionManager -- vim.Sessio⋯287-b4e4-344192c6a01d(523e0a4b-6e83-6bcd-9342-22502dd89866)  4   2022-06-02 11:58:12.623  246 info   0        l3wrhr4o-cbf-h5:70001034-60 47524   vpxd    Originator@6876 vpxLro      0 lro-846066 ChangeLogCollector vim.cdc.ChangeLogCollector.waitForChanges 526861fc-0c28-1930-ae5e-d8c2772bf8c2 52a7a308-9646-c054-f1e7-16131c1a7db6 [VpxLRO] -- BEGIN lro-846066 -- ChangeLogCollector -- vim.c⋯1930-ae5e-d8c2772bf8c2(52a7a308-9646-c054-f1e7-16131c1a7db6)  - 6   2022-06-02 11:58:12.736  113 info   0        499b440  48432   vpxd    Originator@6876 vpxLro      0 lro-846067 SessionManager vim.SessionManager.sessionIsActive 521fe9f6-d061-11a2-ac86-badb3c071373 524cba9b-2cc4-9b70-32e4-421452a404d7 [VpxLRO] -- BEGIN lro-846067 -- SessionManager -- vim.Sessio⋯1a2-ac86-badb3c071373(524cba9b-2cc4-9b70-32e4-421452a404d7) - 8  <NULL> 2022-06-02 11:58:12.740  4 info   0  <NULL>  <NULL>  <NULL> <NULL> 55a419df  48035 <NULL> <NULL> vpxd <NULL> <NULL> <NULL> Originator@6876 vpxLro  <NULL> <NULL> <NULL>  0 lro-846068 SessionManager  vim.SessionManager.sessionIsActive  52585600-b0bc-76b1-c4d5-4d7708671c5e 523b68ba-e312-9909-a3ca-39cc86aaf206 [VpxLRO] -- BEGIN lro-846068 -- SessionManager -- vim.Sessio⋯6b1-c4d5-4d7708671c5e(523b68ba-e312-9909-a3ca-39cc86aaf206)  + 6   2022-06-02 11:58:12.736  113 info   0        499b440  48432   vpxd    Originator@6876 vpxLro      0 lro-846067 SessionManager  vim.SessionManager.sessionIsActive  521fe9f6-d061-11a2-ac86-badb3c071373 524cba9b-2cc4-9b70-32e4-421452a404d7 [VpxLRO] -- BEGIN lro-846067 -- SessionManager -- vim.Sessio⋯1a2-ac86-badb3c071373(524cba9b-2cc4-9b70-32e4-421452a404d7)  + 8  2022-06-02 11:58:12.740  4 info 0 55a419df 48035 vpxd Originator@6876 vpxLro 0 lro-846068 SessionManager vim.SessionManager.sessionIsActive 52585600-b0bc-76b1-c4d5-4d7708671c5e 523b68ba-e312-9909-a3ca-39cc86aaf206 [VpxLRO] -- BEGIN lro-846068 -- SessionManager -- vim.Sessio⋯6b1-c4d5-4d7708671c5e(523b68ba-e312-9909-a3ca-39cc86aaf206) diff --git a/test/expected/test_sql_str_func.sh_00363f89638cb968584afc1ca0a4f52b2cf7a2ae.err b/test/expected/test_sql_str_func.sh_00363f89638cb968584afc1ca0a4f52b2cf7a2ae.err new file mode 100644 index 00000000..e69de29b diff --git a/test/expected/test_sql_str_func.sh_00363f89638cb968584afc1ca0a4f52b2cf7a2ae.out b/test/expected/test_sql_str_func.sh_00363f89638cb968584afc1ca0a4f52b2cf7a2ae.out new file mode 100644 index 00000000..2bc40878 --- /dev/null +++ b/test/expected/test_sql_str_func.sh_00363f89638cb968584afc1ca0a4f52b2cf7a2ae.out @@ -0,0 +1,2 @@ +Row 0: + Column parse_url('https://example.com/sea%26rch?flag&flag2&=def&flag3=abc+def#frag1%20space'): {"scheme":"https","username":null,"password":null,"host":"example.com","port":null,"path":"/sea&rch","query":"flag&flag2&=def&flag3=abc+def","parameters":{"flag":null,"flag2":null,"":"def","flag3":"abc def"},"fragment":"frag1 space"} diff --git a/test/expected/test_sql_str_func.sh_1a1e07b6f72bce5402037761fa8afd66c05b4c34.err b/test/expected/test_sql_str_func.sh_1a1e07b6f72bce5402037761fa8afd66c05b4c34.err new file mode 100644 index 00000000..f196e016 --- /dev/null +++ b/test/expected/test_sql_str_func.sh_1a1e07b6f72bce5402037761fa8afd66c05b4c34.err @@ -0,0 +1 @@ +error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"unexpected JSON value","attrs":[]},"reason":{"str":"","attrs":[]},"snippets":[{"source":"arg","line":1,"content":{"str":"123","attrs":[{"start":0,"end":-1,"type":"role","value":40}]}}],"help":{"str":"Available Properties\n scheme \n username \n password \n host \n port \n path \n query \n parameters/ \n fragment","attrs":[{"start":0,"end":20,"type":"role","value":59},{"start":23,"end":29,"type":"role","value":47},{"start":33,"end":41,"type":"role","value":47},{"start":45,"end":53,"type":"role","value":47},{"start":57,"end":61,"type":"role","value":47},{"start":65,"end":69,"type":"role","value":47},{"start":73,"end":77,"type":"role","value":47},{"start":81,"end":86,"type":"role","value":47},{"start":90,"end":100,"type":"role","value":47},{"start":100,"end":101,"type":"role","value":47},{"start":105,"end":113,"type":"role","value":47}]}} diff --git a/test/expected/test_sql_str_func.sh_1a1e07b6f72bce5402037761fa8afd66c05b4c34.out b/test/expected/test_sql_str_func.sh_1a1e07b6f72bce5402037761fa8afd66c05b4c34.out new file mode 100644 index 00000000..e69de29b diff --git a/test/expected/test_sql_str_func.sh_57fc889eefb98571ecf3892ad670646613bf13a3.err b/test/expected/test_sql_str_func.sh_57fc889eefb98571ecf3892ad670646613bf13a3.err new file mode 100644 index 00000000..7370dfc6 --- /dev/null +++ b/test/expected/test_sql_str_func.sh_57fc889eefb98571ecf3892ad670646613bf13a3.err @@ -0,0 +1 @@ +error: sqlite3_exec failed -- lnav-error:{"level":"warning","message":{"str":"unexpected value for property “/unknown”","attrs":[{"start":33,"end":41,"type":"role","value":47}]},"reason":{"str":"","attrs":[]},"snippets":[{"source":"arg","line":1,"content":{"str":"{\"unknown\":\"abc\"}","attrs":[{"start":0,"end":-1,"type":"role","value":40}]}}],"help":{"str":"Available Properties\n scheme \n username \n password \n host \n port \n path \n query \n parameters/ \n fragment","attrs":[{"start":0,"end":20,"type":"role","value":59},{"start":23,"end":29,"type":"role","value":47},{"start":33,"end":41,"type":"role","value":47},{"start":45,"end":53,"type":"role","value":47},{"start":57,"end":61,"type":"role","value":47},{"start":65,"end":69,"type":"role","value":47},{"start":73,"end":77,"type":"role","value":47},{"start":81,"end":86,"type":"role","value":47},{"start":90,"end":100,"type":"role","value":47},{"start":100,"end":101,"type":"role","value":47},{"start":105,"end":113,"type":"role","value":47}]}} diff --git a/test/expected/test_sql_str_func.sh_57fc889eefb98571ecf3892ad670646613bf13a3.out b/test/expected/test_sql_str_func.sh_57fc889eefb98571ecf3892ad670646613bf13a3.out new file mode 100644 index 00000000..e69de29b diff --git a/test/expected/test_sql_str_func.sh_68860c50e91cd6c1f2004ee0414a6e930ed42c87.err b/test/expected/test_sql_str_func.sh_68860c50e91cd6c1f2004ee0414a6e930ed42c87.err new file mode 100644 index 00000000..ff2b58b1 --- /dev/null +++ b/test/expected/test_sql_str_func.sh_68860c50e91cd6c1f2004ee0414a6e930ed42c87.err @@ -0,0 +1 @@ +error: sqlite3_exec failed -- lnav-error:{"level":"warning","message":{"str":"unexpected value for property “/#”","attrs":[{"start":33,"end":35,"type":"role","value":47}]},"reason":{"str":"","attrs":[]},"snippets":[{"source":"arg","line":1,"content":{"str":"[1, 2, 3]","attrs":[{"start":0,"end":-1,"type":"role","value":40}]}}],"help":{"str":"Available Properties\n scheme \n username \n password \n host \n port \n path \n query \n parameters/ \n fragment","attrs":[{"start":0,"end":20,"type":"role","value":59},{"start":23,"end":29,"type":"role","value":47},{"start":33,"end":41,"type":"role","value":47},{"start":45,"end":53,"type":"role","value":47},{"start":57,"end":61,"type":"role","value":47},{"start":65,"end":69,"type":"role","value":47},{"start":73,"end":77,"type":"role","value":47},{"start":81,"end":86,"type":"role","value":47},{"start":90,"end":100,"type":"role","value":47},{"start":100,"end":101,"type":"role","value":47},{"start":105,"end":113,"type":"role","value":47}]}} diff --git a/test/expected/test_sql_str_func.sh_68860c50e91cd6c1f2004ee0414a6e930ed42c87.out b/test/expected/test_sql_str_func.sh_68860c50e91cd6c1f2004ee0414a6e930ed42c87.out new file mode 100644 index 00000000..e69de29b diff --git a/test/expected/test_sql_str_func.sh_b8ebe81c4881f704624a65ec91be0868c310f6ed.err b/test/expected/test_sql_str_func.sh_b8ebe81c4881f704624a65ec91be0868c310f6ed.err new file mode 100644 index 00000000..e69de29b diff --git a/test/expected/test_sql_str_func.sh_b8ebe81c4881f704624a65ec91be0868c310f6ed.out b/test/expected/test_sql_str_func.sh_b8ebe81c4881f704624a65ec91be0868c310f6ed.out new file mode 100644 index 00000000..18df1743 --- /dev/null +++ b/test/expected/test_sql_str_func.sh_b8ebe81c4881f704624a65ec91be0868c310f6ed.out @@ -0,0 +1,2 @@ +Row 0: + Column unparse_url(NULL): (null) diff --git a/test/expected/test_sql_str_func.sh_cdc7b869132c33cae3c2565806c2396e1b4d6253.err b/test/expected/test_sql_str_func.sh_cdc7b869132c33cae3c2565806c2396e1b4d6253.err new file mode 100644 index 00000000..e69de29b diff --git a/test/expected/test_sql_str_func.sh_cdc7b869132c33cae3c2565806c2396e1b4d6253.out b/test/expected/test_sql_str_func.sh_cdc7b869132c33cae3c2565806c2396e1b4d6253.out new file mode 100644 index 00000000..269441a4 --- /dev/null +++ b/test/expected/test_sql_str_func.sh_cdc7b869132c33cae3c2565806c2396e1b4d6253.out @@ -0,0 +1,2 @@ +Row 0: + Column unparse_url('{}'): (null) diff --git a/test/expected/test_sql_views_vtab.sh_62d15cb9d5a9259f198aa01ca8ed200d6da38d68.out b/test/expected/test_sql_views_vtab.sh_62d15cb9d5a9259f198aa01ca8ed200d6da38d68.out index 48f52f39..3a2b3dcd 100644 --- a/test/expected/test_sql_views_vtab.sh_62d15cb9d5a9259f198aa01ca8ed200d6da38d68.out +++ b/test/expected/test_sql_views_vtab.sh_62d15cb9d5a9259f198aa01ca8ed200d6da38d68.out @@ -1,3 +1,3 @@ view_name filter_id enabled type language pattern  -log   1  1 in  regex  vmk  -log   2    1 in regex vmk1 +log  1  1 in regex vmk +log   2    1 in regex vmk1 diff --git a/test/expected/test_sql_views_vtab.sh_81dc3eb51ec4dc3066a2365524001242c423a9cf.out b/test/expected/test_sql_views_vtab.sh_81dc3eb51ec4dc3066a2365524001242c423a9cf.out index c99c7512..a94d8904 100644 --- a/test/expected/test_sql_views_vtab.sh_81dc3eb51ec4dc3066a2365524001242c423a9cf.out +++ b/test/expected/test_sql_views_vtab.sh_81dc3eb51ec4dc3066a2365524001242c423a9cf.out @@ -1,2 +1,2 @@ view_name filter_id enabled type language pattern  -log   0  1 out  sql  1   +log   0  1 out  sql  1  diff --git a/test/expected/test_sql_views_vtab.sh_a2c0f0e51b3f85ea2a05ecdcacaad962b4fe5d4f.out b/test/expected/test_sql_views_vtab.sh_a2c0f0e51b3f85ea2a05ecdcacaad962b4fe5d4f.out index 38afb7c1..31f2111f 100644 --- a/test/expected/test_sql_views_vtab.sh_a2c0f0e51b3f85ea2a05ecdcacaad962b4fe5d4f.out +++ b/test/expected/test_sql_views_vtab.sh_a2c0f0e51b3f85ea2a05ecdcacaad962b4fe5d4f.out @@ -1,2 +1,2 @@ view_name filter_id enabled type language pattern  -log   1  1 in  regex  vmk  +log  1  1 in regex vmk diff --git a/test/expected/test_text_file.sh_8b2cd055e6a1db2ed9b2af2a917f8556395fa653.out b/test/expected/test_text_file.sh_8b2cd055e6a1db2ed9b2af2a917f8556395fa653.out index c8719bb2..0ef4c309 100644 --- a/test/expected/test_text_file.sh_8b2cd055e6a1db2ed9b2af2a917f8556395fa653.out +++ b/test/expected/test_text_file.sh_8b2cd055e6a1db2ed9b2af2a917f8556395fa653.out @@ -1,2 +1,2 @@  filepath  descriptor  mimetype  content  -{test_dir}/textfile_0.md net.daringfireball.markdown.frontmatter application/json {␊ "comment": "This is JSON front-matter"␊}  +{test_dir}/textfile_0.md net.daringfireball.markdown.frontmatter application/json {␊ "comment": "This is JSON front-matter"␊} diff --git a/test/test_sql_anno.sh b/test/test_sql_anno.sh index e09c3125..8c26fe8a 100644 --- a/test/test_sql_anno.sh +++ b/test/test_sql_anno.sh @@ -48,3 +48,5 @@ run_cap_test ./drive_sql_anno \ "SELECT * from vmw_log, regexp_capture(log_body, '--> /SessionStats/SessionPool/Session/(?[abc]+)')" run_cap_test ./drive_sql_anno "SELECT * FROM foo.bar" + +run_cap_test ./drive_sql_anno "SELECT json_object('abc', 'def') ->> '$.abc'" diff --git a/test/test_sql_str_func.sh b/test/test_sql_str_func.sh index a455a1b7..f1068727 100644 --- a/test/test_sql_str_func.sh +++ b/test/test_sql_str_func.sh @@ -145,6 +145,10 @@ run_cap_test env TEST_COMMENT=parse_url6 ./drive_sql <<'EOF' SELECT parse_url('https://example.com/sea%26rch?flag&flag2&=def#frag1%20space') EOF +run_cap_test env TEST_COMMENT=parse_url7 ./drive_sql <<'EOF' +SELECT parse_url('https://example.com/sea%26rch?flag&flag2&=def&flag3=abc+def#frag1%20space') +EOF + run_cap_test env TEST_COMMENT=unparse_url3 ./drive_sql <<'EOF' SELECT unparse_url(parse_url('https://example.com/search?flag')) @@ -162,6 +166,26 @@ run_cap_test env TEST_COMMENT=unparse_url6 ./drive_sql <<'EOF' SELECT unparse_url(parse_url('https://example.com/search?flag&flag2&=def#frag1%20space')) EOF +run_cap_test env TEST_COMMENT=unparse_url7 ./drive_sql <<'EOF' +SELECT unparse_url(NULL) +EOF + +run_cap_test env TEST_COMMENT=unparse_url8 ./drive_sql <<'EOF' +SELECT unparse_url(123) +EOF + +run_cap_test env TEST_COMMENT=unparse_url9 ./drive_sql <<'EOF' +SELECT unparse_url('[1, 2, 3]') +EOF + +run_cap_test env TEST_COMMENT=unparse_url10 ./drive_sql <<'EOF' +SELECT unparse_url(json_object('unknown', 'abc')) +EOF + +run_cap_test env TEST_COMMENT=unparse_url11 ./drive_sql <<'EOF' +SELECT unparse_url('{}') +EOF + run_cap_test ${lnav_test} -n \ -c ';SELECT log_body, extract(log_body) from vmw_log' \ -c ':write-json-to -' \