aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorAlex Tatiyants <atatiyan@gmail.com>2016-01-06 21:33:50 -0800
committerAlex Tatiyants <atatiyan@gmail.com>2016-01-06 21:33:50 -0800
commit7363d83b6df50f6cd31f15aebe2ace95d13a2e00 (patch)
treea6d16de185a96dea4178b3fbe5ebd99655e03015 /app
parentf5b9496b6d2a5c3863214bde480247f2db7d5900 (diff)
improve syntax highlighting
Diffstat (limited to 'app')
-rw-r--r--app/components/plan-node/plan-node.html2
-rw-r--r--app/components/plan-node/plan-node.ts23
-rw-r--r--app/components/plan-view/plan-view.ts6
-rw-r--r--app/services/help-service.ts7
-rw-r--r--app/services/plan-service.ts1
-rw-r--r--app/services/syntax-highlight-service.ts27
6 files changed, 43 insertions, 23 deletions
diff --git a/app/components/plan-node/plan-node.html b/app/components/plan-node/plan-node.html
index a9295dd..55809ca 100644
--- a/app/components/plan-node/plan-node.html
+++ b/app/components/plan-node/plan-node.html
@@ -10,7 +10,7 @@
</span>
</header>
- <button *ngIf="plan.formattedQuery && !viewOptions.showCompactView" tooltip="view corresponding query"
+ <button *ngIf="plan.query && !viewOptions.showCompactView" tooltip="view corresponding query"
class="btn btn-sm btn-default btn-slim pull-right" (click)="showQuery = !showQuery">
<i class="fa fa-database"></i>
</button>
diff --git a/app/components/plan-node/plan-node.ts b/app/components/plan-node/plan-node.ts
index 87445fb..ce5f5db 100644
--- a/app/components/plan-node/plan-node.ts
+++ b/app/components/plan-node/plan-node.ts
@@ -74,27 +74,38 @@ export class PlanNode {
}
if (this.currentCompactView !== this.viewOptions.showCompactView) {
- this.currentCompactView = this.viewOptions.showCompactView;
- this.calculateBar();
+ this.currentCompactView = this.viewOptions.showCompactView;
+ this.calculateBar();
}
}
getFormattedQuery() {
var keyItems: Array<string> = [];
- var relationName = this.node[this._planService.RELATION_NAME_PROP];
+ // relation name will be highlighted for SCAN nodes
+ var relationName: string = this.node[this._planService.RELATION_NAME_PROP];
if (relationName) {
keyItems.push(this.node[this._planService.SCHEMA_PROP] + '.' + relationName);
keyItems.push(' ' + relationName);
keyItems.push(' ' + this.node[this._planService.ALIAS_PROP] + ' ');
}
+ // group key will be highlighted for AGGREGATE nodes
var groupKey: Array<string> = this.node[this._planService.GROUP_KEY_PROP];
if (groupKey) {
- keyItems.push('BY</span> ' + groupKey.join(','));
- keyItems.push('BY</span> ' + groupKey.join(', '));
+ keyItems.push('GROUP BY ' + groupKey.join(','));
+ }
+
+ // hash condition will be highlighted for HASH JOIN nodes
+ var hashCondition: string = this.node[this._planService.HASH_CONDITION_PROP];
+ if (hashCondition) {
+ keyItems.push(hashCondition.replace('(', '').replace(')', ''));
+ }
+
+ if (this.node[this._planService.NODE_TYPE_PROP].toUpperCase() === 'LIMIT') {
+ keyItems.push('LIMIT');
}
- return this._syntaxHighlightService.highlightKeyItems(this.plan.formattedQuery, keyItems);
+ return this._syntaxHighlightService.highlight(this.plan.query, keyItems);
}
calculateBar() {
diff --git a/app/components/plan-view/plan-view.ts b/app/components/plan-view/plan-view.ts
index e1700ba..302d8ee 100644
--- a/app/components/plan-view/plan-view.ts
+++ b/app/components/plan-view/plan-view.ts
@@ -34,7 +34,7 @@ export class PlanView {
highlightTypes = HighlightType; // exposing the enum to the view
- constructor(private _planService: PlanService, routeParams: RouteParams, private _syntaxHighlightService: SyntaxHighlightService) {
+ constructor(private _planService: PlanService, routeParams: RouteParams) {
this.id = routeParams.get('id');
}
@@ -56,10 +56,6 @@ export class PlanView {
maxCost: this.rootContainer[this._planService.MAXIMUM_COSTS_PROP] || 0,
maxDuration: this.rootContainer[this._planService.MAXIMUM_DURATION_PROP] || 0
}
-
- // get syntax highlighted query
- this._syntaxHighlightService.init();
- this.plan.formattedQuery = this._syntaxHighlightService.highlight(this.plan.query);
}
ngOnInit() {
diff --git a/app/services/help-service.ts b/app/services/help-service.ts
index 8859c24..0195aff 100644
--- a/app/services/help-service.ts
+++ b/app/services/help-service.ts
@@ -12,11 +12,14 @@ export var NODE_DESCRIPTIONS = {
"NESTED LOOP": `merges two record sets by looping through every record in the first set and
trying to find a match in the second set. All matching records are returned.`,
"MERGE JOIN": `merges two record sets by first sorting them on a <strong>join key</strong>.`,
+ "HASH": `generates a hash table from the records in the input recordset. Hash is used by
+ <strong>Hash Join</strong>.`,
+ "HASH JOIN": `joins to record sets by hashing one of them (using a <strong>Hash Scan</scan>).`,
"AGGREGATE": `groups records together based on a GROUP BY or aggregate function (like <code>sum()</code>).`,
"HASHAGGREGATE": `groups records together based on a GROUP BY or aggregate function (like sum()). Hash Aggregate uses
a hash to first organize the records by a key.`,
- "SEQ SCAN": `finds relevant records by sequentially scanning the table. Seq Scans perform a single read operation
- (only the table is read).`,
+ "SEQ SCAN": `finds relevant records by sequentially scanning the input record set. When reading from a table,
+ Seq Scans (unlike Index Scans) perform a single read operation (only the table is read).`,
"INDEX SCAN": `finds relevant records based on an <strong>Index</strong>. Index Scans perform 2 read operations: one to
read the index and another to read the actual value from the table.`,
"INDEX ONLY SCAN": `finds relevant records based on an <strong>Index</strong>. Index Only Scans perform a single read operation
diff --git a/app/services/plan-service.ts b/app/services/plan-service.ts
index 2e56bac..bf74c38 100644
--- a/app/services/plan-service.ts
+++ b/app/services/plan-service.ts
@@ -19,6 +19,7 @@ export class PlanService {
SORT_KEY_PROP: string = 'Sort Key';
JOIN_TYPE_PROP: string = 'Join Type';
INDEX_NAME_PROP: string = 'Index Name';
+ HASH_CONDITION_PROP: string = 'Hash Cond';
// computed by pev
COMPUTED_TAGS_PROP: string = "*Tags";
diff --git a/app/services/syntax-highlight-service.ts b/app/services/syntax-highlight-service.ts
index d082bde..17f6e61 100644
--- a/app/services/syntax-highlight-service.ts
+++ b/app/services/syntax-highlight-service.ts
@@ -2,20 +2,29 @@
/// <reference path="lodash.d.ts" />
export class SyntaxHighlightService {
- init() {
+ OPEN_TAG: string = ' _OPEN_TAG_';
+ CLOSE_TAG: string = '_CLOSE_TAG_';
+
+ highlight(code: string, keyItems: Array<string>) {
hljs.registerLanguage('sql', LANG_SQL);
- }
- highlight(code) {
hljs.configure({
tabReplace: ' ', // 4 spaces
});
- return hljs.highlightAuto(code).value;
- }
- highlightKeyItems(value: string, keyItems: Array<string>) {
- _.each(keyItems, (keyItem) => { value = value.replace(keyItem, `<span class='code-key-item'>${keyItem}</span>`) })
- return value;
+ // prior to syntax highlighting, we want to tag key items in the raw code. making the
+ // query upper case and ensuring that all comma separated values have a space
+ // makes it simpler to find the items we're looing for
+ var result: string = code.toUpperCase().replace(', ', ',');
+ _.each(keyItems, (keyItem: string) => {
+ result = result.replace(keyItem.toUpperCase(), `${this.OPEN_TAG}${keyItem}${this.CLOSE_TAG}`)
+ });
+
+ result = hljs.highlightAuto(result).value;
+ result = result.replace(new RegExp(this.OPEN_TAG, 'g'), "<span class='code-key-item'>")
+ result = result.replace(new RegExp(this.CLOSE_TAG, 'g'), "</span>");
+
+ return result;
}
}
@@ -43,7 +52,7 @@ export var LANG_SQL = function(hljs) {
'authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile ' +
'before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float ' +
'binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound ' +
- 'buffer_cache buffer_pool build bulk by byte byteordermark bytes c cache caching call calling cancel ' +
+ 'buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel ' +
'capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base ' +
'char_length character_length characters characterset charindex charset charsetform charsetid check ' +
'checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close ' +