Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #342

Merged
merged 44 commits into from
Sep 3, 2023
Merged

Fixes #342

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
0ab6401
Fix cross-threading error with message box prompts
MarkMpn Aug 9, 2023
c0020a2
Fix getting values from a TVF with alias
MarkMpn Aug 9, 2023
1ac4f46
Fixed JSON_VALUE getting a null literal
MarkMpn Aug 9, 2023
e8cf5b6
Copy required files for debug
MarkMpn Aug 9, 2023
7f179d6
Updated minimum XTB version
MarkMpn Aug 9, 2023
06df106
Merge branch 'retention' of https://github.com/MarkMpn/Sql4Cds into r…
MarkMpn Aug 9, 2023
9c2c9e3
Merge remote-tracking branch 'origin/master' into retention
MarkMpn Aug 9, 2023
e523e13
Cross apply progress
MarkMpn Aug 13, 2023
852f964
More CROSS APPLY tweaks
MarkMpn Aug 13, 2023
906d2f3
Do not attempt to convert ExecuteTransactionRequest to xxxMultiple re…
MarkMpn Aug 18, 2023
610d2cf
Do not use index spool for left side of nested loops, or where variab…
MarkMpn Aug 18, 2023
2b29bdc
Limit data retrieved for scalar subqueries
MarkMpn Aug 18, 2023
b4f0d9a
Handle nested IN & EXISTS subqueries
MarkMpn Aug 20, 2023
742f07f
Do not use merge join when data types do not have consistent sort orders
MarkMpn Aug 20, 2023
3b592ba
Reorder uncorrelated subqueries for more efficient filtering
MarkMpn Aug 21, 2023
d008580
Use original logical name casing for FetchXML filters and sorts
MarkMpn Aug 21, 2023
c1948fb
Autocomplete collation names
MarkMpn Aug 21, 2023
19312f5
Ensure subquery will only return 1 row before restructuring
MarkMpn Aug 22, 2023
8c5abc3
Support IS [NOT] DISTINCT FROM predicate
MarkMpn Aug 22, 2023
ff9e3df
IS DISTINCT FROM improvements for column comparisons
MarkMpn Aug 23, 2023
628defe
Expose @@VERSION and @@SERVERNAME variables
MarkMpn Aug 24, 2023
8533b9f
Added sql_variant support for SERVERPROPERTY function
MarkMpn Aug 25, 2023
67083ac
Improved autocomplete for variable names
MarkMpn Aug 25, 2023
166f51b
Copy required files on debug builds
MarkMpn Aug 25, 2023
c2881aa
Fixed error with rewriting nested loop joins if uncorrelated subquery…
MarkMpn Aug 28, 2023
fb00de5
Fixed returning schema for sql_variant values
MarkMpn Aug 28, 2023
43fee7e
Improved value returned for @@SERVERNAME and SERVERPROPERTY('serverna…
MarkMpn Aug 28, 2023
048a00b
Save dock layout
MarkMpn Aug 28, 2023
5b9be7c
Load XTB assembly directly
MarkMpn Aug 28, 2023
44594ea
Added metadata for new properties
MarkMpn Aug 28, 2023
90c4ced
Improved handling of floating windows
MarkMpn Aug 28, 2023
a494a04
Fixed uncorrelated TOP 1 scalar subquery
MarkMpn Aug 28, 2023
a314386
Fixed .NET Core build
MarkMpn Aug 28, 2023
b572fd1
Added option to use legacy SetState and Assign messages
MarkMpn Aug 28, 2023
64ff050
Allow executing messages with OptionSetValue parameters
MarkMpn Aug 28, 2023
946b2e4
Standardised copyright notices
MarkMpn Aug 30, 2023
d6701de
Keep @@VERSION more consistent with SQL Server
MarkMpn Aug 30, 2023
2c4e6b5
Do not allow TDS Endpoint for @@SERVERNAME
MarkMpn Aug 30, 2023
c43218f
Keep line breaks and tabs in copied text data but replace with spaces…
MarkMpn Aug 30, 2023
7feeca2
Improved error reporting on batch DML statements
MarkMpn Aug 30, 2023
eabb8ee
Ensure post-build events run only in debug builds
MarkMpn Aug 31, 2023
b3a3246
Can't use DISTINCT predicate or SQL_VARIANT_PROPERTY function in TDS …
MarkMpn Aug 31, 2023
67d2405
Avoid error when missing saved settings
MarkMpn Aug 31, 2023
7ebe428
Updated release notes
MarkMpn Aug 31, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions AzureDataStudioExtension/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# Change Log

## [v7.5.0](https://github.com/MarkMpn/Sql4Cds/releases/tag/v7.5.0) - 2023-09-03

Added `sql_variant` type support, including `SQL_VARIANT_PROPERTY` function
Added `IS [NOT] DISTINCT FROM` predicate support
Added `@@SERVERNAME` and `@@VERSION` global variables
Added `SERVERPROPERTY` function support
Added `USE_LEGACY_UPDATE_MESSAGES` query hint to use legacy update messages `Assign`, `SetState`, `SetParentBusinessUnit` and `SetBusinessEquipment`

Subquery fixes:
- Only include requested columns from `CROSS APPLY` and query-defined tables
- Performance improvements for uncorrelated scalar subqueries
- Only retrieve minimal rows for scalar subqueries
- Fixed use of nested `IN` and `EXISTS` subqueries

Fixed use of table-valued function with alias
Fixed `JSON_VALUE` function with embedded null literals
Fixed bulk DML operations that require non-standard requests
Do not use merge joins for data types with different sort ordering
Fixed filtering and sorting on non-lowercase attributes
Fixed executing messages with OptionSetValue parameters
Improved error reporting on batch DML statements

Added autocomplete for collation names and variable names

## [v7.4.0](https://github.com/MarkMpn/Sql4Cds/releases/tag/v7.4.0) - 2023-08-05

Added support for long-term retention data
Expand Down
3 changes: 3 additions & 0 deletions MarkMpn.Sql4Cds.Controls/MarkMpn.Sql4Cds.Controls.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,7 @@
<EmbeddedResource Include="Images\XmlWriterNode.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PostBuildEvent>copy $(TargetDir)MarkMpn.Sql4Cds.Controls.dll %25appdata%25\MscrmTools\XrmToolBox\Plugins\MarkMpn.Sql4Cds</PostBuildEvent>
</PropertyGroup>
</Project>
5 changes: 3 additions & 2 deletions MarkMpn.Sql4Cds.Controls/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
[assembly: AssemblyTitle("MarkMpn.Sql4Cds.Controls")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("Mark Carrington")]
[assembly: AssemblyProduct("MarkMpn.Sql4Cds.Controls")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyCopyright("Copyright © 2022 - 2023 Mark Carrington")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Expand All @@ -34,3 +34,4 @@
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>MarkMpn.Sql4Cds.Engine</AssemblyName>
<RootNamespace>MarkMpn.Sql4Cds.Engine</RootNamespace>
<Copyright>Copyright © 2020 - 2023 Mark Carrington</Copyright>
</PropertyGroup>

<Import Project="..\MarkMpn.Sql4Cds.Engine\MarkMpn.Sql4Cds.Engine.projitems" Label="Shared" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,12 @@
</ItemGroup>
<Import Project="..\MarkMpn.Sql4Cds.Engine\MarkMpn.Sql4Cds.Engine.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PostBuildEvent>copy $(TargetDir)MarkMpn.Sql4Cds.Engine.dll %25appdata%25\MscrmTools\XrmToolBox\Plugins\MarkMpn.Sql4Cds
copy $(TargetDir)Microsoft.ApplicationInsights.dll %25appdata%25\MscrmTools\XrmToolBox\Plugins\MarkMpn.Sql4Cds
copy $(TargetDir)Microsoft.SqlServer.TransactSql.ScriptDom.dll %25appdata%25\MscrmTools\XrmToolBox\Plugins\MarkMpn.Sql4Cds
copy $(TargetDir)XPath2.dll %25appdata%25\MscrmTools\XrmToolBox\Plugins\MarkMpn.Sql4Cds
copy $(TargetDir)XPath2.Extensions.dll %25appdata%25\MscrmTools\XrmToolBox\Plugins\MarkMpn.Sql4Cds
</PostBuildEvent>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion MarkMpn.Sql4Cds.Engine.NetFx/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Mark Carrington")]
[assembly: AssemblyProduct("MarkMpn.Sql4Cds.Engine")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyCopyright("Copyright © 2020 - 2023 Mark Carrington")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Expand Down
189 changes: 189 additions & 0 deletions MarkMpn.Sql4Cds.Engine.Tests/AdoProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,25 @@ public void StoredProcedureCommandType()
}
}

[TestMethod]
public void AliasedTVF()
{
using (var con = new Sql4CdsConnection(_localDataSource))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "SELECT msg.* FROM SampleMessage('1') AS msg";

using (var reader = cmd.ExecuteReader())
{
Assert.IsTrue(reader.Read());
Assert.AreEqual("1", reader.GetString(0));
Assert.AreEqual(1, reader.GetInt32(1));

Assert.IsFalse(reader.Read());
}
}
}

