diff options
author | Alex Tatiyants <atatiyan@gmail.com> | 2016-01-06 21:33:50 -0800 |
---|---|---|
committer | Alex Tatiyants <atatiyan@gmail.com> | 2016-01-06 21:33:50 -0800 |
commit | 7363d83b6df50f6cd31f15aebe2ace95d13a2e00 (patch) | |
tree | a6d16de185a96dea4178b3fbe5ebd99655e03015 | |
parent | f5b9496b6d2a5c3863214bde480247f2db7d5900 (diff) |
improve syntax highlighting
-rw-r--r-- | app/components/plan-node/plan-node.html | 2 | ||||
-rw-r--r-- | app/components/plan-node/plan-node.ts | 23 | ||||
-rw-r--r-- | app/components/plan-view/plan-view.ts | 6 | ||||
-rw-r--r-- | app/services/help-service.ts | 7 | ||||
-rw-r--r-- | app/services/plan-service.ts | 1 | ||||
-rw-r--r-- | app/services/syntax-highlight-service.ts | 27 |
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 ' + |