Emilio Jose Coronado Lopez has uploaded a new change for review. https://asterix-gerrit.ics.uci.edu/2936
Change subject: commit 2705d8a6966db15ce36a34dcf65ed5c4423290b7 Author: Emilio Jose Coronado Lopez <[email protected]> Date: Fri Jul 20 11:22:01 2018 +0900 ...................................................................... commit 2705d8a6966db15ce36a34dcf65ed5c4423290b7 Author: Emilio Jose Coronado Lopez <[email protected]> Date: Fri Jul 20 11:22:01 2018 +0900 [NO ISSUE] Asterixdb-dashboard: Plan Format| Flat Nested Objects on Table Plan Format: JSON | STRING Flat Nested Objects Change-Id: I7a27a5576ae21b6fda440bfc281d25e62638515c --- M asterixdb/asterix-dashboard/src/node/src/app/app.component.html M asterixdb/asterix-dashboard/src/node/src/app/dashboard/appbar.component.html M asterixdb/asterix-dashboard/src/node/src/app/dashboard/appbar.component.ts M asterixdb/asterix-dashboard/src/node/src/app/dashboard/apptab.component.scss M asterixdb/asterix-dashboard/src/node/src/app/dashboard/apptab.component.ts M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.html M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.scss M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.ts M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata-inspector.component.html M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata-inspector.component.scss M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.html M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.scss M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.ts M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.html M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.scss M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.ts M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-node-svg.component.html M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.html M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.scss M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.ts M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/query-container.component.html M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/query-container.component.scss M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-node.component.scss M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-node.component.ts M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.html M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.scss M asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.ts M asterixdb/asterix-dashboard/src/node/src/app/shared/effects/query.effects.ts M asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/dataverse.reducer.ts M asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/index.reducer.ts M asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/query.reducer.ts M asterixdb/asterix-dashboard/src/node/src/app/shared/services/async-query.service.ts M asterixdb/asterix-dashboard/src/node/src/styles/_constants.scss 33 files changed, 362 insertions(+), 176 deletions(-) git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/36/2936/1 diff --git a/asterixdb/asterix-dashboard/src/node/src/app/app.component.html b/asterixdb/asterix-dashboard/src/node/src/app/app.component.html index 58481be..4bb54c0 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/app.component.html +++ b/asterixdb/asterix-dashboard/src/node/src/app/app.component.html @@ -12,4 +12,4 @@ limitations under the License. */--> <awc-bar></awc-bar> -<awc-tab></awc-tab> +<awc-tab></awc-tab> \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/appbar.component.html b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/appbar.component.html index 290fd55..45e3008 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/appbar.component.html +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/appbar.component.html @@ -12,7 +12,6 @@ limitations under the License. */ --> <header class="awc-navbar"> - <mat-divider [vertical]="true"></mat-divider> <a routerLink="/" aria-label="AsterixDB Web Console"> <img class="awc-asterixDB-logo" src="./assets/asterixdb_tm.png" alt="AsterixDB"> </a> @@ -34,6 +33,9 @@ <a mat-button class="menu awc-button docs-navbar-hide-small" href="https://github.com/apache/asterixdb/" aria-label="GITHUB"> GITHUB </a> + <a mat-button class="menu awc-button docs-navbar-hide-small" aria-label="METADATA" (click)='showMetadata()'> + METADATA + </a> </div> </nav> -</header> +</header> \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/appbar.component.ts b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/appbar.component.ts index 7df060a..c399883 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/appbar.component.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/appbar.component.ts @@ -12,6 +12,8 @@ limitations under the License. */ import { Component } from '@angular/core'; +import { Store } from '@ngrx/store'; +import * as appActions from '../shared/actions/app.actions' @Component({ moduleId: module.id, @@ -20,4 +22,13 @@ styleUrls: ['appbar.component.scss'] }) -export class AppBarComponent {} \ No newline at end of file +export class AppBarComponent { + sideMenuVisible = false; + + constructor(private store: Store <any> ) {} + + showMetadata() { + this.sideMenuVisible = !this.sideMenuVisible; + this.store.dispatch(new appActions.setSideMenuVisible(this.sideMenuVisible)); + } +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/apptab.component.scss b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/apptab.component.scss index e827432..c14f327 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/apptab.component.scss +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/apptab.component.scss @@ -35,4 +35,4 @@ color: white; } background-color: blue; -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/apptab.component.ts b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/apptab.component.ts index db53f55..d176bab 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/apptab.component.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/apptab.component.ts @@ -20,5 +20,5 @@ }) export class AppTabComponent { - constructor() {}; + constructor() {} } \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.html b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.html index 86e9927..d410ff1 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.html +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.html @@ -20,38 +20,50 @@ <mat-spinner *ngIf="querySpinnerVisible" [color]="blue" [diameter]="15" class="spinner"></mat-spinner> </mat-panel-title> </mat-expansion-panel-header> - <mat-panel-description class="content-area"> - <div class='dataverses'> - <div>SELECT DATAVERSE:</div> - <mat-form-field> - <mat-select [(ngModel)]="selected" (selectionChange)="dataverseSelected()"> - <!-- <mat-option [value]='none'>None</mat-option> --> - <mat-option *ngFor="let dataverse of dataverses" [value]="dataverse.DataverseName"> - {{dataverse.DataverseName}} - </mat-option> - </mat-select> - </mat-form-field> + <mat-panel-description class="contentarea"> + <div class='options'> + <div class='dataverses'> + <div class='d1'> + <mat-form-field> + <mat-select placeholder="USE DATAVERSE" [(ngModel)]="selected" (selectionChange)="dataverseSelected()"> + <mat-option value='None'>None</mat-option> + <mat-option *ngFor="let dataverse of dataverses" [value]="dataverse.DataverseName"> + {{dataverse.DataverseName}} + </mat-option> + </mat-select> + </mat-form-field> + </div> + <div class='d1'> + <mat-form-field> + <mat-select placeholder="PLAN FORMAT" [(ngModel)]="formatOptions"> + <mat-option value="JSON">JSON</mat-option> + <mat-option value="STRING">STRING</mat-option> + </mat-select> + </mat-form-field> + </div> + <div class='d1'> + <mat-form-field class='sql-history'> + <mat-select placeholder="SQL++ HISTORY" [(ngModel)]="historyStringSelected" (selectionChange)="historySelected()"> + <mat-option *ngFor="let query of history" [value]="query">{{query}}</mat-option> + </mat-select> + </mat-form-field> + </div> + </div> </div> <div class="codemirror-container"> <textarea class="code" #editor></textarea> </div> - <div class="history"> - <div>HISTORY ({{viewCurrentHistory}}/{{history.length}})</div> - <button mat-button class='input-button' (click)="onClickNextHistory()" matTooltip="History: Next"><mat-icon>keyboard_arrow_up</mat-icon></button> - <button mat-button class='input-button' (click)="onClickPrevHistory()" matTooltip="History: Prev"><mat-icon>keyboard_arrow_down</mat-icon></button> - </div> </mat-panel-description> + <div class="message"> + <span *ngIf="querySuccess" class="metrics">{{metricsString}}</span> + <span *ngIf="queryError" class="queryErrorMessage">{{queryErrorMessageString}}</span> + </div> <mat-action-row> - <div class="message"> - <span *ngIf="querySuccess" class="metrics">{{metricsString}}</span> - <span *ngIf="queryError" class="queryErrorMessage">{{queryErrorMessageString}}</span> - </div> <div class="space"></div> - <button mat-button class='input-button' (click)="onClickNew()" matTooltip="New Query Input">NEW INPUT</button> + <button mat-button class='input-button' (click)="onClickNew()" matTooltip="New Query Input">NEW</button> <button mat-button class='input-button' (click)="onClickClear()" matTooltip="Clear Query Input">CLEAR</button> <button mat-button class='input-button run' (click)="onClickRun()" matTooltip="Execute Query Input">RUN</button> <button mat-button class='input-button' (click)="onClickPrevious()" [disabled]="checkPrevious()" matTooltip="Previous Query Input">PREVIOUS</button> <button mat-button class='input-button' (click)="onClickNext()" [disabled]="checkNext()" matTooltip="Next Query Input">NEXT</button> - <button mat-button class='input-button' (click)="onClickMetadata()" [disabled]="" matTooltip="Next Query Input">METADATA</button> </mat-action-row> </mat-expansion-panel> \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.scss b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.scss index 04b4eb3..aa66fb9 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.scss +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.scss @@ -38,8 +38,14 @@ border-bottom: 1px solid gray; } -.content-area { - //min-height: 130px; +.contentarea { + display: flex; + flex-flow: column; +} + +.options { + display: flex; + flex-flow: row; } .codemirror-container { @@ -54,6 +60,10 @@ .input-button { font-size: 12px !important; +} + +.message { + margin-top: 30px; } .metrics { @@ -71,6 +81,7 @@ .queryErrorMessage { color: rgba(209, 54, 54, 0.87); + font-size: 14px !important; word-break: break-all; font-size: 1.0rem; font-weight: 500; @@ -83,19 +94,34 @@ } .dataverses { + display: flex; + flex-flow: row; + width: 100%; margin-top: 15px; margin-right: 15px; font-size: 0.80rem !important; font-weight: 500 !important; } +.d1 { + margin-right: 15px; +} + +.flex-spacer { + flex: 1 1 20%; +} + .history { display: flex; - flex-flow: column; + flex-flow: row; align-items: center; width: 88px; margin-top: 15px; margin-left: 15px; font-size: 0.80rem !important; font-weight: 500 !important; +} + +.sql-history { + width: 500px !important; } \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.ts b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.ts index d17c28a..7702db7 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/input.component.ts @@ -48,6 +48,8 @@ queryErrorMessages: {}; queryPrepared$: Observable <any> ; queryPrepared: {}; + queryPlanFormats$: Observable <any> ; + queryPlanFormats: {}; preparedQueryCount: number; previousDisabled = true; nextDisabled = true; @@ -56,13 +58,16 @@ dataverses$: Observable<any>; dataverses: any; defaultDataverse = 'Default'; - selected = 'Default'; + selected = 'None'; history = []; currentHistory = 0; viewCurrentHistory = 0; // for the view sideMenuVisible$: Observable<any>; sideMenuVisible: any; none = 'None'; + planFormat = 'JSON'; + historyStringSelected = ''; + formatOptions = 'JSON'; /* Codemirror configuration */ codemirrorConfig = { mode: "asterix", @@ -109,7 +114,8 @@ // Initialize Query Editor, prepare the default query this.queryPrepare = { editorId: String(this.currentQuery), - queryString: this.queryString + queryString: this.queryString, + planFormat: this.planFormat }; this.store.dispatch(new sqlQueryActions.PrepareQuery(this.queryPrepare)); } else { @@ -131,6 +137,7 @@ this.metricsString = "SUCCESS: "; this.metricsString += " Execution time: " + this.queryMetrics[this.currentQuery].executionTime; this.metricsString += " Elapsed time: " + this.queryMetrics[this.currentQuery].elapsedTime; + this.metricsString += " Size: " + (this.queryMetrics[this.currentQuery].resultSize/1024).toFixed(2) + ' Kb'; } } else { this.queryMetrics = {}; @@ -148,11 +155,22 @@ } }) + /* Watching for SQL Input Errors: Error Message stored in Query Cache */ + this.queryPlanFormats$ = this.store.select(s => s.sqlQuery.sqlQueryPlanFormatHash); + this.queryPlanFormats$.subscribe((data: any) => { + if (data) { + this.queryPlanFormats = data; + } else { + this.queryPlanFormats = {}; + } + }) + this.preparedQueryCount = 0; // Initialize Query Editor, prepare the default query this.queryPrepare = { editorId: String(this.currentQuery), - queryString: this.queryString + queryString: this.queryString, + planFormat: this.formatOptions }; this.store.dispatch(new sqlQueryActions.PrepareQuery(this.queryPrepare)); // lets inform other views what's the current SQL editor @@ -165,9 +183,9 @@ this.dataverses$ = this.store.select(s => s.dataverse.dataverses.results); this.dataverses$.subscribe((data: any[]) => { this.dataverses = data; - this.defaultDataverse = 'KAMON' + this.defaultDataverse = '' }); - this.store.dispatch(new dataverseActions.SelectDataverses('-')); + this.store.dispatch(new dataverseActions.SelectDataverses('-'), ); } showMetrics() { @@ -176,6 +194,7 @@ this.metricsString = "SUCCESS: "; this.metricsString += " Execution time: " + this.queryMetrics[this.currentQuery].executionTime; this.metricsString += " Elapsed time: " + this.queryMetrics[this.currentQuery].elapsedTime; + this.metricsString += " Size: " + (this.queryMetrics[this.currentQuery].resultSize/1024).toFixed(2) + ' Kb'; this.querySuccess = true; } } @@ -192,18 +211,23 @@ } } - getQueryResults(queryString: string) { + getQueryResults(queryString: string, planFormat: string) { let QueryOrder = this.currentQuery; this.queryRequest = { requestId: String(QueryOrder), - queryString: queryString + queryString: queryString, + planFormat: planFormat }; this.store.dispatch(new sqlQueryActions.ExecuteQuery(this.queryRequest)); this.querySpinnerVisible = true; } onClickRun() { - this.getQueryResults(this.queryString); // .replace(/\n/g, " ")); + let planFormat = this.formatOptions; + this.getQueryResults(this.queryString, planFormat); // .replace(/\n/g, " ")); + if (this.history.length === 0) { + this.history.push('Clear'); + } this.history.push(this.queryString); this.currentHistory = this.history.length - 1; this.viewCurrentHistory = this.history.length; @@ -213,7 +237,8 @@ // Saving first this.queryPrepare = { editorId: String(this.currentQuery), - queryString: this.queryString + queryString: this.queryString, + planFormat: this.formatOptions }; this.store.dispatch(new sqlQueryActions.PrepareQuery(this.queryPrepare)); // Prepare a new Query String, cleanup screen messages @@ -226,25 +251,28 @@ this.queryError = false; this.queryPrepare = { editorId: String(this.currentQuery), - queryString: "" + queryString: "", + planFormat: this.formatOptions }; this.store.dispatch(new sqlQueryActions.PrepareQuery(this.queryPrepare)); // lets inform other views what's the current SQL editor let currentQueryIndex = String(this.currentQuery); this.store.dispatch(new appActions.setEditorIndex(currentQueryIndex)); - this.dataverseSelected(); + this.selected = "None"; this.editor.focus(); } onClickClear() { let queryClear = { editorId: String(this.currentQuery), - queryString: "" + queryString: "", + planFormat: "JSON" }; this.store.dispatch(new sqlQueryActions.CleanQuery(queryClear)); this.queryErrorMessageString = ""; this.queryString = ""; this.metricsString = ""; + this.dataverseSelected(); this.editor.getDoc().setValue(this.queryString); this.editor.focus(); } @@ -281,10 +309,10 @@ // Saving First this.queryPrepare = { editorId: String(this.currentQuery), - queryString: this.queryString + queryString: this.queryString, + planFormat: this.formatOptions }; this.store.dispatch(new sqlQueryActions.PrepareQuery(this.queryPrepare)); - this.currentQuery = this.currentQuery + next; this.queryErrorMessageString = ""; this.metricsString = ""; @@ -298,6 +326,9 @@ // Retrieve the prepared SQL string this.queryString = this.queryPrepared[this.currentQuery]; this.editor.getDoc().setValue(this.queryString); + + // Retrieve the prepared SQL plan Format + this.formatOptions = this.queryPlanFormats[this.currentQuery]; // lets inform other views what's the current SQL editor let currentQueryIndex = String(this.currentQuery); @@ -337,13 +368,30 @@ dataverseSelected() { if (this.selected == undefined) { + this.queryString = 'None'; + } else if (this.selected === 'None') { this.queryString = ''; + this.selected = 'None'; } else { this.queryString = 'Use ' + this.selected + '; '; } this.editor.getDoc().setValue(this.queryString); this.editor.focus(); } + + historySelected() { + if (this.historyStringSelected == undefined) { + this.historyStringSelected = ''; + } else if (this.historyStringSelected === 'Clear') { + this.history = []; + this.historyStringSelected = ''; + } + this.queryString = this.historyStringSelected; + this.editor.getDoc().setValue(this.queryString); + this.editor.focus(); + } + + planFormatSelected() {} onClickNextHistory() { if (this.currentHistory < this.history.length - 1) { @@ -364,9 +412,4 @@ this.editor.focus(); } } - - onClickMetadata() { - this.sideMenuVisible = !this.sideMenuVisible; - this.store.dispatch(new appActions.setSideMenuVisible(this.sideMenuVisible)); - } -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata-inspector.component.html b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata-inspector.component.html index cd38636..e8869ca 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata-inspector.component.html +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata-inspector.component.html @@ -19,4 +19,4 @@ <mat-action-row> <button mat-button class='input-button' (click)="onClickClose()">CLOSE</button> </mat-action-row> -</div> +</div> \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata-inspector.component.scss b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata-inspector.component.scss index fd6f01d..0ca0461 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata-inspector.component.scss +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata-inspector.component.scss @@ -27,4 +27,4 @@ .content { margin-left: auto !important; margin-right: auto !important; -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.html b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.html index 056ff44..386520b 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.html +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.html @@ -60,4 +60,4 @@ {{index.IndexName}}</li> </section> </mat-expansion-panel> -</div> +</div> \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.scss b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.scss index 6cd5966..b79d774 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.scss +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.scss @@ -87,4 +87,4 @@ display: flex; flex-flow: row; align-items: center; -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.ts b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.ts index 2271dda..99c470c 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/metadata.component.ts @@ -163,4 +163,4 @@ onClickClose() { this.dialogCreateDsRef.close(); } -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.html b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.html index 01a4a0a..e95752e 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.html +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.html @@ -18,11 +18,11 @@ <tree-view [data]="data" [queryId]="queryId"></tree-view> </div> <div *ngIf='queryOptimizedLogicalPlan != ""'> - <plan-view [jsonPlan]="queryOptimizedLogicalPlan" [plan]="optimalLogicalPlan" [planName]="'OPTIMIZED PLAN'"></plan-view> + <plan-view [planFormat]="planFormat" [jsonPlan]="queryOptimizedLogicalPlan" [plan]="optimalLogicalPlan" [planName]="'OPTIMIZED PLAN'"></plan-view> </div> <div *ngIf='queryLogicalPlan != ""'> - <plan-view [jsonPlan]="queryLogicalPlan" [plan]="logicalPlan" [planName]="'LOGICAL PLAN'"></plan-view> + <plan-view [planFormat]="planFormat" [jsonPlan]="queryLogicalPlan" [plan]="logicalPlan" [planName]="'LOGICAL PLAN'"></plan-view> </div> </div> </mat-card-content> -</mat-card> +</mat-card> \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.scss b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.scss index e55a5a5..67431c8 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.scss +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.scss @@ -31,4 +31,4 @@ .divider { width: 100%; -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.ts b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.ts index 196fbda..592e9b5 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/output.component.ts @@ -32,8 +32,12 @@ logicalPlan: any; optimalLogicalPlan: any; results$: Observable < any > ; + planFormat$: Observable < any > ; + planFormat: any; SQLresults: any; queryId: any = ""; + observedPlanFormat = ""; + constructor(private store: Store <any>) { let key = '1'; @@ -65,16 +69,28 @@ this.SQLresults = data; this.queryLogicalPlan = ""; this.queryOptimizedLogicalPlan = ""; + this.planFormat = "JSON"; if (this.SQLresults[queryId]) { // Extract the logical plan if (this.SQLresults[queryId]['plans']) { if (this.SQLresults[queryId]['plans']['logicalPlan']) { this.queryLogicalPlan = JSON.stringify(this.SQLresults[queryId]['plans']['logicalPlan'], null, 8); this.logicalPlan = this.SQLresults[queryId]['plans']['logicalPlan']; + this.planFormat = this.SQLresults[queryId]['planFormat']; + if (this.planFormat === 'JSON') { + this.queryLogicalPlan = JSON.stringify(this.SQLresults[queryId]['plans']['logicalPlan'], null, 8); + } else { + this.queryLogicalPlan = this.SQLresults[queryId]['plans']['logicalPlan']; + } } if (this.SQLresults[queryId]['plans']['optimizedLogicalPlan']) { - this.queryOptimizedLogicalPlan = JSON.stringify(this.SQLresults[queryId]['plans']['optimizedLogicalPlan'], null, 8); this.optimalLogicalPlan = this.SQLresults[queryId]['plans']['optimizedLogicalPlan']; + this.planFormat = this.SQLresults[queryId]['planFormat']; + if (this.planFormat === 'JSON') { + this.queryOptimizedLogicalPlan = JSON.stringify(this.SQLresults[queryId]['plans']['optimizedLogicalPlan'], null, 8); + } else { + this.queryOptimizedLogicalPlan = this.SQLresults[queryId]['plans']['optimizedLogicalPlan']; + } } } @@ -88,4 +104,4 @@ this.data = []; } } -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-node-svg.component.html b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-node-svg.component.html index 1ef741b..9901bc5 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-node-svg.component.html +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-node-svg.component.html @@ -12,70 +12,70 @@ limitations under the License. */--> <svg id='node{{level}}{{item}}{{subplan}}{{planName}}' xmlns="http://www.w3.org/2000/svg" xml:lang="en" xmlns:xlink="http://www.w3.org/1999/xlink" - width="200px" height="160px" class="plan-node" (click)="seeDetails(viewParams_)"> - <title>{{details}}</title> - <style> - @keyframes cycle { - 33.3% { - visibility: visible; - } - 100% { - visibility: hidden - } - } + width="200px" height="160px" class="plan-node" (click)="seeDetails(viewParams_)"> + <title>{{details}}</title> + <style> + @keyframes cycle { + 33.3% { + visibility: visible; + } + 100% { + visibility: hidden + } + } - .lit { - animation: cycle 9s step-start infinite; - } + .lit { + animation: cycle 9s step-start infinite; + } - .red .lit { - animation-delay: -3s; - } + .red .lit { + animation-delay: -3s; + } - .yellow .lit { - animation-delay: -6s; - } + .yellow .lit { + animation-delay: -6s; + } - .green .lit { - animation-delay: 0; - } + .green .lit { + animation-delay: 0; + } - .operation-text { - font-size: 12px; - font-family: Roboto, "Helvetica Neue", monospace; - fill: black; - } + .operation-text { + font-size: 12px; + font-family: Roboto, "Helvetica Neue", monospace; + fill: black; + } - .operation-see-more { - font-size: 12px; - font-family: Roboto, "Helvetica Neue", monospace; - fill: black; - cursor: pointer; - } + .operation-see-more { + font-size: 12px; + font-family: Roboto, "Helvetica Neue", monospace; + fill: black; + cursor: pointer; + } - .card { - cursor: pointer; - } + .card { + cursor: pointer; + } - .card:hover { - stroke: blue; - } + .card:hover { + stroke: blue; + } - .operation-details { - visibility: none; - transition: opacity 1s ease-in-out; - opacity: 0; - } + .operation-details { + visibility: none; + transition: opacity 1s ease-in-out; + opacity: 0; + } - </style> - <text class="operation-text" x="50%" y="50%" text-anchor="middle">{{getNodeOperatorId()}} : {{getNodeName()}}</text> -</svg> + </style> + <text class="operation-text" x="50%" y="50%" text-anchor="middle">{{getNodeOperatorId()}} : {{getNodeName()}}</text> + </svg> -<div class="branch" *ngIf="node.inputs"> - <li *ngIf="checkSubPlan()" class="li sub"> - <plan-node-svg class="sub" [planName]="planName" [node]="node.inputs[item].subplan[0]" [level]="0" [item]="0" [subplan]="level+item+subplan+1"></plan-node-svg> - </li> - <li class="li" *ngFor="let subNode of node.inputs; let i = index"> - <plan-node-svg class="" [planName]="planName" [node]="subNode" [level]="level+1" [item]="i" [subplan]="subplan" [viewParams]="viewParams"></plan-node-svg> - </li> + <div class="branch" *ngIf="node.inputs"> + <li *ngIf="checkSubPlan()" class="li sub"> + <plan-node-svg class="sub" [planName]="planName" [node]="node.inputs[item].subplan[0]" [level]="0" [item]="0" [subplan]="level+item+subplan+1"></plan-node-svg> + </li> + <li class="li" *ngFor="let subNode of node.inputs; let i = index"> + <plan-node-svg class="" [planName]="planName" [node]="subNode" [level]="level+1" [item]="i" [subplan]="subplan" [viewParams]="viewParams"></plan-node-svg> + </li> </div> diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.html b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.html index cda6cf5..3e43547 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.html +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.html @@ -12,15 +12,15 @@ limitations under the License. */ --> <div *ngIf="plan_" class="plan-graph" id={{planName}}> - <mat-expansion-panel hideToggle> + <mat-expansion-panel hideToggle [expanded]="true"> <mat-expansion-panel-header class="plan-header header-centered-v"> <mat-icon>assessment</mat-icon> <mat-panel-title>{{planName}}</mat-panel-title> <mat-panel-description></mat-panel-description> </mat-expansion-panel-header> <mat-panel-description class='content'> - <div class='panel'> - <button mat-button class='button' (click)="showJSON()" matTooltip="Toggle JSON or Graphic View">JSON</button> + <div *ngIf="!jsonButtonDisabled" class='panel'> + <button id='jsonButton' mat-button class='button' (click)="showJSON()" matTooltip="Toggle JSON or Graphic View">JSON</button> </div> <div class="divider"> <div *ngIf="!jsonVisible" class="plan"> @@ -34,4 +34,4 @@ </div> </mat-panel-description> </mat-expansion-panel> -</div> +</div> \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.scss b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.scss index 916620c..28dd380 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.scss +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.scss @@ -95,4 +95,4 @@ margin-left: auto; margin-right: auto; width: 50%; -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.ts b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.ts index e66ac5f..dd0ee6b 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/plan-view.component.ts @@ -13,6 +13,7 @@ export class PlanViewComponent { + @Input() planFormat: any; @Input() plan: any; @Input() planName: any; @Input() jsonPlan: any; @@ -21,25 +22,26 @@ numberOfLevels: number = 0; numberOfNodes: number = 0; jsonVisible = false; + jsonButtonDisabled = false; constructor() {} - ngOnInit() { - this.plan_ = this.plan; - /* find the number of nodes in the tree */ - let summary : planCount = {nodesCnt:0, levelsCnt:0} - summary = this.analyzePlan(this.plan_, summary); - this.numberOfLevels = summary.levelsCnt; - this.numberOfNodes = summary.nodesCnt; - } + ngOnInit() {} - ngOnChanges(changes: SimpleChange) { + ngOnChanges() { this.plan_ = this.plan; - /* find the number of nodes in the tree */ - let summary : planCount = {nodesCnt:0, levelsCnt:0} - summary = this.analyzePlan(this.plan_, summary); - this.numberOfLevels = summary.levelsCnt; - this.numberOfNodes = summary.nodesCnt; + /* If plan format is JSON analyze and augment for visualization */ + if (this.planFormat === 'JSON') { + let summary : planCount = {nodesCnt:0, levelsCnt:0} + summary = this.analyzePlan(this.plan_, summary); + this.numberOfLevels = summary.levelsCnt; + this.numberOfNodes = summary.nodesCnt; + this.jsonVisible = false; + this.jsonButtonDisabled = false; + } else { + this.jsonVisible = true; + this.jsonButtonDisabled = true; + } } /* @@ -110,4 +112,4 @@ } } } -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/query-container.component.html b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/query-container.component.html index 4aeaab5..a2e0d3e 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/query-container.component.html +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/query-container.component.html @@ -19,4 +19,4 @@ <div *ngIf="visible" class="drawer"> <awc-metadata></awc-metadata> </div> -</div> +</div> \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/query-container.component.scss b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/query-container.component.scss index 95e70e7..137721e 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/query-container.component.scss +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/query-container.component.scss @@ -52,4 +52,4 @@ width: 100%; margin: 0; padding: 0; -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-node.component.scss b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-node.component.scss index 3349a8e..0cfbbb5 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-node.component.scss +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-node.component.scss @@ -25,7 +25,7 @@ } .node-content{ - padding-top: 5px; + padding: 5px; border: 1px dashed gainsboro; } @@ -58,6 +58,8 @@ .value { color: blue; - padding: 5px; + padding: 15px; + padding-top: 5px; + padding-bottom: 5px; border: 1px dashed gainsboro; -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-node.component.ts b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-node.component.ts index 405d6ef..4bc947a 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-node.component.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-node.component.ts @@ -37,6 +37,7 @@ initData() { this.node_ = this.node; + // this.nodeChildren = this.node.children; } changeJsonPathValue(event) { @@ -101,4 +102,4 @@ return false; } } -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.html b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.html index 2488c3e..b037a11 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.html +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.html @@ -19,12 +19,12 @@ </mat-expansion-panel-header> <mat-panel-description class='content'> <div class='panel'> - <span class='summary' >Items: {{metrics.resultCount}} Size: {{metrics.resultSizeKb}} Kb</span> + <!--<span class='summary' >Items: {{metrics.resultCount}} Size: {{metrics.resultSizeKb}} Kb</span>--> <mat-paginator [showFirstLastButtons]="true" [length]='metrics.resultCount' [pageSize]='pagedefaults.pageSize' [pageSizeOptions]='pageSizeOptions' (page)='showResults($event, false)'> </mat-paginator> <span class='options'> - <button mat-button class='button' (click)='dataExpand()' matTooltip="Expand Data"><mat-icon>add_circle</mat-icon></button> - <button mat-button class='button' (click)='dataCollapse()' matTooltip="Collapse Data"><mat-icon>remove_circle_outline</mat-icon></button> + <button mat-button class='button' (click)='dataExpand()' [disabled]= 'checkView()' matTooltip="Expand Data"><mat-icon>add_circle</mat-icon></button> + <button mat-button class='button' (click)='dataCollapse()' [disabled]= 'checkView()' matTooltip="Collapse Data"><mat-icon>remove_circle_outline</mat-icon></button> <button mat-button class='button button-json' (click)='showTable()' matTooltip="Show Table View">TABLE</button> <button mat-button class='button button-json' (click)='showTree()' matTooltip="Show Tree View">TREE</button> <button mat-button class='button button-json' (click)='showJSON()' matTooltip="Show JSON View">JSON</button> @@ -37,7 +37,7 @@ </div> <div class='divider'> <div *ngIf='tableVisible'> - <table mat-table [dataSource]="dataSource" class='items-table'> + <table mat-table [dataSource]="dataSource" class='items-table table-responsive'> <ng-container matColumnDef="{{col}}" *ngFor="let col of displayedColumns"> <th mat-header-cell *matHeaderCellDef class='cell'>{{col}}</th> <td mat-cell *matCellDef="let element"class='cell' >{{element[col]}}</td> @@ -54,9 +54,9 @@ </div> <div id='bottom'></div> </div> - <button *ngIf='showGoTop' mat-fab color='warn' class='button back-button' (click)='gotoTop()'> + <button *ngIf='showGoTop' mat-fab color='primary' class='button back-button' (click)='gotoTop()'> <mat-icon>keyboard_arrow_up</mat-icon> </button> </mat-panel-description> </mat-expansion-panel> -</div> +</div> \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.scss b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.scss index effa0ad..1eb6c92 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.scss +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.scss @@ -52,7 +52,8 @@ font-size: 14px; border: 1px dashed gainsboro; padding-top: 20px; - padding-bottom: 20px + padding-bottom: 20px; + overflow: auto; } .content { @@ -99,7 +100,9 @@ font-size: 14px; color: blue; border-radius: 4px; + // padding: 10px; height: 40px; + // background-color: #8CCDD1; } .back-button { @@ -107,6 +110,7 @@ position: fixed; bottom: 50px; right: 100px; + //padding: .5em; font-size: 14px; } @@ -124,8 +128,8 @@ display: inline-flex; } -table { - width: 100%; +.items-table { + min-width: 100%; } tr.example-element-row:not(.example-expanded-row):hover { @@ -139,3 +143,34 @@ .cell { padding-left: 15px; } + +.table-responsive { + display: block; + width: 100%; + overflow-x: auto; + + .mat-table { + width: 100%; + max-width: 100%; + margin-bottom: 1rem; + display: table; + border-collapse: collapse; + margin: 0px; + } + + .mat-row, + .mat-header-row { + display: table-row; + } + + .mat-cell, + .mat-header-cell { + word-wrap: initial; + display: table-cell; + padding: 0px 5px; + line-break: unset; + white-space: nowrap; + overflow: hidden; + vertical-align: middle; + } +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.ts b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.ts index 823d994..96f73ad 100644 --- a/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/dashboard/query/tree-view.component.ts @@ -80,7 +80,7 @@ this.currentIndex = this.currentRange.pageIndex; this.treeData = this.rawData.filter(this.filter, this.currentRange); // Build the dynamic table column names - this.buildTableColums(this.treeData[0]); + this.buildTableColums(this.treeData); // Flat the results to display in a table this.flatDataforTable(this.treeData); @@ -286,16 +286,28 @@ * Build the table column names from result data */ displayedColumns: string[] = []; - buildTableColums(item) { - var resultKeyList = Object.keys(item); - var resultKey: string = resultKeyList[0]; - if (item[resultKey] instanceof Object) { - // is a SQL++ Query Results - var nestedKeyList = Object.keys(item[resultKey]); - this.displayedColumns = nestedKeyList; - } - else { // is a SQL++ Metadata Results and there is an Array - this.displayedColumns = resultKeyList; + buildTableColums(items) { + var itemsKeyList = Object.keys(items[0]); + var itemsKey: string = itemsKeyList[0]; + this.flattenData = []; + var len = 0; + if (items[0][itemsKey] instanceof Object) { + for (let i = 0; i < items.length; i++) { + var resultKeyList = Object.keys(items[i][itemsKey]); + var resultKey: string = resultKeyList[0]; + if (items[resultKey] instanceof Object) { + var nestedKeyList = Object.keys(items[resultKey]); + if (nestedKeyList.length > len ) { + this.displayedColumns = nestedKeyList; + len = nestedKeyList.length; + } + } else { // is a SQL++ Metadata Results and there is an Array + if (resultKeyList.length > len ) { + this.displayedColumns = resultKeyList; + len = resultKeyList.length; + } + } + } } } @@ -309,12 +321,14 @@ if (data[0][resultKey] instanceof Object) { for (let i = 0; i < data.length; i++) { var nestedKeyList = Object.keys(data[i][resultKey]); + this.flattenData[i] = {}; for (let k = 0; k < nestedKeyList.length; k++) { if ( typeof data[i][resultKey][nestedKeyList[k]] === 'object' ){ var nestedObjectStr = JSON.stringify(data[i][resultKey][nestedKeyList[k]], null, '\n'); + this.flattenData[i][nestedKeyList[k]] = nestedObjectStr; // Not Implemented Yet } else { - this.flattenData[i] = data[i][resultKey]; + this.flattenData[i][nestedKeyList[k]] = data[i][resultKey][nestedKeyList[k]]; } } } @@ -322,11 +336,18 @@ else { this.flattenData = data; } - this.dataSource.data = this.flattenData; } jsonTransform(item) { return JSON.stringify(item, null, 4); } + + checkView() { + if (!this.treeVisible) { + return true; + } else { + return false + } + } } \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/shared/effects/query.effects.ts b/asterixdb/asterix-dashboard/src/node/src/app/shared/effects/query.effects.ts index 0d209cd1..317211f 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/shared/effects/query.effects.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/shared/effects/query.effects.ts @@ -30,7 +30,7 @@ executeQuery$: Observable<Action> = this.actions .ofType(sqlQueryActions.EXECUTE_QUERY) .switchMap(query => { - return this.sqlService.executeSQLQuery((query as any).payload.queryString) + return this.sqlService.executeSQLQuery((query as any).payload.queryString, (query as any).payload.planFormat) .map(sqlQueryResult => new sqlQueryActions.ExecuteQuerySuccess(sqlQueryResult)) .catch(sqlQueryError => of(new sqlQueryActions.ExecuteQueryFail(sqlQueryError))); }); @@ -41,7 +41,7 @@ executeMetadataQuery$: Observable<Action> = this.actions .ofType(sqlQueryActions.EXECUTE_METADATA_QUERY) .switchMap(query => { - return this.sqlService.executeSQLQuery((query as any).payload) + return this.sqlService.executeSQLQuery((query as any).payload, (query as any).payload.planFormat) .map(sqlMetadataQueryResult => new sqlQueryActions.ExecuteMetadataQuerySuccess(sqlMetadataQueryResult)) .catch(sqlMetadataQueryError => of(new sqlQueryActions.ExecuteMetadataQueryFail(sqlMetadataQueryError))); }); diff --git a/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/dataverse.reducer.ts b/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/dataverse.reducer.ts index 28f6a58..bc4fbcf 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/dataverse.reducer.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/dataverse.reducer.ts @@ -176,4 +176,4 @@ default: return state; } -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/index.reducer.ts b/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/index.reducer.ts index 7d8dd33..42b2104 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/index.reducer.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/index.reducer.ts @@ -162,4 +162,4 @@ default: return state; } -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/query.reducer.ts b/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/query.reducer.ts index 8dc67a0..408172b 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/query.reducer.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/query.reducer.ts @@ -25,7 +25,9 @@ successHash:{}, errorHash: {}, sqlQueryString: string, + sqlQueryPlanFormat: string, sqlQueryStringHash: {}, + sqlQueryPlanFormatHash: {}, sqlQueryResultHash: {}, sqlQueryErrorHash: {}, sqlQueryPrepared: {}, @@ -39,7 +41,9 @@ successHash:{}, errorHash: {}, sqlQueryString: "", + sqlQueryPlanFormat: "", sqlQueryStringHash: {}, + sqlQueryPlanFormatHash: {}, sqlQueryResultHash: {}, sqlQueryErrorHash: {}, sqlQueryPrepared: {}, @@ -60,6 +64,7 @@ sqlQueryErrorHash: state.sqlQueryErrorHash, sqlQueryResultHash: state.sqlQueryResultHash, sqlQueryStringHash: state.sqlQueryStringHash, + sqlQueryPlanFormatHash: { ...state.sqlQueryPlanFormatHash, [action.payload.editorId]: action.payload.planFormat }, sqlQueryMetrics: state.sqlQueryMetrics, currentRequestId: state.currentRequestId }); @@ -92,7 +97,9 @@ successHash: { ...state.successHash, [action.payload.requestId]: false }, errorHash: { ...state.errorHash, [action.payload.requestId]: false }, sqlQueryString: action.payload.queryString, + sqlQueryPlanFormat: action.payload.planFormat, sqlQueryStringHash: { ...state.sqlQueryStringHash, [action.payload.requestId]: action.payload.queryString }, + sqlQueryPlanFormatHash: { ...state.sqlQueryPlanFormatHash, [action.payload.requestId]: action.payload.planFormat }, sqlQueryResultHash: { ...state.sqlQueryResultHash, [action.payload.requestId]: [] }, sqlQueryErrorHash: { ...state.sqlQueryErrorHash, [action.payload.requestId]: [] }, sqlQueryMetrics: { ...state.sqlQueryMetrics, [action.payload.requestId]: [] }, @@ -105,11 +112,13 @@ * store */ case sqlQueryActions.EXECUTE_QUERY_SUCCESS: { + action.payload['planFormat'] = state.sqlQueryPlanFormat; return Object.assign({}, state, { loadingHash: { ...state.loadingHash, [state.currentRequestId]: false }, loadedHash: { ...state.loadedHash, [state.currentRequestId]: true }, successHash: { ...state.successHash, [state.currentRequestId]: true }, errorHash: { ...state.errorHash, [state.currentRequestId]: false }, + sqlQueryPlanFormatHash: state.sqlQueryPlanFormatHash, sqlQueryStringHash: { ...state.sqlQueryStringHash, [state.currentRequestId]: state.sqlQueryString }, sqlQueryResultHash: { ...state.sqlQueryResultHash, [state.currentRequestId]: action.payload }, sqlQueryErrorHash: { ...state.sqlQueryErrorHash, [state.currentRequestId]: [] }, @@ -123,11 +132,13 @@ * store */ case sqlQueryActions.EXECUTE_QUERY_FAIL: { + action.payload['planFormat'] = state.sqlQueryPlanFormat; return Object.assign({}, state, { loadingHash: { ...state.loadingHash, [state.currentRequestId]: false }, loadedHash: { ...state.loadedHash, [state.currentRequestId]: true }, successHash: { ...state.successHash, [state.currentRequestId]: false }, errorHash: { ...state.errorHash, [state.currentRequestId]: true }, + sqlQueryPlanFormatHash: state.sqlQueryPlanFormatHash, sqlQueryStringHash: { ...state.sqlQueryStringHash, [state.currentRequestId]: state.sqlQueryString }, sqlQueryResultHash: { ...state.sqlQueryResultHash, [state.currentRequestId]: [] }, sqlQueryErrorHash: { ...state.sqlQueryErrorHash, [state.currentRequestId]: action.payload.errors }, @@ -142,4 +153,4 @@ return state; } } -} +} \ No newline at end of file diff --git a/asterixdb/asterix-dashboard/src/node/src/app/shared/services/async-query.service.ts b/asterixdb/asterix-dashboard/src/node/src/app/shared/services/async-query.service.ts index 30463b5..5366531 100755 --- a/asterixdb/asterix-dashboard/src/node/src/app/shared/services/async-query.service.ts +++ b/asterixdb/asterix-dashboard/src/node/src/app/shared/services/async-query.service.ts @@ -35,6 +35,7 @@ */ @Injectable() export class SQLService { + defaultPlanFormat='JSON'; /* * SQLQueryService constructor using * HttpClient from Angular 5 @@ -47,7 +48,7 @@ */ selectDataverses() : Observable<any> { let query = "SELECT VALUE dv FROM Metadata.`Dataverse` dv" - return this.executeSQLQuery(query); + return this.executeSQLQuery(query, this.defaultPlanFormat); } /* @@ -56,7 +57,7 @@ */ selectDatasets() : Observable<any> { let query = "SELECT VALUE ds FROM Metadata.`Dataset` ds" - return this.executeSQLQuery(query); + return this.executeSQLQuery(query, this.defaultPlanFormat); } /* @@ -65,7 +66,7 @@ */ selectDatatypes() : Observable<any> { let query = "SELECT VALUE dt FROM Metadata.`Datatype` dt" - return this.executeSQLQuery(query); + return this.executeSQLQuery(query, this.defaultPlanFormat); } /* @@ -74,7 +75,7 @@ */ selectIndexes() : Observable<any> { let query = "SELECT VALUE ix FROM Metadata.`Index` ix" - return this.executeSQLQuery(query); + return this.executeSQLQuery(query, this.defaultPlanFormat); } /* @@ -174,7 +175,7 @@ status: string; login(username: string, password: string): Observable<boolean> */ - executeSQLQuery(query: string): Observable<any> { + executeSQLQuery(query: string, planFormat: string): Observable<any> { const apiUrl = AsterixRestApiUrl; const headers = new HttpHeaders(); headers.append('Content-Type', 'application/json'); @@ -182,7 +183,8 @@ return this.http.post(apiUrl, {statement: query, 'logical-plan': true, - 'optimized-logical-plan': true }, options) + 'optimized-logical-plan': true, + 'plan-format': planFormat }, options) .map((response: Response) => { return response; }) .catch((error: any) => this.handleExecuteQueryError(error)) } diff --git a/asterixdb/asterix-dashboard/src/node/src/styles/_constants.scss b/asterixdb/asterix-dashboard/src/node/src/styles/_constants.scss index f551ae8..923d254 100755 --- a/asterixdb/asterix-dashboard/src/node/src/styles/_constants.scss +++ b/asterixdb/asterix-dashboard/src/node/src/styles/_constants.scss @@ -13,6 +13,8 @@ */ @import '../../node_modules/@angular/material/theming'; +@import '~@angular/material/prebuilt-themes/deeppurple-amber.css'; + $small-breakpoint-width: 720px; /* For desktop, the content should be aligned with the page title. */ -- To view, visit https://asterix-gerrit.ics.uci.edu/2936 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7a27a5576ae21b6fda440bfc281d25e62638515c Gerrit-PatchSet: 1 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Emilio Jose Coronado Lopez <[email protected]>