[TestMethod]
public void CorrelatedNotExistsTypeConversion()
{
Expand Down Expand Up @@ -1304,5 +1323,175 @@ public void StringAgg()
Assert.AreEqual("C, B, A", actual);
}
}

[TestMethod]
public void JsonValueNull()
{
using (var con = new Sql4CdsConnection(_localDataSource))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "SELECT JSON_VALUE('{ \"changedAttributes\": [ { \"logicalName\": \"column1\", \"oldValue\": null, \"newValue\": \"\" } ] }', '$.changedAttributes[0].oldValue')";
Assert.AreEqual(DBNull.Value, cmd.ExecuteScalar());
}
}

[TestMethod]
public void VariantType()
{
using (var con = new Sql4CdsConnection(_localDataSource))
using (var cmd = con.CreateCommand())
{
// Can select two variant values of different types in the same column
cmd.CommandText = "SELECT SERVERPROPERTY('edition') UNION ALL SELECT SERVERPROPERTY('editionid')";

using (var reader = cmd.ExecuteReader())
{
Assert.IsTrue(reader.Read());
Assert.AreEqual("Enterprise Edition", reader.GetString(0));
Assert.IsTrue(reader.Read());
Assert.AreEqual(1804890536, reader.GetInt64(0));
Assert.IsFalse(reader.Read());
}
}
}

