You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dm...@apache.org on 2017/03/17 00:20:24 UTC
[16/19] ignite git commit: IGNITE-4821 Implemented enforce join order
option on query tab.
IGNITE-4821 Implemented enforce join order option on query tab.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/94c1e7cb
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/94c1e7cb
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/94c1e7cb
Branch: refs/heads/ignite-1192
Commit: 94c1e7cb505e0a40e1d3c28de5a25b5aefbd55c0
Parents: f361da4
Author: Vasiliy Sisko <vs...@gridgain.com>
Authored: Wed Mar 15 11:43:23 2017 +0700
Committer: Andrey Novikov <an...@gridgain.com>
Committed: Wed Mar 15 11:43:23 2017 +0700
----------------------------------------------------------------------
modules/web-console/backend/app/agent.js | 14 ++++++-
modules/web-console/backend/app/browser.js | 8 ++--
.../frontend/app/modules/agent/agent.module.js | 10 +++--
.../frontend/app/modules/sql/sql.controller.js | 25 ++++++++++---
.../frontend/public/stylesheets/style.scss | 8 +++-
.../web-console/frontend/views/sql/sql.tpl.pug | 39 +++++++++++++-------
6 files changed, 74 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/94c1e7cb/modules/web-console/backend/app/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/agent.js b/modules/web-console/backend/app/agent.js
index b4394b7..f65eabb 100644
--- a/modules/web-console/backend/app/agent.js
+++ b/modules/web-console/backend/app/agent.js
@@ -227,17 +227,27 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo,
* @param {String} cacheName Cache name.
* @param {String} query Query.
* @param {Boolean} nonCollocatedJoins Flag whether to execute non collocated joins.
+ * @param {Boolean} enforceJoinOrder Flag whether enforce join order is enabled.
* @param {Boolean} local Flag whether to execute query locally.
* @param {int} pageSize Page size.
* @returns {Promise}
*/
- fieldsQuery(demo, nid, cacheName, query, nonCollocatedJoins, local, pageSize) {
+ fieldsQuery(demo, nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, local, pageSize) {
const cmd = new Command(demo, 'exe')
.addParam('name', 'org.apache.ignite.internal.visor.compute.VisorGatewayTask')
.addParam('p1', nid)
.addParam('p2', 'org.apache.ignite.internal.visor.query.VisorQueryTask');
- if (nonCollocatedJoins) {
+ if (enforceJoinOrder) {
+ cmd.addParam('p3', 'org.apache.ignite.internal.visor.query.VisorQueryArgV3')
+ .addParam('p4', cacheName)
+ .addParam('p5', query)
+ .addParam('p6', nonCollocatedJoins)
+ .addParam('p7', enforceJoinOrder)
+ .addParam('p8', local)
+ .addParam('p9', pageSize);
+ }
+ else if (nonCollocatedJoins) {
cmd.addParam('p3', 'org.apache.ignite.internal.visor.query.VisorQueryArgV2')
.addParam('p4', cacheName)
.addParam('p5', query)
http://git-wip-us.apache.org/repos/asf/ignite/blob/94c1e7cb/modules/web-console/backend/app/browser.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/browser.js b/modules/web-console/backend/app/browser.js
index 56f2acc..00ae751 100644
--- a/modules/web-console/backend/app/browser.js
+++ b/modules/web-console/backend/app/browser.js
@@ -98,9 +98,9 @@ module.exports.factory = (_, socketio, agentMgr, configure) => {
});
// Execute query on node and return first page to browser.
- socket.on('node:query', (nid, cacheName, query, distributedJoins, local, pageSize, cb) => {
+ socket.on('node:query', (nid, cacheName, query, distributedJoins, enforceJoinOrder, local, pageSize, cb) => {
agentMgr.findAgent(accountId())
- .then((agent) => agent.fieldsQuery(demo, nid, cacheName, query, distributedJoins, local, pageSize))
+ .then((agent) => agent.fieldsQuery(demo, nid, cacheName, query, distributedJoins, enforceJoinOrder, local, pageSize))
.then((res) => cb(null, res))
.catch((err) => cb(_errorToJson(err)));
});
@@ -114,13 +114,13 @@ module.exports.factory = (_, socketio, agentMgr, configure) => {
});
// Execute query on node and return full result to browser.
- socket.on('node:query:getAll', (nid, cacheName, query, distributedJoins, local, cb) => {
+ socket.on('node:query:getAll', (nid, cacheName, query, distributedJoins, enforceJoinOrder, local, cb) => {
// Set page size for query.
const pageSize = 1024;
agentMgr.findAgent(accountId())
.then((agent) => {
- const firstPage = agent.fieldsQuery(demo, nid, cacheName, query, distributedJoins, local, pageSize)
+ const firstPage = agent.fieldsQuery(demo, nid, cacheName, query, distributedJoins, enforceJoinOrder, local, pageSize)
.then(({result}) => {
if (result.key)
return Promise.reject(result.key);
http://git-wip-us.apache.org/repos/asf/ignite/blob/94c1e7cb/modules/web-console/frontend/app/modules/agent/agent.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/agent/agent.module.js b/modules/web-console/frontend/app/modules/agent/agent.module.js
index c0e92d5..724fc6c 100644
--- a/modules/web-console/frontend/app/modules/agent/agent.module.js
+++ b/modules/web-console/frontend/app/modules/agent/agent.module.js
@@ -265,12 +265,13 @@ class IgniteAgentMonitor {
* @param {String} cacheName Cache name.
* @param {String} [query] Query if null then scan query.
* @param {Boolean} nonCollocatedJoins Flag whether to execute non collocated joins.
+ * @param {Boolean} enforceJoinOrder Flag whether enforce join order is enabled.
* @param {Boolean} local Flag whether to execute query locally.
* @param {int} pageSize
* @returns {Promise}
*/
- query(nid, cacheName, query, nonCollocatedJoins, local, pageSize) {
- return this._rest('node:query', nid, maskNull(cacheName), maskNull(query), nonCollocatedJoins, local, pageSize)
+ query(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, local, pageSize) {
+ return this._rest('node:query', nid, maskNull(cacheName), maskNull(query), nonCollocatedJoins, enforceJoinOrder, local, pageSize)
.then(({result}) => {
if (_.isEmpty(result.key))
return result.value;
@@ -284,11 +285,12 @@ class IgniteAgentMonitor {
* @param {String} cacheName Cache name.
* @param {String} [query] Query if null then scan query.
* @param {Boolean} nonCollocatedJoins Flag whether to execute non collocated joins.
+ * @param {Boolean} enforceJoinOrder Flag whether enforce join order is enabled.
* @param {Boolean} local Flag whether to execute query locally.
* @returns {Promise}
*/
- queryGetAll(nid, cacheName, query, nonCollocatedJoins, local) {
- return this._rest('node:query:getAll', nid, maskNull(cacheName), maskNull(query), nonCollocatedJoins, local);
+ queryGetAll(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, local) {
+ return this._rest('node:query:getAll', nid, maskNull(cacheName), maskNull(query), nonCollocatedJoins, enforceJoinOrder, local);
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/94c1e7cb/modules/web-console/frontend/app/modules/sql/sql.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/sql/sql.controller.js b/modules/web-console/frontend/app/modules/sql/sql.controller.js
index c082d4e..7ded2d5 100644
--- a/modules/web-console/frontend/app/modules/sql/sql.controller.js
+++ b/modules/web-console/frontend/app/modules/sql/sql.controller.js
@@ -34,6 +34,8 @@ const SCAN_CACHE_WITH_FILTER_CASE_SENSITIVE = 'VISOR_SCAN_CACHE_WITH_FILTER_CASE
const NON_COLLOCATED_JOINS_SINCE = '1.7.0';
+const ENFORCE_JOIN_VERS = [['1.7.9', '1.8.0'], ['1.8.4', '1.9.0'], ['1.9.1']];
+
const _fullColName = (col) => {
const res = [];
@@ -1336,7 +1338,8 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
agentMonitor.awaitAgent()
.then(() => _closeOldQuery(paragraph))
.then(() => args.localNid || _chooseNode(args.cacheName, false))
- .then((nid) => agentMonitor.query(nid, args.cacheName, args.query, args.nonCollocatedJoins, !!args.localNid, args.pageSize))
+ .then((nid) => agentMonitor.query(nid, args.cacheName, args.query, args.nonCollocatedJoins,
+ args.enforceJoinOrder, !!args.localNid, args.pageSize))
.then(_processQueryResult.bind(this, paragraph, false))
.catch((err) => paragraph.errMsg = err.message);
};
@@ -1369,8 +1372,18 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
return false;
};
+ $scope.enforceJoinOrderAvailable = (paragraph) => {
+ const cache = _.find($scope.caches, {name: paragraph.cacheName});
+
+ if (cache)
+ return !!_.find(cache.nodes, (node) => Version.includes(node.version, ...ENFORCE_JOIN_VERS));
+
+ return false;
+ };
+
$scope.execute = (paragraph, local = false) => {
const nonCollocatedJoins = !!paragraph.nonCollocatedJoins;
+ const enforceJoinOrder = !!paragraph.enforceJoinOrder;
$scope.actionAvailable(paragraph, true) && _chooseNode(paragraph.cacheName, local)
.then((nid) => {
@@ -1390,6 +1403,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
pageSize: paragraph.pageSize,
maxPages: paragraph.maxPages,
nonCollocatedJoins,
+ enforceJoinOrder,
localNid: local ? nid : null
};
@@ -1397,7 +1411,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
ActivitiesData.post({ action: '/queries/execute' });
- return agentMonitor.query(nid, args.cacheName, qry, nonCollocatedJoins, local, args.pageSize);
+ return agentMonitor.query(nid, args.cacheName, qry, nonCollocatedJoins, enforceJoinOrder, local, args.pageSize);
})
.then((res) => {
_processQueryResult(paragraph, true, res);
@@ -1450,7 +1464,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
ActivitiesData.post({ action: '/queries/explain' });
- return agentMonitor.query(nid, args.cacheName, args.query, false, false, args.pageSize);
+ return agentMonitor.query(nid, args.cacheName, args.query, false, !!paragraph.enforceJoinOrder, false, args.pageSize);
})
.then(_processQueryResult.bind(this, paragraph, true))
.catch((err) => {
@@ -1488,7 +1502,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
ActivitiesData.post({ action: '/queries/scan' });
- return agentMonitor.query(nid, args.cacheName, query, false, local, args.pageSize);
+ return agentMonitor.query(nid, args.cacheName, query, false, false, local, args.pageSize);
})
.then((res) => _processQueryResult(paragraph, true, res))
.catch((err) => {
@@ -1609,7 +1623,8 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
const args = paragraph.queryArgs;
return Promise.resolve(args.localNid || _chooseNode(args.cacheName, false))
- .then((nid) => agentMonitor.queryGetAll(nid, args.cacheName, args.query, !!args.nonCollocatedJoins, !!args.localNid))
+ .then((nid) => agentMonitor.queryGetAll(nid, args.cacheName, args.query, !!args.nonCollocatedJoins,
+ !!args.enforceJoinOrder, !!args.localNid))
.then((res) => _export(paragraph.name + '-all.csv', paragraph.gridOptions.columnDefs, res.columns, res.rows))
.catch(Messages.showError)
.then(() => paragraph.ace && paragraph.ace.focus());
http://git-wip-us.apache.org/repos/asf/ignite/blob/94c1e7cb/modules/web-console/frontend/public/stylesheets/style.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/public/stylesheets/style.scss b/modules/web-console/frontend/public/stylesheets/style.scss
index ab7e3dd..a07472e 100644
--- a/modules/web-console/frontend/public/stylesheets/style.scss
+++ b/modules/web-console/frontend/public/stylesheets/style.scss
@@ -809,7 +809,7 @@ button.form-control {
}
.btn-group {
- vertical-align:top;
+ vertical-align: top;
margin-left: 10px;
i { line-height: 18px; }
@@ -1854,6 +1854,12 @@ th[st-sort] {
display: inline-block;
}
+.panel-top-align {
+ label {
+ vertical-align: top !important;
+ }
+}
+
button.dropdown-toggle {
margin-right: 5px;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/94c1e7cb/modules/web-console/frontend/views/sql/sql.tpl.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/sql/sql.tpl.pug b/modules/web-console/frontend/views/sql/sql.tpl.pug
index 931d632..bc134a6 100644
--- a/modules/web-console/frontend/views/sql/sql.tpl.pug
+++ b/modules/web-console/frontend/views/sql/sql.tpl.pug
@@ -91,20 +91,31 @@ mixin paragraph-rename
input.form-control(id='paragraph-name-{{paragraph.id}}' ng-model='paragraph.editName' required ng-click='$event.stopPropagation();' ignite-on-enter='renameParagraph(paragraph, paragraph.editName)' ignite-on-escape='paragraph.edit = false')
mixin query-settings
- label.tipLabel(bs-tooltip data-placement='bottom' data-title='Configure periodical execution of last successfully executed query') Refresh rate:
- button.btn.btn-default.fa.fa-clock-o.tipLabel(ng-class='{"btn-info": paragraph.rate && paragraph.rate.installed}' bs-popover data-template-url='{{ $ctrl.paragraphRateTemplateUrl }}' data-placement='left' data-auto-close='1' data-trigger='click') {{rateAsString(paragraph)}}
-
- label.tipLabel(bs-tooltip data-placement='bottom' data-title='Max number of rows to show in query result as one page') Page size:
- button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.pageSize' bs-select bs-options='item for item in pageSizes')
-
- label.tipLabel(bs-tooltip data-placement='bottom' data-title='Limit query max results to specified number of pages') Max pages:
- button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.maxPages' bs-select bs-options='item.value as item.label for item in maxPages')
-
- label.tipLabel(ng-if='nonCollocatedJoinsAvailable(paragraph)' bs-tooltip data-placement='bottom' data-title='Non-collocated joins is a special mode that allow to join data across cluster without collocation.<br/>\
- Nested joins are not supported for now.<br/>\
- <b>NOTE</b>: In some cases it may consume more heap memory or may take a long time than collocated joins.' data-trigger='hover')
- input(type='checkbox' ng-model='paragraph.nonCollocatedJoins')
- span Allow non-collocated joins
+ .panel-top-align
+ label.tipLabel(bs-tooltip data-placement='bottom' data-title='Configure periodical execution of last successfully executed query') Refresh rate:
+ button.btn.btn-default.fa.fa-clock-o.tipLabel(ng-class='{"btn-info": paragraph.rate && paragraph.rate.installed}' bs-popover data-template-url='{{ $ctrl.paragraphRateTemplateUrl }}' data-placement='left' data-auto-close='1' data-trigger='click') {{rateAsString(paragraph)}}
+
+ label.tipLabel(bs-tooltip data-placement='bottom' data-title='Max number of rows to show in query result as one page') Page size:
+ button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.pageSize' bs-select bs-options='item for item in pageSizes')
+
+ label.tipLabel(bs-tooltip data-placement='bottom' data-title='Limit query max results to specified number of pages') Max pages:
+ button.btn.btn-default.select-toggle.tipLabel(ng-model='paragraph.maxPages' bs-select bs-options='item.value as item.label for item in maxPages')
+
+ .panel-tip-container
+ .row(ng-if='nonCollocatedJoinsAvailable(paragraph)')
+ label.tipLabel(bs-tooltip data-placement='bottom' data-title='Non-collocated joins is a special mode that allow to join data across cluster without collocation.<br/>\
+ Nested joins are not supported for now.<br/>\
+ <b>NOTE</b>: In some cases it may consume more heap memory or may take a long time than collocated joins.' data-trigger='hover')
+ input(type='checkbox' ng-model='paragraph.nonCollocatedJoins')
+ span Allow non-collocated joins
+ .row(ng-if='enforceJoinOrderAvailable(paragraph)')
+ label.tipLabel(bs-tooltip data-placement='bottom' data-title='Enforce join order of tables in the query.<br/>\
+ If <b>set</b> then query optimizer will not reorder tables in join.<br/>\
+ <b>NOTE:</b> It is not recommended to enable this property until you are sure that\
+ your indexes and the query itself are correct and tuned as much as possible but\
+ query optimizer still produces wrong join order.' data-trigger='hover')
+ input(type='checkbox' ng-model='paragraph.enforceJoinOrder')
+ span Enforce join order
mixin query-actions
button.btn.btn-primary(ng-disabled='!actionAvailable(paragraph, true)' ng-click='execute(paragraph)') Execute