public inbox for [email protected]
help / color / mirror / Atom feedFrom: Akshay Joshi <[email protected]>
To: pgadmin-hackers <[email protected]>
Subject: [pgAdmin4][Patch]: RM #3397 Add support for JIT stats in EXPLAIN output in PG11
Date: Fri, 29 Jun 2018 14:25:58 +0530
Message-ID: <CANxoLDdnaPB8gt-v+4aVY2urY8suGqK=pFiWFZ-Agxkgkx_VYw@mail.gmail.com> (raw)
Hi Hackers,
Attached is the patch to fix the RM #3397 Add support for JIT stats in
EXPLAIN output in PG11. Please review it.
--
*Akshay Joshi*
*Sr. Software Architect *
*Phone: +91 20-3058-9517Mobile: +91 976-788-8246*
Attachments:
[application/octet-stream] RM_3397.patch (8.8K, 3-RM_3397.patch)
download | inline diff:
diff --git a/web/pgadmin/feature_tests/query_tool_tests.py b/web/pgadmin/feature_tests/query_tool_tests.py
index ac463d3..226b323 100644
--- a/web/pgadmin/feature_tests/query_tool_tests.py
+++ b/web/pgadmin/feature_tests/query_tool_tests.py
@@ -104,6 +104,16 @@ class QueryToolFeatureTest(BaseFeatureTest):
self._query_tool_notify_statements()
self._clear_query_tool()
+ # explain query with JIT stats
+ print("Explain query with JIT stats... ",
+ file=sys.stderr, end="")
+ if self._supported_jit_on_server():
+ self._query_tool_explain_check_jit_stats()
+ print("OK.", file=sys.stderr)
+ self._clear_query_tool()
+ else:
+ print("Skipped.", file=sys.stderr)
+
def after(self):
self.page.remove_server(self.server)
connection = test_utils.get_db_connection(
@@ -660,9 +670,62 @@ SELECT 1, pg_sleep(300)"""
wait.until(WaitForAnyElementWithText(
(By.CSS_SELECTOR, 'td.payload'), "Hello"))
print("OK.", file=sys.stderr)
+ self._clear_query_tool()
else:
print("Skipped.", file=sys.stderr)
+ def _supported_jit_on_server(self):
+ connection = test_utils.get_db_connection(
+ self.server['db'],
+ self.server['username'],
+ self.server['db_password'],
+ self.server['host'],
+ self.server['port'],
+ self.server['sslmode']
+ )
+
+ pg_cursor = connection.cursor()
+ pg_cursor.execute('select version()')
+ version_string = pg_cursor.fetchone()
+
+ is_edb = False
+ if len(version_string) > 0:
+ is_edb = 'EnterpriseDB' in version_string[0]
+
+ connection.close()
+
+ return connection.server_version >= 110000 and not is_edb
+
+ def _query_tool_explain_check_jit_stats(self):
+ wait = WebDriverWait(self.page.driver, 10)
+
+ self.page.fill_codemirror_area_with("SET jit_above_cost=10;")
+ self.page.find_by_id("btn-flash").click()
+ self.page.wait_for_query_tool_loading_indicator_to_disappear()
+ self._clear_query_tool()
+
+ self.page.fill_codemirror_area_with("SELECT count(*) FROM pg_class;")
+ query_op = self.page.find_by_id("btn-query-dropdown")
+ query_op.click()
+ ActionChains(self.driver).move_to_element(
+ query_op.find_element_by_xpath(
+ "//li[contains(.,'Explain Options')]")).perform()
+
+ self.page.find_by_id("btn-explain-verbose").click()
+ self.page.find_by_id("btn-explain-costs").click()
+ self.page.find_by_id("btn-explain-analyze").click()
+
+ self.page.wait_for_query_tool_loading_indicator_to_disappear()
+ self.page.click_tab('Data Output')
+
+ canvas = wait.until(EC.presence_of_element_located(
+ (By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas"))
+ )
+ # Search for 'Output' word in result (verbose option)
+ canvas.find_element_by_xpath("//*[contains(string(), 'JIT')]")
+
+ self._clear_query_tool()
+
class WaitForAnyElementWithText(object):
def __init__(self, locator, text):
diff --git a/web/pgadmin/misc/static/explain/css/explain.css b/web/pgadmin/misc/static/explain/css/explain.css
index d549f85..34fa74f 100644
--- a/web/pgadmin/misc/static/explain/css/explain.css
+++ b/web/pgadmin/misc/static/explain/css/explain.css
@@ -17,6 +17,26 @@
opacity: 1;
}
+.pg-explain-stats-area {
+ position: absolute;
+ top: 5px;
+ right: 25px;
+ opacity: 0.5;
+}
+
+.pg-explain-stats-btn {
+ top: 5px;
+ min-width: 25px;
+ border: 1px solid transparent;
+}
+.pg-explain-stats-btn.disabled {
+ cursor: auto !important;
+}
+
+.pg-explain-stats-area:hover {
+ opacity: 1;
+}
+
.explain-tooltip {
display: table-cell;
text-align: left;
@@ -55,4 +75,4 @@ td.explain-tooltip-val {
height: 100%;
width: 100%;
overflow: auto;
-}
\ No newline at end of file
+}
diff --git a/web/pgadmin/misc/static/explain/js/explain.js b/web/pgadmin/misc/static/explain/js/explain.js
index e028774..1ad25df 100644
--- a/web/pgadmin/misc/static/explain/js/explain.js
+++ b/web/pgadmin/misc/static/explain/js/explain.js
@@ -687,6 +687,83 @@ define('pgadmin.misc.explain', [
},
});
+ // Backbone model for other statistics
+ var StatsModel = Backbone.Model.extend({
+ defaults: {
+ JIT: [],
+ Triggers: [],
+ },
+ set_statistics: function(xpos, ypos, graphContainer, toolTipContainer) {
+ var jit_stats = this.get('JIT'),
+ triggers_stats = this.get('Triggers');
+ $('#btn-explain-stats').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) {
+ 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) {
+ 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') {
+ tooltip.append('<tr><td class="label explain-tooltip"> '
+ + key + '</td><td class="label explain-tooltip-val">'
+ + value + '</td></tr>');
+ } else {
+ tooltip.append('<tr><td class="label explain-tooltip"> '
+ + key + '</td><td class="label explain-tooltip-val">'
+ + value + '</td></tr>');
+ }
+ });
+ }
+ else {
+ tooltip.append('<tr><td class="label explain-tooltip"> '
+ + key_id + '</td><td class="label explain-tooltip-val">'
+ + triggers + '</td></tr>');
+ }
+ });
+ }
+
+ // Show toolTip at respective x,y coordinates
+ toolTipContainer.css({
+ 'opacity': '0.8',
+ 'left': '',
+ 'right': '65px',
+ 'top': '15px',
+ });
+ });
+
+ // Remove tooltip when mouse is out from node's area
+ $('#btn-explain-stats').on('mouseout', () => {
+ toolTipContainer.empty();
+ toolTipContainer.css({
+ 'opacity': '0',
+ 'left': 0,
+ 'top': 0,
+ });
+
+ });
+ },
+ });
+
// Main backbone model to store JSON object
var MainPlanModel = Backbone.Model.extend({
defaults: {
@@ -696,6 +773,7 @@ define('pgadmin.misc.explain', [
},
initialize: function() {
this.set('Plan', new PlanModel());
+ this.set('Statistics', new StatsModel());
},
// Parse the JSON data and fetch its children plans
@@ -718,6 +796,17 @@ define('pgadmin.misc.explain', [
delete data['Plan'];
}
+ var stats = this.get('Statistics');
+ if (data && 'JIT' in data) {
+ stats.set('JIT', data['JIT']);
+ delete data ['JIT'];
+ }
+
+ if (data && 'Triggers' in data) {
+ stats.set('Triggers', data['Triggers']);
+ delete data ['Triggers'];
+ }
+
return data;
},
toJSON: function() {
@@ -745,6 +834,10 @@ define('pgadmin.misc.explain', [
plan.draw(
g, xpos, ypos, undefined, undefined, graphContainer, toolTipContainer
);
+
+ //Set the Statistics as tooltip
+ var stats = this.get('Statistics');
+ stats.set_statistics(xpos, ypos, graphContainer, toolTipContainer);
},
});
@@ -784,6 +877,21 @@ define('pgadmin.misc.explain', [
class: 'fa fa-search-minus',
}));
+ var statsArea = $('<div></div>', {
+ class: 'pg-explain-stats-area btn-group',
+ role: 'group',
+ }).appendTo(container);
+
+ $('<button></button>', {
+ id: 'btn-explain-stats',
+ class: 'btn pg-explain-stats-btn badge disabled',
+ title: 'Statistics',
+ tabindex: 0,
+ }).appendTo(statsArea).append(
+ $('<i></i>', {
+ class: 'fa fa-line-chart',
+ }));
+
// Main div to be drawn all images on
var planDiv = $('<div></div>', {
class: 'pgadmin-explain-container',
view thread (12+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [pgAdmin4][Patch]: RM #3397 Add support for JIT stats in EXPLAIN output in PG11
In-Reply-To: <CANxoLDdnaPB8gt-v+4aVY2urY8suGqK=pFiWFZ-Agxkgkx_VYw@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox