diff --git a/src/sql/azdata.proposed.d.ts b/src/sql/azdata.proposed.d.ts
index bb4902e6e4..c2a4754c8c 100644
--- a/src/sql/azdata.proposed.d.ts
+++ b/src/sql/azdata.proposed.d.ts
@@ -1264,6 +1264,27 @@ declare module 'azdata' {
* Edges corresponding to the children.
*/
edges: ExecutionPlanEdge[];
+ /**
+ * Warning/parallelism badges applicable to the current node
+ */
+ badges: ExecutionPlanBadge[];
+ }
+
+ export interface ExecutionPlanBadge {
+ /**
+ * Type of the node overlay. This determines the icon that is displayed for it
+ */
+ type: BadgeType;
+ /**
+ * Text to display for the overlay tooltip
+ */
+ tooltip: string;
+ }
+
+ export enum BadgeType {
+ Warning = 0,
+ CriticalWarning = 1,
+ Parallelism = 2
}
export interface ExecutionPlanEdge {
diff --git a/src/sql/workbench/api/common/sqlExtHost.api.impl.ts b/src/sql/workbench/api/common/sqlExtHost.api.impl.ts
index 2ec19cc4ac..28f112d36f 100644
--- a/src/sql/workbench/api/common/sqlExtHost.api.impl.ts
+++ b/src/sql/workbench/api/common/sqlExtHost.api.impl.ts
@@ -593,6 +593,10 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp
}
};
+ const executionPlan: typeof azdata.executionPlan = {
+ BadgeType: sqlExtHostTypes.executionPlan.BadgeType
+ };
+
return {
version: initData.version,
accounts,
@@ -644,7 +648,8 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp
TabOrientation: sqlExtHostTypes.TabOrientation,
sqlAssessment,
TextType: sqlExtHostTypes.TextType,
- designers: designers
+ designers: designers,
+ executionPlan: executionPlan
};
},
extHostNotebook: extHostNotebook,
diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts
index b41ccdbbdc..4b3fe83601 100644
--- a/src/sql/workbench/api/common/sqlExtHostTypes.ts
+++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts
@@ -1031,3 +1031,11 @@ export namespace designers {
GraphNode = 'GraphNode'
}
}
+
+export namespace executionPlan {
+ export enum BadgeType {
+ Warning = 0,
+ CriticalWarning = 1,
+ Parallelism = 2
+ }
+}
diff --git a/src/sql/workbench/contrib/executionPlan/browser/constants.ts b/src/sql/workbench/contrib/executionPlan/browser/constants.ts
index e1845ed350..b1d0879a8d 100644
--- a/src/sql/workbench/contrib/executionPlan/browser/constants.ts
+++ b/src/sql/workbench/contrib/executionPlan/browser/constants.ts
@@ -249,6 +249,14 @@ export let executionPlanNodeIconPaths =
unionAll: imageBasePath + 'union_all.png'
};
+export const badgeIconPaths = {
+ warning: imageBasePath + 'badge_warning.svg',
+
+ parallelism: imageBasePath + 'badge_parallelism.svg',
+
+ criticalWarning: imageBasePath + 'badge_critical_warning.svg'
+};
+
const parentContainer = 'qps-container';
export const savePlanIconClassNames = [parentContainer, 'save-plan-icon'].join(' ');
export const openPropertiesIconClassNames = [parentContainer, 'open-properties-icon'].join(' ');
diff --git a/src/sql/workbench/contrib/executionPlan/browser/executionPlan.ts b/src/sql/workbench/contrib/executionPlan/browser/executionPlan.ts
index 75356b1e87..3c77278aa2 100644
--- a/src/sql/workbench/contrib/executionPlan/browser/executionPlan.ts
+++ b/src/sql/workbench/contrib/executionPlan/browser/executionPlan.ts
@@ -4,14 +4,15 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/executionPlan';
-import type * as azdata from 'azdata';
+import * as azdata from 'azdata';
+import * as sqlExtHostType from 'sql/workbench/api/common/sqlExtHostTypes';
import { IPanelView, IPanelTab } from 'sql/base/browser/ui/panel/panel';
import { localize } from 'vs/nls';
import { dispose } from 'vs/base/common/lifecycle';
import { ActionBar } from 'sql/base/browser/ui/taskbar/actionbar';
import * as DOM from 'vs/base/browser/dom';
import * as azdataGraphModule from 'azdataGraph';
-import { customZoomIconClassNames, openPlanFileIconClassNames, openPropertiesIconClassNames, openQueryIconClassNames, executionPlanNodeIconPaths, savePlanIconClassNames, searchIconClassNames, zoomInIconClassNames, zoomOutIconClassNames, zoomToFitIconClassNames } from 'sql/workbench/contrib/executionPlan/browser/constants';
+import { customZoomIconClassNames, openPlanFileIconClassNames, openPropertiesIconClassNames, openQueryIconClassNames, executionPlanNodeIconPaths, savePlanIconClassNames, searchIconClassNames, zoomInIconClassNames, zoomOutIconClassNames, zoomToFitIconClassNames, badgeIconPaths } from 'sql/workbench/contrib/executionPlan/browser/constants';
import { isString } from 'vs/base/common/types';
import { PlanHeader } from 'sql/workbench/contrib/executionPlan/browser/planHeader';
import { ExecutionPlanPropertiesView } from 'sql/workbench/contrib/executionPlan/browser/executionPlanPropertiesView';
@@ -362,12 +363,47 @@ export class ExecutionPlan implements ISashLayoutProvider {
}
}
+ if (node.badges) {
+ diagramNode.badges = [];
+ for (let i = 0; i < node.badges.length; i++) {
+ diagramNode.badges.push(this.getBadgeTypeString(node.badges[i].type));
+ }
+ }
+
if (node.description) {
diagramNode.description = node.description;
}
return diagramNode;
}
+ private getBadgeTypeString(badgeType: sqlExtHostType.executionPlan.BadgeType): {
+ type: string,
+ tooltip: string
+ } | undefined {
+ /**
+ * TODO: Need to figure out if tooltip have to be removed. For now, they are empty
+ */
+ switch (badgeType) {
+ case sqlExtHostType.executionPlan.BadgeType.Warning:
+ return {
+ type: 'warning',
+ tooltip: ''
+ };
+ case sqlExtHostType.executionPlan.BadgeType.CriticalWarning:
+ return {
+ type: 'criticalWarning',
+ tooltip: ''
+ };
+ case sqlExtHostType.executionPlan.BadgeType.Parallelism:
+ return {
+ type: 'parallelism',
+ tooltip: ''
+ };
+ default:
+ return undefined;
+ }
+ }
+
private populateEdges(edge: InternalExecutionPlanEdge, diagramEdge: any) {
diagramEdge.label = '';
const edgeId = this.createGraphElementId();
@@ -401,7 +437,7 @@ export class ExecutionPlan implements ISashLayoutProvider {
let graphRoot: azdata.executionPlan.ExecutionPlanNode = this._graphModel.root;
this.populate(graphRoot, diagramRoot);
- this.azdataGraphDiagram = new azdataGraph.azdataQueryPlan(container, diagramRoot, executionPlanNodeIconPaths);
+ this.azdataGraphDiagram = new azdataGraph.azdataQueryPlan(container, diagramRoot, executionPlanNodeIconPaths, badgeIconPaths);
this.azdataGraphDiagram.graph.setCellsMovable(false); // preventing drag and drop of graph nodes.
this.azdataGraphDiagram.graph.setCellsDisconnectable(false); // preventing graph edges to be disconnected from source and target nodes.
@@ -435,7 +471,6 @@ export class ExecutionPlan implements ISashLayoutProvider {
});
}
-
public set graphModel(graph: azdata.executionPlan.ExecutionPlanGraph | undefined) {
this._graphModel = graph;
if (this._graphModel) {
diff --git a/src/sql/workbench/contrib/executionPlan/browser/images/icons/badge_critical_warning.svg b/src/sql/workbench/contrib/executionPlan/browser/images/icons/badge_critical_warning.svg
new file mode 100644
index 0000000000..1d4645ac4b
--- /dev/null
+++ b/src/sql/workbench/contrib/executionPlan/browser/images/icons/badge_critical_warning.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/sql/workbench/contrib/executionPlan/browser/images/icons/badge_parallel_process.svg b/src/sql/workbench/contrib/executionPlan/browser/images/icons/badge_parallel_process.svg
new file mode 100644
index 0000000000..4bd3c09d58
--- /dev/null
+++ b/src/sql/workbench/contrib/executionPlan/browser/images/icons/badge_parallel_process.svg
@@ -0,0 +1,19 @@
+
+
+
diff --git a/src/sql/workbench/contrib/executionPlan/browser/images/icons/badge_warning.svg b/src/sql/workbench/contrib/executionPlan/browser/images/icons/badge_warning.svg
new file mode 100644
index 0000000000..9aa86d6e54
--- /dev/null
+++ b/src/sql/workbench/contrib/executionPlan/browser/images/icons/badge_warning.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/sql/workbench/contrib/executionPlan/browser/media/executionPlan.css b/src/sql/workbench/contrib/executionPlan/browser/media/executionPlan.css
index 0fc7fca29f..3473e96518 100644
--- a/src/sql/workbench/contrib/executionPlan/browser/media/executionPlan.css
+++ b/src/sql/workbench/contrib/executionPlan/browser/media/executionPlan.css
@@ -106,6 +106,7 @@ However we always want it to be the width of the container it is resizing.
width: 100%;
height: 100%;
overflow: scroll;
+ position: relative;
}
/* Properties view in execution plan */