Skip to content

Commit

Permalink
Merge pull request #483 from MarkMpn/v9-fixes
Browse files Browse the repository at this point in the history
V9 fixes
+semver:minor
  • Loading branch information
MarkMpn authored Jun 9, 2024
2 parents d2b3862 + 84a4bb1 commit d4f1403
Show file tree
Hide file tree
Showing 76 changed files with 3,035 additions and 607 deletions.
18 changes: 18 additions & 0 deletions AzureDataStudioExtension/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Change Log

## [v9.1.0](https://github.com/MarkMpn/Sql4Cds/releases/tag/v9.1.0) - 2024-06-10

Enabled access to recycle bin records via the `bin` schema
Enabled `INSERT`, `UPDATE` and `DELETE` statements on `principalobjectaccess` table
Enabled use of subqueries within `ON` clause of `JOIN` statements
Added support for `___pid` virtual column for lookups to elastic tables
Improved folding of queries using index spools
Improved primary key calculation when using joins on non-key columns
Apply column order setting to parameters for stored procedures and table-valued functions
Fixed error with DeleteMultiple requests
Fixed paging error with `DISTINCT` queries causing results to be limited to 50,000 records
Fixed paging errors when sorting by optionset values causing some results to be skipped
Fixed errors when using joins inside `[NOT] EXISTS` subqueries
Fixed incorrect results when applying aliases to `___name` and `___type` virtual columns
Fixed max length calculation for string columns
Fixed display of error messages
Fixed "invalid program" errors when combining type conversions with `AND` or `OR`

## [v9.0.1](https://github.com/MarkMpn/Sql4Cds/releases/tag/v9.0.1) - 2024-05-08

Fixed `NullReferenceException` errors when:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Text;
using MarkMpn.Sql4Cds.Engine;
using MarkMpn.Sql4Cds.Engine.ExecutionPlan;
using Microsoft.VisualStudio.DebuggerVisualizers;

