mirror of https://github.com/tstack/lnav.git
[sql] jget() is not returning values with the right sqlite type
This commit is contained in:
parent
7252e5fc0f
commit
f6e245c04a
1
NEWS
1
NEWS
|
@ -24,6 +24,7 @@ lnav v0.10.1:
|
|||
* The tab for the "Files" panel will be highlighted in red if there
|
||||
is an issue opening a file.
|
||||
* Overwritten files should be reloaded again.
|
||||
* The "jget()" SQL function now returns numbers with the correct type.
|
||||
|
||||
lnav v0.10.0:
|
||||
Features:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# aminclude_static.am generated automatically by Autoconf
|
||||
# from AX_AM_MACROS_STATIC on Wed Sep 8 14:08:11 PDT 2021
|
||||
# from AX_AM_MACROS_STATIC on Thu Sep 9 16:09:09 PDT 2021
|
||||
|
||||
|
||||
# Code coverage
|
||||
|
|
|
@ -681,16 +681,15 @@ bool handle_paging_key(int ch)
|
|||
|
||||
case 'I':
|
||||
{
|
||||
auto &hs = lnav_data.ld_hist_source2;
|
||||
auto &hist_tc = lnav_data.ld_views[LNV_HISTOGRAM];
|
||||
|
||||
if (toggle_view(&hist_tc)) {
|
||||
auto *src_view = dynamic_cast<text_time_translator *>(tc->get_sub_source());
|
||||
|
||||
if (src_view != nullptr) {
|
||||
src_view->time_for_row(tc->get_top()) | [&hs, &hist_tc](auto log_top) {
|
||||
hs.row_for_time(log_top) | [&hist_tc](auto row) {
|
||||
hist_tc.set_top(row);
|
||||
src_view->time_for_row(tc->get_top()) | [](auto log_top) {
|
||||
lnav_data.ld_hist_source2.row_for_time(log_top) | [](auto row) {
|
||||
lnav_data.ld_views[LNV_HISTOGRAM].set_top(row);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -700,6 +699,7 @@ bool handle_paging_key(int ch)
|
|||
auto *dst_view = dynamic_cast<text_time_translator *>(top_tc->get_sub_source());
|
||||
|
||||
if (dst_view != nullptr) {
|
||||
auto& hs = lnav_data.ld_hist_source2;
|
||||
auto hist_top_time_opt = hs.time_for_row(hist_tc.get_top());
|
||||
auto curr_top_time_opt = dst_view->time_for_row(top_tc->get_top());
|
||||
if (hist_top_time_opt && curr_top_time_opt &&
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "vtab_module.hh"
|
||||
#include "vtab_module_json.hh"
|
||||
|
||||
#include "lnav_util.hh"
|
||||
#include "yajl/api/yajl_gen.h"
|
||||
#include "sqlite-extension-func.hh"
|
||||
|
||||
|
@ -53,11 +54,12 @@ using namespace mapbox;
|
|||
|
||||
class sql_json_op : public json_op {
|
||||
public:
|
||||
sql_json_op(json_ptr &ptr) : json_op(ptr), sjo_type(-1), sjo_int(0) { };
|
||||
sql_json_op(json_ptr &ptr) : json_op(ptr) { };
|
||||
|
||||
int sjo_type;
|
||||
int sjo_type{-1};
|
||||
string sjo_str;
|
||||
int sjo_int;
|
||||
int64_t sjo_int{0};
|
||||
double sjo_float{0.0};
|
||||
};
|
||||
|
||||
static void null_or_default(sqlite3_context *context, int argc, sqlite3_value **argv)
|
||||
|
@ -172,6 +174,28 @@ static int gen_handle_string(void *ctx, const unsigned char * stringVal, size_t
|
|||
return sjo->jo_ptr_error_code == yajl_gen_status_ok;
|
||||
}
|
||||
|
||||
static int gen_handle_number(void *ctx, const char *numval, size_t numlen)
|
||||
{
|
||||
sql_json_op *sjo = (sql_json_op *)ctx;
|
||||
yajl_gen gen = (yajl_gen)sjo->jo_ptr_data;
|
||||
|
||||
if (sjo->jo_ptr.jp_state == json_ptr::MS_DONE) {
|
||||
if (strtonum(sjo->sjo_int, numval, numlen) == numlen) {
|
||||
sjo->sjo_type = SQLITE_INTEGER;
|
||||
} else {
|
||||
auto numstr = std::string(numval, numlen);
|
||||
|
||||
sjo->sjo_float = std::stod(numstr);
|
||||
sjo->sjo_type = SQLITE_FLOAT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
sjo->jo_ptr_error_code = yajl_gen_number(gen, numval, numlen);
|
||||
}
|
||||
|
||||
return sjo->jo_ptr_error_code == yajl_gen_status_ok;
|
||||
}
|
||||
|
||||
static void sql_jget(sqlite3_context *context,
|
||||
int argc, sqlite3_value **argv)
|
||||
{
|
||||
|
@ -205,6 +229,7 @@ static void sql_jget(sqlite3_context *context,
|
|||
jo.jo_ptr_callbacks.yajl_null = gen_handle_null;
|
||||
jo.jo_ptr_callbacks.yajl_boolean = gen_handle_boolean;
|
||||
jo.jo_ptr_callbacks.yajl_string = gen_handle_string;
|
||||
jo.jo_ptr_callbacks.yajl_number = gen_handle_number;
|
||||
jo.jo_ptr_data = gen.get_handle();
|
||||
|
||||
handle.reset(yajl_alloc(&json_op::ptr_callbacks, nullptr, &jo));
|
||||
|
@ -258,6 +283,9 @@ static void sql_jget(sqlite3_context *context,
|
|||
case SQLITE_INTEGER:
|
||||
sqlite3_result_int(context, jo.sjo_int);
|
||||
return;
|
||||
case SQLITE_FLOAT:
|
||||
sqlite3_result_double(context, jo.sjo_float);
|
||||
return;
|
||||
}
|
||||
|
||||
string_fragment result = gen.to_string_fragment();
|
||||
|
@ -268,6 +296,9 @@ static void sql_jget(sqlite3_context *context,
|
|||
}
|
||||
|
||||
sqlite3_result_text(context, result.data(), result.length(), SQLITE_TRANSIENT);
|
||||
#ifdef HAVE_SQLITE3_VALUE_SUBTYPE
|
||||
sqlite3_result_subtype(context, JSON_SUBTYPE);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct concat_context {
|
||||
|
|
|
@ -104,6 +104,16 @@ Row 0:
|
|||
Column jget('[null, true, 20, 30, 40]', '/3'): 30
|
||||
EOF
|
||||
|
||||
run_test ./drive_sql "select typeof(jget('[null, true, 20, 30, 40]', '/3'))"
|
||||
|
||||
check_error_output "" <<EOF
|
||||
EOF
|
||||
|
||||
check_output "jget null does not work" <<EOF
|
||||
Row 0:
|
||||
Column typeof(jget('[null, true, 20, 30, 40]', '/3')): integer
|
||||
EOF
|
||||
|
||||
run_test ./drive_sql "select jget('[null, true, 20, 30, 40, {\"msg\": \"Hello\"}]', '/5')"
|
||||
|
||||
check_error_output "" <<EOF
|
||||
|
@ -124,6 +134,16 @@ Row 0:
|
|||
Column jget('[null, true, 20, 30, 40, {"msg": "Hello"}]', '/5/msg'): Hello
|
||||
EOF
|
||||
|
||||
run_test ./drive_sql "select jget('[null, true, 20, 30, 40, {\"msg\": \"Hello\"}]', '')"
|
||||
|
||||
check_error_output "" <<EOF
|
||||
EOF
|
||||
|
||||
check_output "jget null does not work" <<EOF
|
||||
Row 0:
|
||||
Column jget('[null, true, 20, 30, 40, {"msg": "Hello"}]', ''): [null,true,20,30,40,{"msg":"Hello"}]
|
||||
EOF
|
||||
|
||||
run_test ./drive_sql "select jget('[null, true, 20, 30, 40]', '/abc')"
|
||||
|
||||
check_error_output "" <<EOF
|
||||
|
@ -174,6 +194,16 @@ Row 0:
|
|||
Column jget('[null, true, 20, 30, 4.0]', '/4'): 4.0
|
||||
EOF
|
||||
|
||||
run_test ./drive_sql "select typeof(jget('[null, true, 20, 30, 4.0]', '/4'))"
|
||||
|
||||
check_error_output "" <<EOF
|
||||
EOF
|
||||
|
||||
check_output "jget for array does not work" <<EOF
|
||||
Row 0:
|
||||
Column typeof(jget('[null, true, 20, 30, 4.0]', '/4')): real
|
||||
EOF
|
||||
|
||||
run_test ./drive_sql "select jget('[null, true, 20, 30, 40', '/0/foo')"
|
||||
|
||||
check_error_output "" <<EOF
|
||||
|
|
Loading…
Reference in New Issue