Add EXPLAIN options for SETTINGS and SUMMARY. Fixes #4335

Prevent flickering of large tooltips on the Graphical EXPLAIN canvas. Fixes #4224
EXPLAIN options should be Query Tool instance-specific. Fixes #4395
This commit is contained in:
Aditya Toshniwal
2019-07-03 13:57:56 +01:00
committed by Dave Page
parent 15556f9f89
commit 0340b8fb28
25 changed files with 425 additions and 249 deletions

View File

@@ -30,7 +30,6 @@
.pg-explain-stats-btn {
top: 5px;
min-width: 25px;
border: 1px solid transparent;
pointer-events: none;
font-size: 0.75rem;
}

View File

@@ -427,14 +427,7 @@ define('pgadmin.misc.explain', [
// Calculate co-ordinates for tooltip
var toolTipX = ((currentXpos + pWIDTH) * zoomFactor - graphContainer.scrollLeft());
var toolTipY = ((currentYpos + pHEIGHT) * zoomFactor - graphContainer.scrollTop());
// Recalculate x.y if tooltip is going out of screen
if (graphContainer.width() < (toolTipX + toolTipContainer[0].clientWidth))
toolTipX -= (toolTipContainer[0].clientWidth + (pWIDTH * zoomFactor));
//if(document.children[0].clientHeight < (toolTipY + toolTipContainer[0].clientHeight))
if (graphContainer.height() < (toolTipY + toolTipContainer[0].clientHeight))
toolTipY -= (toolTipContainer[0].clientHeight + ((pHEIGHT / 2) * zoomFactor));
var toolTipY = ((currentYpos) * zoomFactor - graphContainer.scrollTop());
toolTipX = toolTipX < 0 ? 0 : (toolTipX);
toolTipY = toolTipY < 0 ? 0 : (toolTipY);
@@ -727,6 +720,19 @@ define('pgadmin.misc.explain', [
delete data ['Triggers'];
}
if(data) {
let summKeys = ['Planning Time', 'Execution Time'],
summary = {};
summKeys.forEach((key)=>{
if (key in data) {
summary[key] = data[key];
}
});
statistics.set('Summary', summary);
}
return data;
},
toJSON: function() {

View File

@@ -15,81 +15,102 @@ let StatisticsModel = Backbone.Model.extend({
defaults: {
JIT: [],
Triggers: [],
Summary: {},
},
set_statistics: function(toolTipContainer) {
var jit_stats = this.get('JIT'),
triggers_stats = this.get('Triggers');
triggers_stats = this.get('Triggers'),
summary = this.get('Summary');
if (Object.keys(jit_stats).length > 0 ||
Object.keys(triggers_stats).length > 0) {
Object.keys(triggers_stats).length > 0 ||
Object.keys(summary).length > 0) {
$('.pg-explain-stats-area').removeClass('d-none');
}
$('.pg-explain-stats-area').on('mouseover', () => {
var tooltip = $('<table></table>', {
class: 'pgadmin-tooltip-table',
});
if (Object.keys(jit_stats).length > 0){
tooltip.append('<tr><td class="label explain-tooltip">JIT:</td></tr>');
_.each(jit_stats, function(value, key) {
key = _.escape(key);
value = _.escape(value);
tooltip.append(`
<tr>
<td class="label explain-tooltip"> ${key}</td>
<td class="label explain-tooltip-val">${value}</td>
</tr>
`);
});
}
if (Object.keys(triggers_stats).length > 0){
tooltip.append('<tr><td class="label explain-tooltip">Triggers:</td></tr>');
_.each(triggers_stats, function(triggers, key_id) {
if (triggers instanceof Object) {
_.each(triggers, function(value, key) {
if (key === 'Trigger Name') {
key = _.escape(key);
value = _.escape(value);
tooltip.append(`
<tr>
<td class="label explain-tooltip"> ${key}</td>
<td class="label explain-tooltip-val">${value}</td>
</tr>
`);
} else {
key = _.escape(key);
value = _.escape(value);
tooltip.append(`
<tr>
<td class="label explain-tooltip"> ${key}</td>
<td class="label explain-tooltip-val">${value}</td>
</tr>
`);
}
});
}
else {
key_id = _.escape(key_id);
triggers = _.escape(triggers);
tooltip.append(`
<tr>
<td class="label explain-tooltip"> ${key_id}</td>
<td class="label explain-tooltip-val">${triggers}</td>
</tr>
`);
}
});
}
if (Object.keys(summary).length > 0){
tooltip.append('<tr><td class="label explain-tooltip">Summary:</td></tr>');
_.each(summary, function(value, key) {
key = _.escape(key);
value = _.escape(value);
tooltip.append(`
<tr>
<td class="label explain-tooltip"> ${key}</td>
<td class="label explain-tooltip-val">${value}</td>
</tr>
`);
});
}
$('.pg-explain-stats-area').off('mouseover').on('mouseover', () => {
// Empty the tooltip content if it has any and add new data
toolTipContainer.empty();
if (Object.keys(jit_stats).length == 0 &&
Object.keys(triggers_stats).length == 0) {
Object.keys(triggers_stats).length == 0 &&
Object.keys(summary).length == 0) {
return;
}
var tooltip = $('<table></table>', {
class: 'pgadmin-tooltip-table',
}).appendTo(toolTipContainer);
if (Object.keys(jit_stats).length > 0){
tooltip.append('<tr><td class="label explain-tooltip">JIT:</td></tr>');
_.each(jit_stats, function(value, key) {
key = _.escape(key);
value = _.escape(value);
tooltip.append(`
<tr>
<td class="label explain-tooltip"> ${key}</td>
<td class="label explain-tooltip-val">${value}</td>
</tr>
`);
});
}
if (Object.keys(triggers_stats).length > 0){
tooltip.append('<tr><td class="label explain-tooltip">Triggers:</td></tr>');
_.each(triggers_stats, function(triggers, key_id) {
if (triggers instanceof Object) {
_.each(triggers, function(value, key) {
if (key === 'Trigger Name') {
key = _.escape(key);
value = _.escape(value);
tooltip.append(`
<tr>
<td class="label explain-tooltip"> ${key}</td>
<td class="label explain-tooltip-val">${value}</td>
</tr>
`);
} else {
key = _.escape(key);
value = _.escape(value);
tooltip.append(`
<tr>
<td class="label explain-tooltip"> ${key}</td>
<td class="label explain-tooltip-val">${value}</td>
</tr>
`);
}
});
}
else {
key_id = _.escape(key_id);
triggers = _.escape(triggers);
tooltip.append(`
<tr>
<td class="label explain-tooltip"> ${key_id}</td>
<td class="label explain-tooltip-val">${triggers}</td>
</tr>
`);
}
});
}
toolTipContainer.empty();
toolTipContainer.append(tooltip);
// Show toolTip at respective x,y coordinates
toolTipContainer.css({
@@ -104,12 +125,13 @@ let StatisticsModel = Backbone.Model.extend({
});
// Remove tooltip when mouse is out from node's area
$('.pg-explain-stats-area').on('mouseout', () => {
$('.pg-explain-stats-area').off('mouseout').on('mouseout', () => {
toolTipContainer.empty();
toolTipContainer.css({
'opacity': '0',
'left': 0,
'top': 0,
'right': '',
});
});
},