namespace MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide
{
public class ExecutionPlanObjectSource : VisualizerObjectSource
{
public override void GetData(object target, Stream outgoingData)
{
if (target is IRootExecutionPlanNode root)
{
WritePlan(outgoingData, root);
}
else if (target is IExecutionPlanNode node)
{
WritePlan(outgoingData, new UnknownRootNode { Source = node });
}
else if (target is Sql4CdsCommand cmd)
{
if (cmd.Plan != null)
WritePlan(outgoingData, cmd.Plan.First());
else
WritePlan(outgoingData, cmd.GeneratePlan(false).First());
}
}

private void WritePlan(Stream outgoingData, IRootExecutionPlanNode source)
{
var json = ExecutionPlanSerializer.Serialize(source);
SerializeAsJson(outgoingData, new SerializedPlan { Plan = json });
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net462</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.DebuggerVisualizers" Version="17.6.1032901" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MarkMpn.Sql4Cds.Engine.NetCore\MarkMpn.Sql4Cds.Engine.NetCore.csproj" Condition="'$(TargetFramework)' == 'net6.0'" />
<ProjectReference Include="..\MarkMpn.Sql4Cds.Engine.NetFx\MarkMpn.Sql4Cds.Engine.NetFx.csproj" Condition="'$(TargetFramework)' == 'net462'" />
</ItemGroup>

</Project>
13 changes: 13 additions & 0 deletions MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide/SerializedPlan.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide
{
public class SerializedPlan
{
public string Plan { get; set; }
}
}
35 changes: 35 additions & 0 deletions MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide/UnknownRootNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MarkMpn.Sql4Cds.Engine.ExecutionPlan;

namespace MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide
{
internal class UnknownRootNode : IRootExecutionPlanNode
{
public string Sql { get; set; }
public int Index { get; set; }
public int Length { get; set; }
public int LineNumber { get; set; }

public IExecutionPlanNode Parent => null;

public int ExecutionCount => 0;

public TimeSpan Duration => TimeSpan.Zero;

public IExecutionPlanNode Source { get; set; }

public IEnumerable<IExecutionPlanNode> GetSources()
{
yield return Source;
}

public override string ToString()
{
return "< Unknown Root >";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"MarkMpn.Sql4Cds.DebugVisualizer.DisplayName": "SQL 4 CDS Visualizer"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System.Diagnostics;
using MarkMpn.Sql4Cds.Engine;
using Microsoft;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Commands;
using Microsoft.VisualStudio.Extensibility.DebuggerVisualizers;
using Microsoft.VisualStudio.Extensibility.Shell;
using Microsoft.VisualStudio.Extensibility.VSSdkCompatibility;
using Microsoft.VisualStudio.RpcContracts.RemoteUI;
using Microsoft.VisualStudio.Shell;

namespace MarkMpn.Sql4Cds.DebugVisualizer.DebuggerSide
{
/// <summary>
/// Debugger visualizer provider for <see cref="IRootExecutionPlanNode"/>.
/// </summary>
[VisualStudioContribution]
internal class ExecutionPlanDebuggerVisualizerProvider : DebuggerVisualizerProvider
{
private const string DisplayName = "MarkMpn.Sql4Cds.DebugVisualizer.DisplayName";

public override DebuggerVisualizerProviderConfiguration DebuggerVisualizerProviderConfiguration => new(
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.AdaptiveIndexSpoolNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.AliasNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.AssertNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.AssignVariablesNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.BulkDeleteJobNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.ComputeScalarNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.ConcatenateNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.ConditionalNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.ConstantScanNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.ContinueBreakNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.DeclareVariablesNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.DeleteNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.DistinctNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.ExecuteAsNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.ExecuteMesageNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.FetchXmlScan, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.FilterNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.GlobalOptionSetQueryNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.GotoLabelNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.GoToNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.HashJoinNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.HashMatchAggregateNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.IndexSpoolNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.InsertNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.MergeJoinNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.MetadataQueryNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.NestedLoopNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.OffsetFetchNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.OpenJsonNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.PartitionedAggregateNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.PrintNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.RaiseErrorNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.RetrieveTotalRecordCountNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.RevertNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.SelectNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.SortNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.SqlNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.StreamAggregateNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.SystemFunctionNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.TableSpoolNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.ThrowNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.TopNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.BeginTryNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.EndTryNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.BeginCatchNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.EndCatchNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.UpdateNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.WaitForNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.ExecutionPlan.XmlWriterNode, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"),
new VisualizerTargetType($"%{DisplayName}%", "MarkMpn.Sql4Cds.Engine.Sql4CdsCommand, MarkMpn.Sql4Cds.Engine, Version=0.0.0.0, Culture=neutral"))
{
VisualizerObjectSourceType = new("MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide.ExecutionPlanObjectSource, MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide")
};

public override async Task<IRemoteUserControl> CreateVisualizerAsync(VisualizerTarget visualizerTarget, CancellationToken cancellationToken)
{
var serializedPlan = await visualizerTarget.ObjectSource.RequestDataAsync<SerializedPlan>(null, cancellationToken);
var plan = ExecutionPlanSerializer.Deserialize(serializedPlan.Plan);

await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var wrapper = new WpfControlWrapper(new QueryPlanUserControl(plan));
return wrapper;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.Extensibility;

namespace MarkMpn.Sql4Cds.DebugVisualizer.DebuggerSide
{
/// <summary>
/// Extension entrypoint for the VisualStudio.Extensibility extension.
/// </summary>
[VisualStudioContribution]
internal class ExtensionEntrypoint : Extension
{
/// <inheritdoc/>
public override ExtensionConfiguration ExtensionConfiguration => new()
{
RequiresInProcessHosting = true
};

/// <inheritdoc />
protected override void InitializeServices(IServiceCollection serviceCollection)
{
base.InitializeServices(serviceCollection);

// You can configure dependency injection here by adding services to the serviceCollection.
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<VssdkCompatibleExtension>true</VssdkCompatibleExtension>
</PropertyGroup>
<ItemGroup>
<None Remove="QueryPlanUserControl.xaml" />
</ItemGroup>

<ItemGroup>
<Content Include="..\MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide\bin\$(Configuration)\net6.0\MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide.dll" Link="netcoreapp\MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide.dll" />
<Content Include="..\MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide\bin\$(Configuration)\net462\MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide.dll" Link="net2.0\MarkMpn.Sql4Cds.DebugVisualizer.DebugeeSide.dll" />
</ItemGroup>

<ItemGroup>
<Page Include="QueryPlanUserControl.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.DebuggerVisualizers" Version="17.6.1032901" />
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Sdk" Version="17.9.2092" />
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Build" Version="17.9.2092" />
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.10.40171">
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System.Xaml" />
<Reference Include="WindowsFormsIntegration" />
</ItemGroup>

<ItemGroup>
<Folder Include="Images\" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MarkMpn.Sql4Cds.Controls\MarkMpn.Sql4Cds.Controls.csproj" />
<ProjectReference Include="..\MarkMpn.Sql4Cds.Engine.NetFx\MarkMpn.Sql4Cds.Engine.NetFx.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<UserControl x:Class="MarkMpn.Sql4Cds.DebugVisualizer.DebuggerSide.QueryPlanUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Grid x:Name="grid"/>
</UserControl>
Loading

0 comments on commit d4f1403

Please sign in to comment.