Skip to content

Commit

Permalink
Merge branch 'master' into nested-loop-join-error
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn authored Nov 16, 2024
2 parents 752db8e + 15d7236 commit bee1ac7
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 50 deletions.
6 changes: 6 additions & 0 deletions AzureDataStudioExtension/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

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

Fixed Intellisense with trailing comments
Improved SQL to Fetch XML conversion of datetime filters
Fixed use of case-insensitive table names in INSERT statements

## [v9.4.0](https://github.com/MarkMpn/Sql4Cds/releases/tag/v9.4.0) - 2024-11-06
New SQL support
* `NEWID` function
Expand Down
78 changes: 78 additions & 0 deletions MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2976,6 +2976,36 @@ public void SimpleUpdate()
</fetch>");
}

[TestMethod]
public void CaseInsensitiveUpdate()
{
var planBuilder = new ExecutionPlanBuilder(new SessionContext(_localDataSources, this), this);

var query = "UPDATE Account SET Name = 'foo' WHERE name = 'bar'";

var plans = planBuilder.Build(query, null, out _);

Assert.AreEqual(1, plans.Length);

var update = AssertNode<UpdateNode>(plans[0]);
Assert.AreEqual("account", update.LogicalName);
Assert.AreEqual("Account.accountid", update.PrimaryIdAccessors.Single().SourceAttributes.Single());
Assert.AreEqual("Expr1", update.NewValueAccessors.Single(a => a.TargetAttribute == "name").SourceAttributes.Single());
var computeScalar = AssertNode<ComputeScalarNode>(update.Source);
Assert.AreEqual("'foo'", computeScalar.Columns["Expr1"].ToSql());
var fetch = AssertNode<FetchXmlScan>(computeScalar.Source);
Assert.AreEqual("Account", fetch.Alias);
AssertFetchXml(fetch, @"
<fetch>
<entity name='account'>
<attribute name='accountid' />
<filter>
<condition attribute='name' operator='eq' value='bar' />
</filter>
</entity>
</fetch>");
}

[TestMethod]
public void UpdateFromJoin()
{
Expand Down Expand Up @@ -3387,6 +3417,34 @@ public void SimpleDelete()
</fetch>");
}

[TestMethod]
public void CaseInsensitiveDelete()
{
var planBuilder = new ExecutionPlanBuilder(new SessionContext(_localDataSources, this), this);

var query = "DELETE FROM Account WHERE name = 'bar'";

var plans = planBuilder.Build(query, null, out _);

Assert.AreEqual(1, plans.Length);

var delete = AssertNode<DeleteNode>(plans[0]);
Assert.AreEqual("account", delete.LogicalName);
Assert.AreEqual("accountid", delete.PrimaryIdAccessors.Single().TargetAttribute);
Assert.AreEqual("Account.accountid", delete.PrimaryIdAccessors.Single().SourceAttributes.Single());
var fetch = AssertNode<FetchXmlScan>(delete.Source);
Assert.AreEqual("Account", fetch.Alias);
AssertFetchXml(fetch, @"
<fetch>
<entity name='account'>
<attribute name='accountid' />
<filter>
<condition attribute='name' operator='eq' value='bar' />
</filter>
</entity>
</fetch>");
}

[TestMethod]
public void SimpleInsertSelect()
{
Expand Down Expand Up @@ -3414,6 +3472,26 @@ public void SimpleInsertSelect()
</fetch>");
}

[TestMethod]
public void CaseInsensitiveInsert()
{
var planBuilder = new ExecutionPlanBuilder(new SessionContext(_localDataSources, this), this);

var query = "INSERT INTO Account (Name) VALUES ('Data8')";

var plans = planBuilder.Build(query, null, out _);

Assert.AreEqual(1, plans.Length);

var insert = AssertNode<InsertNode>(plans[0]);
Assert.AreEqual("account", insert.LogicalName);
Assert.AreEqual("name", insert.Accessors.Single().TargetAttribute);
Assert.AreEqual("Expr2", insert.Accessors.Single().SourceAttributes.Single());
var constantScan = AssertNode<ConstantScanNode>(insert.Source);
Assert.AreEqual("Expr2", constantScan.Schema.Single().Key);
Assert.AreEqual(1, constantScan.Values.Count);
}

[TestMethod]
public void SelectDuplicateColumnNames()
{
Expand Down
2 changes: 1 addition & 1 deletion MarkMpn.Sql4Cds.Engine/ExecutionPlanBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1416,7 +1416,7 @@ private InsertNode ConvertInsertSpecification(NamedTableReference target, IList<
var node = new InsertNode
{
DataSource = dataSource.Name,
LogicalName = logicalName,
LogicalName = metadata.LogicalName,
Source = reader.Source,
Accessors = reader.ValidateInsertColumnMapping(targetColumns, sourceColumns)
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<iconUrl>http://markcarrington.dev/sql4cds-icon/</iconUrl>
<description>Converts FetchXML to SQL queries. This is a minimal source-only package, you can also use the MarkMpn.Sql4Cds.Engine package that includes this conversion as well as SQL to FetchXML conversion.</description>
<summary>Minimal source-only package to convert FetchXML to SQL</summary>
<releaseNotes>Fixed use of alias in filters</releaseNotes>
<releaseNotes>Include join alias in output column aliases when converting from Fetch XML to SQL</releaseNotes>
<copyright>Copyright © 2020 Mark Carrington</copyright>
<language>en-GB</language>
<tags>FetchXML SQL CDS</tags>
Expand Down
27 changes: 3 additions & 24 deletions MarkMpn.Sql4Cds.Engine/MarkMpn.Sql4Cds.Engine.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,9 @@
<iconUrl>https://markcarrington.dev/sql4cds-icon/</iconUrl>
<description>Convert SQL queries to FetchXml and execute them against Dataverse / D365</description>
<summary>Convert SQL queries to FetchXml and execute them against Dataverse / D365</summary>
<releaseNotes>New SQL support
* `NEWID` function
* `DATETRUNC` function

SQL Server compatibility improvements
* Improved data type conversions for better SQL Server compatibility
* Reworked `DATEPART` / `DATEADD` / `DATEDIFF` functions for improved SQL Server compatibility

DML operation optimizations
* Update/delete records without reading them first if possible - disable if necessary with `NO_DIRECT_DML` query hint
* Implemented minimal updates via new `MINIMAL_UPDATES` query hint
* Refactored type conversion logic for consistency across insert/update/delete operations

Other improvements
* Extended support for executing messages with more parameter types
* TDS Endpoint compatibility improvements

Bug fixes
* Fixed filtering on `metadata.alternate_key.entitykeyindexstatus`
* Show confirmation message before executing bulk delete job
* Fixed use of `INSERT` and `UPDATE` with virtual tables
* Fixed use of `FULL OUTER JOIN` with Fetch XML
* Fixed filtering of `OUTER JOIN` / `OUTER APPLY` results when using nested loops
* Fixed use of alias in filters when converting from Fetch XML to SQL
<releaseNotes>Include join alias in output column aliases when converting from Fetch XML to SQL
Improved SQL to Fetch XML conversion of datetime filters
Fixed use of case-insensitive table names in INSERT statements
</releaseNotes>
<copyright>Copyright © 2020 Mark Carrington</copyright>
<language>en-GB</language>
Expand Down
28 changes: 4 additions & 24 deletions MarkMpn.Sql4Cds/MarkMpn.SQL4CDS.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,10 @@ plugins or integrations by writing familiar SQL and converting it.
Queries can also run using the preview TDS Endpoint. A wide range of SQL functionality is also built
in to allow running queries that aren't directly supported by either FetchXML or the TDS Endpoint.</description>
<summary>Convert SQL queries to FetchXML and execute them against Dataverse / D365</summary>
<releaseNotes>New SQL support
* `NEWID` function
* `DATETRUNC` function

SQL Server compatibility improvements
* Improved data type conversions for better SQL Server compatibility
* Reworked `DATEPART` / `DATEADD` / `DATEDIFF` functions for improved SQL Server compatibility

DML operation optimizations
* Update/delete records without reading them first if possible - disable if necessary with `NO_DIRECT_DML` query hint
* Implemented minimal updates via new `MINIMAL_UPDATES` query hint
* Refactored type conversion logic for consistency across insert/update/delete operations

Other improvements
* Extended support for executing messages with more parameter types
* TDS Endpoint compatibility improvements

Bug fixes
* Fixed filtering on `metadata.alternate_key.entitykeyindexstatus`
* Show confirmation message before executing bulk delete job
* Fixed use of `INSERT` and `UPDATE` with virtual tables
* Fixed use of `FULL OUTER JOIN` with Fetch XML
* Fixed filtering of `OUTER JOIN` / `OUTER APPLY` results when using nested loops
* Fixed use of alias in filters when converting from Fetch XML to SQL
<releaseNotes>Fixed Intellisense with trailing comments
Include join alias in output column aliases when converting from Fetch XML to SQL
Improved SQL to Fetch XML conversion of datetime filters
Fixed use of case-insensitive table names in INSERT statements
</releaseNotes>
<copyright>Copyright © 2019 Mark Carrington</copyright>
<language>en-GB</language>
Expand Down

0 comments on commit bee1ac7

Please sign in to comment.