Emilio Jose Coronado Lopez has uploaded a new change for review.

  https://asterix-gerrit.ics.uci.edu/2786

Change subject: [DAS]
......................................................................

[DAS]

Change-Id: I8e18e8b8af044f651bf2881a4427ffd3bc17d4b6
---
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.scss
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.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.ts
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/query.reducer.ts
M 
asterixdb/asterix-dashboard/src/node/src/app/shared/services/async-query.service.ts
17 files changed, 224 insertions(+), 75 deletions(-)


  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/86/2786/1

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..f709031 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,34 +20,47 @@
             <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>
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..c143aa4 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 {
@@ -148,11 +154,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 +182,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() {
@@ -192,18 +209,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 +235,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 +249,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 +307,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 +324,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,7 +366,10 @@
 
     dataverseSelected() {
         if (this.selected == undefined) {
+            this.queryString = 'None';
+        } else if (this.selected === 'None') {
             this.queryString = '';
+            this.selected = 'None';
         } else {
             this.queryString = 'Use ' + this.selected + '; ';
         }
@@ -345,6 +377,20 @@
         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) {
           this.currentHistory++;
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..e79f2ce 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
@@ -20,6 +20,7 @@
 .header {
     font-size: 1.0rem;
     font-weight: 500;
+    //color: rgb(145, 152, 158);
     color: blue;
     border-bottom: 1px solid rgb(145, 152, 158);
 }
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..d8f7066 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,10 +18,10 @@
             <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>
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..fa629f0 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'];
+                    }
                 }
             }
 
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..17f167a 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
@@ -11,6 +11,8 @@
 See the License for the specific language governing permissions and
 limitations under the License.
 */-->
+<!--<svg id='mysvg{{level}}{{item}}{{subplan}}{{planName}}' 
xmlns="http://www.w3.org/2000/svg"; xmlns:xlink="http://www.w3.org/1999/xlink";
+width="50px" height="50px" viewBox="0 0 50 50" preserveAspectRatio="xMidYMid 
meet"></svg> -->
 <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>
@@ -69,8 +71,18 @@
 
   </style>
   <text class="operation-text" x="50%" y="50%" 
text-anchor="middle">{{getNodeOperatorId()}} : {{getNodeName()}}</text>
+  <!--<line x1="0" y1="30" x2="200" y2="30" stroke="blue" /> -->
+  <!--<text  class="operation-details" x="50%" y="50" 
text-anchor="middle">{{details}}</text> -->
 </svg>
 
+<!--<svg id='node{{level}}{{item}}{{subplan}}{{planName}}' 
xmlns="http://www.w3.org/2000/svg"; xml:lang="en" class="dot"
+     xmlns:xlink="http://www.w3.org/1999/xlink";
+     width="10px" height="50px">
+    <title>Connection</title>
+    <circle cx="5" cy="5" r="5"/>
+    <line x1="5" y1="10" x2="5" y2="50" stroke="blue" />
+    <circle cx="5" cy="45" r="5"/>
+</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>
@@ -79,3 +91,9 @@
     <plan-node-svg class="" [planName]="planName" [node]="subNode" 
[level]="level+1" [item]="i" [subplan]="subplan" 
[viewParams]="viewParams"></plan-node-svg>
   </li>
 </div>
+
+<!--
+<div class="merge" *ngIf="checkMerge()">
+  <P>MERGE WITH</P>
+  <P>{{node['mergeWith']}} : {{node['mergeOpName'].toUpperCase()}}</P>
+</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..0295b8f 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">
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..da8f11a 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;
+        }
        }
 
     /*
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..05cf4fa 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>
@@ -54,7 +54,7 @@
                 </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>
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..e42c73a 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
@@ -99,7 +99,9 @@
     font-size: 14px;
     color: blue;
     border-radius: 4px;
+    // padding: 10px;
     height: 40px;
+    // background-color: #8CCDD1;
 }
 
 .back-button {
@@ -107,6 +109,7 @@
     position: fixed;
     bottom: 50px;
     right: 100px;
+    //padding: .5em;
     font-size: 14px;
 }
 
@@ -138,4 +141,4 @@
 
 .cell {
     padding-left: 15px;
-}
+}
\ 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..a6d8052 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
@@ -329,4 +329,12 @@
     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/query.reducer.ts 
b/asterixdb/asterix-dashboard/src/node/src/app/shared/reducers/query.reducer.ts
index 8dc67a0..05e039f 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 },
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))
     }

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/2786
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8e18e8b8af044f651bf2881a4427ffd3bc17d4b6
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: release-0.9.4-pre-rc
Gerrit-Owner: Emilio Jose Coronado Lopez <[email protected]>

Reply via email to