From 5931611533d27e1bf68725882c000f9601e0c4ea Mon Sep 17 00:00:00 2001 From: Hannah Bast Date: Sun, 9 Jul 2023 19:41:21 +0200 Subject: [PATCH] Show information about "lazy scans" in "Analysis" view The runtime information shown in the "Analysis" tree now contains additional information, notably such related to "lazy index scans", see PR https://github.com/ad-freiburg/qlever/pull/1003 . The status of the "normal" operations has been renamed to "fully materialized" and is not explicitly shown in the tree. The status of the lazy index scans is called "lazily materialized". When hovering over a node in the tree, more detailed infomation is shown at the bottom if available. --- backend/static/css/style.css | 6 ++++-- backend/static/js/helper.js | 6 +++++- backend/static/js/qleverUI.js | 12 ++++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/backend/static/css/style.css b/backend/static/css/style.css index 4aa286ab..cb964a79 100644 --- a/backend/static/css/style.css +++ b/backend/static/css/style.css @@ -286,13 +286,13 @@ li.CodeMirror-hint-active { #result-tree .node > p { margin: 0; white-space: nowrap; } #result-tree .node-name { font-weight: bold; } +/* #result-tree .node-status { font-size: 80%; color: blue; } */ #result-tree .node-status:before { content: "Status: " } -/* #result-tree .node-status { font-size: 90%; } */ #result-tree .node-status.failed { font-weight: bold; color: red; } #result-tree .node-status.child-failed { color: red; } #result-tree .node-status.not-started { color: blue; } #result-tree .node-status.optimized-out { color: blue; } -#result-tree .node-status.complete-during-query-planning { color: blue; } +#result-tree .node-status.lazily-materialized { color: blue; } #result-tree .node-cols:before { content: "Cols: "; } #result-tree .node-size:before { content: "Size: "; } #result-tree .node-size { display: inline; } @@ -301,6 +301,8 @@ li.CodeMirror-hint-active { #result-tree .node-time { display: inline; } #result-tree .node-cost-estimate { display: inline; padding-left: 1em; } #result-tree .node-time:after { content: "ms"; } +#result-tree .node-details { display: none; color: blue; } +#result-tree .node-details:before { content: "Details: " } #result-tree div.cached-not-pinned .node-time:after { content: "ms [cached]"; } #result-tree div.cached-pinned .node-time:after { content: "ms [cached, pinned]"; } #result-tree div.ancestor-cached .node-time:after { content: "ms [ancestor cached]"; } diff --git a/backend/static/js/helper.js b/backend/static/js/helper.js index 7cb60b4b..16e24d56 100644 --- a/backend/static/js/helper.js +++ b/backend/static/js/helper.js @@ -93,7 +93,7 @@ function addTextElementsToQueryExecutionTreeForTreant(tree_node, is_ancestor_cac // console.log("-> REWRITTEN TO:", text["name"]) text["status"] = tree_node["status"]; - if (text["status"] == "completed") { delete text["status"]; } + if (text["status"] == "fully materialized") { delete text["status"]; } text["cols"] = tree_node["column_names"].join(", ") .replace(/qlc_/g, "").replace(/_qlever_internal_variable_query_planner/g, "") .replace(/\?[A-Z_]*/g, function (match) { return match.toLowerCase(); }); @@ -111,6 +111,10 @@ function addTextElementsToQueryExecutionTreeForTreant(tree_node, is_ancestor_cac : formatInteger(tree_node["original_operation_time"]); text["cost-estimate"] = "[~ " + formatInteger(tree_node["estimated_operation_cost"]) + "]" text["total"] = text["time"]; + if (tree_node["details"]) { + text["details"] = JSON.stringify(tree_node["details"]); + console.log("details:", text["details"]); + } // Delete all other keys except "children" (we only needed them here to // create a proper "text" element) and the "text" element. diff --git a/backend/static/js/qleverUI.js b/backend/static/js/qleverUI.js index a4a00903..5380e38e 100755 --- a/backend/static/js/qleverUI.js +++ b/backend/static/js/qleverUI.js @@ -657,6 +657,14 @@ async function processQuery(sendLimit=0, element=$("#exebtn")) { nodeStructure: runtime_info["query_execution_tree"] } var treant_chart = new Treant(treant_tree); + + // For each node, on mouseover show the details. + $("div.node").hover(function () { + $(this).children(".node-details").show(); + }, function () { + $(this).children(".node-details").hide(); + }); + $("p.node-time"). filter(function () { return $(this).html().replace(/,/g, "") >= high_query_time_ms }). parent().addClass("high"); @@ -669,12 +677,12 @@ async function processQuery(sendLimit=0, element=$("#exebtn")) { .parent().addClass("cached-pinned").addClass("cached"); $("p.node-cache-status").filter(function () { return $(this).html() === "ancestor_cached" }) .parent().addClass("ancestor-cached").addClass("cached"); - $("p.node-status").filter(function() { return $(this).text() === "completed"}).addClass("completed"); + $("p.node-status").filter(function() { return $(this).text() === "fully materialized"}).addClass("fully-materialized"); + $("p.node-status").filter(function() { return $(this).text() === "lazily materialized"}).addClass("lazily-materialized"); $("p.node-status").filter(function() { return $(this).text() === "failed"}).addClass("failed"); $("p.node-status").filter(function() { return $(this).text() === "failed because child failed"}).addClass("child-failed"); $("p.node-status").filter(function() { return $(this).text() === "not started"}).addClass("not-started"); $("p.node-status").filter(function() { return $(this).text() === "optimized out"}).addClass("optimized-out"); - $("p.node-status").filter(function() { return $(this).text() === "completed during query planning"}).addClass("completed-during-query-planning"); if ($('#logRequests').is(':checked')) { select = "";