mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
* Porting showplan code from ssms * Moving showplans bits to a subfolder * code cleanup * Remvoing unnecssary conditional visibility
145 lines
5.3 KiB
C#
145 lines
5.3 KiB
C#
//
|
|
// Copyright (c) Microsoft. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
//
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.ShowPlan.ShowPlanGraph
|
|
{
|
|
/// <summary>
|
|
/// Parses stytement type ShowPlan XML nodes
|
|
/// </summary>
|
|
internal class StatementParser : XmlPlanParser
|
|
{
|
|
/// <summary>
|
|
/// Creates new node and adds it to the graph.
|
|
/// </summary>
|
|
/// <param name="item">Item being parsed.</param>
|
|
/// <param name="parentItem">Parent item.</param>
|
|
/// <param name="parentNode">Parent node.</param>
|
|
/// <param name="context">Node builder context.</param>
|
|
/// <returns>The node that corresponds to the item being parsed.</returns>
|
|
public override Node GetCurrentNode(object item, object parentItem, Node parentNode, NodeBuilderContext context)
|
|
{
|
|
return NewNode(context);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines Operation that corresponds to the object being parsed.
|
|
/// </summary>
|
|
/// <param name="node">Node being parsed.</param>
|
|
/// <returns>Operation that corresponds to the node.</returns>
|
|
protected override Operation GetNodeOperation(Node node)
|
|
{
|
|
object statementType = node["StatementType"];
|
|
Operation statement = statementType != null
|
|
? OperationTable.GetStatement(statementType.ToString())
|
|
: Operation.Unknown;
|
|
|
|
|
|
return statement;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines node subtree cost from existing node properties.
|
|
/// </summary>
|
|
/// <param name="node">Node being parsed.</param>
|
|
/// <returns>Node subtree cost.</returns>
|
|
protected override double GetNodeSubtreeCost(Node node)
|
|
{
|
|
object value = node["StatementSubTreeCost"];
|
|
return value != null ? Convert.ToDouble(value, CultureInfo.CurrentCulture) : 0;
|
|
}
|
|
|
|
protected override bool ShouldParseItem(object parsedItem)
|
|
{
|
|
// Special case. An empty statement without QueryPlan but with
|
|
// a UDF or StoreProc should be skipped
|
|
StmtSimpleType statement = parsedItem as StmtSimpleType;
|
|
if (statement != null)
|
|
{
|
|
// We use hidden wrapper statements for UDFs and StoredProcs
|
|
// Hidden statements don't have any of their properties defined
|
|
// We can use one of properties which is always set by server
|
|
// such as StatementIdSpecified to distinguish between a real
|
|
// statement and a hidden wrapper statement
|
|
if (!statement.StatementIdSpecified)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// By default, the statement is parsed
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enumerates FunctionType blocks and removes all items from UDF and StoredProc properties.
|
|
/// </summary>
|
|
/// <param name="parsedItem">The item being parsed.</param>
|
|
/// <returns>Enumeration.</returns>
|
|
public override IEnumerable<FunctionTypeItem> ExtractFunctions(object parsedItem)
|
|
{
|
|
StmtSimpleType statement = parsedItem as StmtSimpleType;
|
|
if (statement != null)
|
|
{
|
|
// If this is a simple statement it may have UDF and StoredProc fields
|
|
if (statement.UDF != null)
|
|
{
|
|
foreach (FunctionType function in statement.UDF)
|
|
{
|
|
yield return new FunctionTypeItem(function, FunctionTypeItem.ItemType.Udf);
|
|
}
|
|
statement.UDF = null;
|
|
}
|
|
|
|
if (statement.StoredProc != null)
|
|
{
|
|
yield return new FunctionTypeItem(statement.StoredProc, FunctionTypeItem.ItemType.StoredProcedure);
|
|
statement.StoredProc = null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// This is some other type of Statement. Call ExtractFunctions for all its children
|
|
foreach (object item in GetChildren(parsedItem))
|
|
{
|
|
XmlPlanParser parser = XmlPlanParserFactory.GetParser(item.GetType());
|
|
foreach (FunctionTypeItem functionItem in parser.ExtractFunctions(item))
|
|
{
|
|
yield return functionItem;
|
|
}
|
|
}
|
|
}
|
|
|
|
yield break;
|
|
}
|
|
|
|
/// <summary>
|
|
/// protected constructor prevents this object from being externally instantiated
|
|
/// </summary>
|
|
protected StatementParser()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Singelton instance
|
|
/// </summary>
|
|
private static StatementParser statementParser = null;
|
|
public static StatementParser Instance
|
|
{
|
|
get
|
|
{
|
|
if (statementParser == null)
|
|
{
|
|
statementParser = new StatementParser();
|
|
}
|
|
return statementParser;
|
|
}
|
|
}
|
|
}
|
|
}
|