[TestMethod]
public void VariantComparisons()
{
using (var con = new Sql4CdsConnection(_localDataSource))
using (var cmd = con.CreateCommand())
{
// Variant values are compared according to the type family hierarchy
// https://dba.stackexchange.com/questions/56722/why-does-implicit-conversion-from-sql-variant-basetype-decimal-not-work-well-w
cmd.CommandText = @"
declare
@v sql_variant = convert(decimal(28,8), 20.0);

select sql_variant_property(@v, 'BaseType') as BaseType, -- 'decimal',
iif(convert(int, 10.0) < @v, 1, 0) as ResultInt, -- 1
iif(convert(decimal, 10.0) < @v, 1, 0) as ResultDecimal, -- 1
iif(convert(float, 10.0) < @v, 1, 0) as ResultFloat, -- 0 !
iif(convert(float, 10.0) < convert(float, @v), 1, 0) as ResultFloatFloat, -- 1
iif(convert(float, 10.0) < convert(decimal(28,8), @v), 1, 0) as ResultFloatDecimal; -- 1";

using (var reader = cmd.ExecuteReader())
{
Assert.IsTrue(reader.Read());

var i = 0;
Assert.AreEqual("decimal", reader.GetString(i++));
Assert.AreEqual(1, reader.GetInt32(i++));
Assert.AreEqual(1, reader.GetInt32(i++));
Assert.AreEqual(0, reader.GetInt32(i++));
Assert.AreEqual(1, reader.GetInt32(i++));
Assert.AreEqual(1, reader.GetInt32(i++));

Assert.IsFalse(reader.Read());
}
}
}

