diff --git a/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/Contracts/ExecutionPlanGraph.cs b/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/Contracts/ExecutionPlanGraph.cs
index 7744840b..49a3ea9f 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/Contracts/ExecutionPlanGraph.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/Contracts/ExecutionPlanGraph.cs
@@ -63,7 +63,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.Contracts
///
public double RelativeCost { get; set; }
///
- /// Time take by the node operation in milliseconds
+ /// Time taken by the node operation in milliseconds
///
public long? ElapsedTimeInMs { get; set; }
///
@@ -92,6 +92,22 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.Contracts
/// Top operations table data for the node
///
public List TopOperationsData { get; set; }
+ ///
+ /// The cost metrics for the node.
+ ///
+ public List CostMetrics { get; set; }
+ }
+
+ public class CostMetric
+ {
+ ///
+ /// Name of the cost metric
+ ///
+ public string Name { get; set; }
+ ///
+ /// The value for the cost metric
+ ///
+ public string Value { get; set; }
}
public class ExecutionPlanGraphPropertyBase
diff --git a/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/ExecutionPlanGraphUtils.cs b/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/ExecutionPlanGraphUtils.cs
index 905b4d48..0e7c8d4b 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/ExecutionPlanGraphUtils.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/ExecutionPlanGraphUtils.cs
@@ -33,8 +33,40 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan
}).ToList();
}
+ private static void ParseCostMetricProperty(List costMetrics, string name, PropertyValue? property)
+ {
+ if (property != null)
+ {
+ var costMetric = new CostMetric()
+ {
+ Name = name,
+ Value = ExecutionPlanGraphUtils.GetPropertyDisplayValue(property)
+ };
+
+ costMetrics.Add(costMetric);
+ }
+ }
+
public static ExecutionPlanNode ConvertShowPlanTreeToExecutionPlanTree(Node currentNode)
{
+ var costMetrics = new List();
+
+ var elapsedCpuTimeInMs = currentNode.ElapsedCpuTimeInMs;
+ if (elapsedCpuTimeInMs.HasValue)
+ {
+ var costMetric = new CostMetric()
+ {
+ Name = "ElapsedCpuTime",
+ Value = $"{elapsedCpuTimeInMs.Value}"
+ };
+ costMetrics.Add(costMetric);
+ }
+
+ ExecutionPlanGraphUtils.ParseCostMetricProperty(costMetrics, "EstimateRowsAllExecs", currentNode.Properties["EstimateRowsAllExecs"] as PropertyValue);
+ ExecutionPlanGraphUtils.ParseCostMetricProperty(costMetrics, "EstimatedRowsRead", currentNode.Properties["EstimatedRowsRead"] as PropertyValue);
+ ExecutionPlanGraphUtils.ParseCostMetricProperty(costMetrics, "ActualRows", currentNode.Properties["ActualRows"] as PropertyValue);
+ ExecutionPlanGraphUtils.ParseCostMetricProperty(costMetrics, "ActualRowsRead", currentNode.Properties["ActualRowsRead"] as PropertyValue);
+
return new ExecutionPlanNode
{
ID = currentNode.ID,
@@ -52,7 +84,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan
Badges = GenerateNodeOverlay(currentNode),
Name = currentNode.DisplayName,
ElapsedTimeInMs = currentNode.ElapsedTimeInMs,
- TopOperationsData = ParseTopOperationsData(currentNode)
+ TopOperationsData = ParseTopOperationsData(currentNode),
+ CostMetrics = costMetrics
};
}
@@ -134,6 +167,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan
propertyDataType = PropertyValueDataType.String;
break;
}
+
propsList.Add(new ExecutionPlanGraphProperty()
{
Name = prop.DisplayName,
@@ -412,8 +446,13 @@ GO
";
}
- private static string GetPropertyDisplayValue(PropertyValue property)
+ private static string GetPropertyDisplayValue(PropertyValue? property)
{
+ if (property == null)
+ {
+ return string.Empty;
+ }
+
try
{
// Get the property value.
@@ -421,7 +460,7 @@ GO
if (propertyValue == null)
{
- return String.Empty;
+ return string.Empty;
}
// Convert the property value to the text.
@@ -430,7 +469,7 @@ GO
catch (Exception e)
{
Logger.Write(TraceEventType.Error, e.ToString());
- return String.Empty;
+ return string.Empty;
}
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/ShowPlan/Node.cs b/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/ShowPlan/Node.cs
index 48a05dd6..4643d712 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/ShowPlan/Node.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/ExecutionPlan/ShowPlan/Node.cs
@@ -501,6 +501,26 @@ namespace Microsoft.SqlTools.ServiceLayer.ExecutionPlan.ShowPlan
}
}
+ public long? ElapsedCpuTimeInMs
+ {
+ get
+ {
+ long? time = null;
+ var actualStatsWrapper = this["ActualTimeStatistics"] as ExpandableObjectWrapper;
+ if (actualStatsWrapper != null)
+ {
+ var counters = actualStatsWrapper["ActualCPUms"] as RunTimeCounters;
+ if (counters != null)
+ {
+ var elapsedTime = counters.MaxCounter;
+ long ticks = (long)elapsedTime * TimeSpan.TicksPerMillisecond;
+ time = new DateTime(ticks).Millisecond;
+ }
+ }
+ return time;
+ }
+ }
+
///
/// ENU name for Logical Operator
///