public inbox for [email protected]
help / color / mirror / Atom feedFrom: Akshay Joshi <[email protected]>
To: Dave Page <[email protected]>
Cc: pgadmin-hackers <[email protected]>
Subject: Re: [pgAdmin4][Patch]: RM #3397 Add support for JIT stats in EXPLAIN output in PG11
Date: Sat, 30 Jun 2018 13:45:36 +0530
Message-ID: <CANxoLDd7P5QKxbhbQ93Hw=gF0NQdFt2pyy5XnQ_LThTVmk8Bnw@mail.gmail.com> (raw)
In-Reply-To: <CA+OCxow4L5AL8QNYxVckjGVtaN9h+J+72Kg_wjuQ+qJA5ffShw@mail.gmail.com>
References: <CANxoLDdnaPB8gt-v+4aVY2urY8suGqK=pFiWFZ-Agxkgkx_VYw@mail.gmail.com>
<CA+OCxozxjz+m=zy_AN4QPQtNHKuYTpQ6YpihoS=ugpzLe_jvEQ@mail.gmail.com>
<CANxoLDcKr_A+gCBwgdG6GGrc78Rm2mtLsvmL-pEx7UPSPg8kBA@mail.gmail.com>
<CA+OCxow4L5AL8QNYxVckjGVtaN9h+J+72Kg_wjuQ+qJA5ffShw@mail.gmail.com>
Hi Dave
On Fri, Jun 29, 2018 at 7:45 PM, Dave Page <[email protected]> wrote:
>
>
> On Fri, Jun 29, 2018 at 3:12 PM, Akshay Joshi <
> [email protected]> wrote:
>
>> Hi Dave
>>
>> On Fri, Jun 29, 2018 at 6:56 PM, Dave Page <[email protected]> wrote:
>>
>>> Hi
>>>
>>> On Fri, Jun 29, 2018 at 9:55 AM, Akshay Joshi <
>>> [email protected]> wrote:
>>>
>>>> Hi Hackers,
>>>>
>>>> Attached is the patch to fix the RM #3397 Add support for JIT stats in
>>>> EXPLAIN output in PG11. Please review it.
>>>>
>>>
>>> A couple of immediate thoughts:
>>>
>>> - When the canvas is first rendered, there's a vertical scrollbar now.
>>> As soon as I mouseover the new icon, it vanishes and the icon jumps to the
>>> right.
>>>
>>
>> Will look into it. Vertical scrollbar comes even if you remove my
>> patch and try to hover any image.
>>
>>>
>>> - The icon seems lighter than the other controls on the left.
>>>
>>
>> Same css has been applied, only difference is button is disabled.
>>
>>>
>>> - The icon isn't disabled when there is no info to show.
>>>
>>
>> Button is always disabled, I have just change the opacity.
>>
>>>
>>> Thanks.
>>>
>>
> Maybe - but I can still click it and it reacts as if it's active. It may
> be lighter to indicate that it's disabled, but its not behaving as such.
>
Attached is the modified patch. Please review it.
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>
--
*Akshay Joshi*
*Sr. Software Architect *
*Phone: +91 20-3058-9517Mobile: +91 976-788-8246*
Attachments:
[application/octet-stream] RM_3397_v2.patch (9.3K, 3-RM_3397_v2.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..38bb322 100644
--- a/web/pgadmin/misc/static/explain/css/explain.css
+++ b/web/pgadmin/misc/static/explain/css/explain.css
@@ -17,6 +17,18 @@
opacity: 1;
}
+.pg-explain-stats-area {
+ position: absolute;
+ top: 5px;
+ right: 25px;
+}
+
+.pg-explain-stats-btn {
+ top: 5px;
+ min-width: 25px;
+ border: 1px solid transparent;
+}
+
.explain-tooltip {
display: table-cell;
text-align: left;
@@ -37,8 +49,6 @@ td.explain-tooltip-val {
.pgadmin-explain-tooltip {
position: absolute;
- padding:5px;
- border: 1px solid white;
opacity:0;
color: cornsilk;
background-color: #010125;
@@ -55,4 +65,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..04cc7f8 100644
--- a/web/pgadmin/misc/static/explain/js/explain.js
+++ b/web/pgadmin/misc/static/explain/js/explain.js
@@ -615,6 +615,9 @@ define('pgadmin.misc.explain', [
});
toolTipContainer.css('left', toolTipX);
toolTipContainer.css('top', toolTipY);
+
+ $('.pgadmin-explain-tooltip').css('padding', '5px');
+ $('.pgadmin-explain-tooltip').css('border', '1px solid white');
});
// Remove tooltip when mouse is out from node's area
@@ -687,6 +690,85 @@ 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');
+ $('.pg-explain-stats-area').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',
+ });
+
+ $('.pgadmin-explain-tooltip').css('padding', '5px');
+ $('.pgadmin-explain-tooltip').css('border', '1px solid white');
+ });
+
+ // Remove tooltip when mouse is out from node's area
+ $('.pg-explain-stats-area').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 +778,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 +801,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 +839,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 +882,22 @@ 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',
+ title: 'Statistics',
+ tabindex: 0,
+ disabled: 'disabled',
+ }).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], [email protected]
Subject: Re: [pgAdmin4][Patch]: RM #3397 Add support for JIT stats in EXPLAIN output in PG11
In-Reply-To: <CANxoLDd7P5QKxbhbQ93Hw=gF0NQdFt2pyy5XnQ_LThTVmk8Bnw@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