[TestMethod]
public void SqlVariantProperty()
{
using (var con = new Sql4CdsConnection(_localDataSource))
using (var cmd = con.CreateCommand())
{
// Variant values are compared according to the type family hierarchy
// https://dba.stackexchange.com/questions/56722/why-does-implicit-conversion-from-sql-variant-basetype-decimal-not-work-well-w
cmd.CommandText = @"
declare
@v sql_variant = cast (46279.1 as decimal(8,2));

SELECT SQL_VARIANT_PROPERTY(@v,'BaseType') AS 'Base Type',
SQL_VARIANT_PROPERTY(@v,'Precision') AS 'Precision',
SQL_VARIANT_PROPERTY(@v,'Scale') AS 'Scale' ";

using (var reader = cmd.ExecuteReader())
{
Assert.IsTrue(reader.Read());

var i = 0;
Assert.AreEqual("decimal", reader.GetString(i++));
Assert.AreEqual(8, reader.GetInt32(i++));
Assert.AreEqual(2, reader.GetInt32(i++));

Assert.IsFalse(reader.Read());
}
}
}

[TestMethod]
public void VariantTypes()
{
using (var con = new Sql4CdsConnection(_localDataSource))
using (var cmd = con.CreateCommand())
{
// Variant values are compared according to the type family hierarchy
// https://dba.stackexchange.com/questions/56722/why-does-implicit-conversion-from-sql-variant-basetype-decimal-not-work-well-w
cmd.CommandText = @"
declare
@v sql_variant = 1;
declare
@n sql_variant;

SELECT @v
UNION ALL
SELECT @n";

using (var reader = (Sql4CdsDataReader) cmd.ExecuteReader())
{
Assert.AreEqual(typeof(object), reader.GetProviderSpecificFieldType(0));
Assert.AreEqual(typeof(object), reader.GetFieldType(0));
Assert.AreEqual("sql_variant", reader.GetDataTypeName(0));

var schema = reader.GetSchemaTable();
Assert.AreEqual(typeof(object), schema.Rows[0]["DataType"]);
Assert.AreEqual(typeof(object), schema.Rows[0]["ProviderSpecificDataType"]);

Assert.IsTrue(reader.Read());

Assert.AreEqual(1, reader.GetInt32(0));
Assert.AreEqual(1, reader.GetValue(0));
Assert.AreEqual(new SqlInt32(1), reader.GetProviderSpecificValue(0));

Assert.IsTrue(reader.Read());

Assert.AreEqual(DBNull.Value, reader.GetValue(0));
Assert.AreEqual(DBNull.Value, reader.GetProviderSpecificValue(0));

Assert.IsFalse(reader.Read());
}
}
}

[TestMethod]
public void ExecSetState()
{
using (var con = new Sql4CdsConnection(_localDataSource))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "INSERT INTO contact (firstname, lastname) VALUES ('Test', 'User'); SELECT @@IDENTITY";
var id = cmd.ExecuteScalar();

cmd.CommandText = @"
DECLARE @id EntityReference
SELECT TOP 1 @id = contactid FROM contact
EXEC SetState @id, 1, 2";

cmd.ExecuteNonQuery();

cmd.CommandText = "SELECT statecode, statuscode FROM contact WHERE contactid = @id";
cmd.Parameters.Add(new Sql4CdsParameter("@id", id));

using (var reader = cmd.ExecuteReader())
{
Assert.IsTrue(reader.Read());
Assert.AreEqual(1, reader.GetInt32(0));
Assert.AreEqual(2, reader.GetInt32(1));
Assert.IsFalse(reader.Read());
}
}
}
}
}
Loading