Skip to content

Commit

Permalink
Moving IQueryExecutionOptions to internal progress
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed Feb 21, 2022
1 parent 7e78cc6 commit c23fd39
Show file tree
Hide file tree
Showing 34 changed files with 120 additions and 145 deletions.
86 changes: 14 additions & 72 deletions MarkMpn.Sql4Cds.Engine.Tests/AdoProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,66 +23,8 @@
namespace MarkMpn.Sql4Cds.Engine.Tests
{
[TestClass]
public class AdoProviderTests : FakeXrmEasyTestsBase, IQueryExecutionOptions
public class AdoProviderTests : FakeXrmEasyTestsBase
{
CancellationToken IQueryExecutionOptions.CancellationToken => CancellationToken.None;

bool IQueryExecutionOptions.BlockUpdateWithoutWhere => false;

bool IQueryExecutionOptions.BlockDeleteWithoutWhere => false;

bool IQueryExecutionOptions.UseBulkDelete => false;

int IQueryExecutionOptions.BatchSize => 1;

bool IQueryExecutionOptions.UseTDSEndpoint => false;

bool IQueryExecutionOptions.UseRetrieveTotalRecordCount => true;

int IQueryExecutionOptions.MaxDegreeOfParallelism => 10;

bool IQueryExecutionOptions.ColumnComparisonAvailable => true;

bool IQueryExecutionOptions.UseLocalTimeZone => false;

List<JoinOperator> IQueryExecutionOptions.JoinOperatorsAvailable => new List<JoinOperator> { JoinOperator.Inner, JoinOperator.LeftOuter };

bool IQueryExecutionOptions.BypassCustomPlugins => false;

void IQueryExecutionOptions.RetrievingNextPage()
{
}

void IQueryExecutionOptions.Progress(double? progress, string message)
{
}

bool IQueryExecutionOptions.ContinueRetrieve(int count)
{
return true;
}

bool IQueryExecutionOptions.ConfirmInsert(int count, EntityMetadata meta)
{
return true;
}

bool IQueryExecutionOptions.ConfirmUpdate(int count, EntityMetadata meta)
{
return true;
}

bool IQueryExecutionOptions.ConfirmDelete(int count, EntityMetadata meta)
{
return true;
}

string IQueryExecutionOptions.PrimaryDataSource => "uat";

Guid IQueryExecutionOptions.UserId => Guid.NewGuid();

bool IQueryExecutionOptions.QuotedIdentifiers => true;

[TestMethod]
public void SelectArithmetic()
{
Expand All @@ -99,7 +41,7 @@ public void SelectArithmetic()
}
};

using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = query;
Expand All @@ -120,7 +62,7 @@ public void SelectArithmetic()
[TestMethod]
public void SelectParameters()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "SELECT @param1, @param2";
Expand All @@ -141,7 +83,7 @@ public void SelectParameters()
[TestMethod]
public void InsertRecordsAffected()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "INSERT INTO account (name) VALUES (@name)";
Expand All @@ -157,7 +99,7 @@ public void InsertRecordsAffected()
[TestMethod]
public void InsertRecordsAffectedMultipleCommands()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "INSERT INTO account (name) VALUES (@name); INSERT INTO account (name) VALUES (@name)";
Expand All @@ -173,7 +115,7 @@ public void InsertRecordsAffectedMultipleCommands()
[TestMethod]
public void CombinedInsertSelect()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "INSERT INTO account (name) VALUES (@name); SELECT accountid FROM account WHERE name = @name";
Expand All @@ -195,7 +137,7 @@ public void CombinedInsertSelect()
[TestMethod]
public void MultipleResultSets()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "INSERT INTO account (name) VALUES (@name); SELECT accountid FROM account WHERE name = @name; SELECT name FROM account";
Expand Down Expand Up @@ -225,7 +167,7 @@ public void MultipleResultSets()
[TestMethod]
public void GetLastInsertId()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "INSERT INTO account (name) VALUES (@name); SELECT @@IDENTITY";
Expand All @@ -242,7 +184,7 @@ public void GetLastInsertId()
[TestMethod]
public void RowCount()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "INSERT INTO account (name) VALUES ('1'), ('2'), ('3'); SELECT @@ROWCOUNT; SELECT @@ROWCOUNT";
Expand All @@ -265,7 +207,7 @@ public void RowCount()
[TestMethod]
public void LoadToDataTable()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "SELECT 1, 'hello world'";
Expand All @@ -286,7 +228,7 @@ public void LoadToDataTable()
[TestMethod]
public void ControlOfFlow()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = @"
Expand Down Expand Up @@ -329,7 +271,7 @@ SELECT @param1
[TestMethod]
public void Print()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "PRINT @param1";
Expand All @@ -347,7 +289,7 @@ public void Print()
[TestMethod]
public void GoTo()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = @"
Expand Down Expand Up @@ -392,7 +334,7 @@ goto label2
[TestMethod]
public void ContinueBreak()
{
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList(), this))
using (var con = new Sql4CdsConnection(_localDataSource.Values.ToList()))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = @"
Expand Down
6 changes: 3 additions & 3 deletions MarkMpn.Sql4Cds.Engine.Tests/ExecutionPlanTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3680,7 +3680,7 @@ public void TableVariableNotSupported()
public void IfStatement()
{
var metadata = new AttributeMetadataCache(_service);
var planBuilder = new ExecutionPlanBuilder(metadata, new StubTableSizeCache(), this) { CompileConditions = false };
var planBuilder = new ExecutionPlanBuilder(metadata, new StubTableSizeCache(), this) { EstimatedPlanOnly = false };

var query = @"
IF @param1 = 1
Expand Down Expand Up @@ -3715,7 +3715,7 @@ INSERT INTO account (name) VALUES ('one')
public void WhileStatement()
{
var metadata = new AttributeMetadataCache(_service);
var planBuilder = new ExecutionPlanBuilder(metadata, new StubTableSizeCache(), this) { CompileConditions = false };
var planBuilder = new ExecutionPlanBuilder(metadata, new StubTableSizeCache(), this) { EstimatedPlanOnly = false };

var query = @"
WHILE @param1 < 10
Expand Down Expand Up @@ -3745,7 +3745,7 @@ INSERT INTO account (name) VALUES (@param1)
public void IfNotExists()
{
var metadata = new AttributeMetadataCache(_service);
var planBuilder = new ExecutionPlanBuilder(metadata, new StubTableSizeCache(), this) { CompileConditions = false };
var planBuilder = new ExecutionPlanBuilder(metadata, new StubTableSizeCache(), this) { EstimatedPlanOnly = false };

var query = @"
IF NOT EXISTS(SELECT * FROM account WHERE name = @param1)
Expand Down
2 changes: 2 additions & 0 deletions MarkMpn.Sql4Cds.Engine.Tests/FakeXrmEasyTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ public FakeXrmEasyTestsBase()
{
_context = new XrmFakedContext();
_context.InitializeMetadata(Assembly.GetExecutingAssembly());
_context.CallerId = new EntityReference("systemuser", Guid.NewGuid());

_service = _context.GetOrganizationService();
_dataSource = new DataSource { Name = "uat", Connection = _service, Metadata = new AttributeMetadataCache(_service), TableSizeCache = new StubTableSizeCache() };

_context2 = new XrmFakedContext();
_context2.InitializeMetadata(Assembly.GetExecutingAssembly());
_context2.CallerId = _context.CallerId;

_service2 = _context2.GetOrganizationService();
_dataSource2 = new DataSource { Name = "prod", Connection = _service2, Metadata = new AttributeMetadataCache(_service2), TableSizeCache = new StubTableSizeCache() };
Expand Down
2 changes: 1 addition & 1 deletion MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public override void Prepare()
/// <returns>The root nodes of the plan</returns>
public IRootExecutionPlanNode[] GeneratePlan(bool compileForExecution)
{
_planBuilder.CompileConditions = compileForExecution;
_planBuilder.EstimatedPlanOnly = compileForExecution;
var plan = _planBuilder.Build(CommandText, ((Sql4CdsParameterCollection)Parameters).GetParameterTypes(), out _useTDSEndpointDirectly);

if (compileForExecution)
Expand Down
14 changes: 2 additions & 12 deletions MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,15 @@ public Sql4CdsConnection(IOrganizationService svc) : this(BuildDataSources(svc))
/// Creates a new <see cref="Sql4CdsConnection"/> using the specified list of data sources
/// </summary>
/// <param name="dataSources">The list of data sources to use</param>
public Sql4CdsConnection(IReadOnlyList<DataSource> dataSources) : this(dataSources, null)
{
}

/// <summary>
/// Creates a new <see cref="Sql4CdsConnection"/> using the specified list of data sources
/// </summary>
/// <param name="dataSources">The list of data sources to use</param>
/// <param name="options">The options to control how queries will be executed</param>
public Sql4CdsConnection(IReadOnlyList<DataSource> dataSources, IQueryExecutionOptions options)
public Sql4CdsConnection(IReadOnlyList<DataSource> dataSources)
{
if (dataSources == null)
throw new ArgumentNullException(nameof(dataSources));

if (dataSources.Count == 0)
throw new ArgumentOutOfRangeException("At least one data source must be supplied");

if (options == null)
options = new DefaultQueryExecutionOptions(dataSources[0], CancellationToken.None);
var options = new DefaultQueryExecutionOptions(dataSources[0], CancellationToken.None);

_dataSources = dataSources.ToDictionary(ds => ds.Name, StringComparer.OrdinalIgnoreCase);
_options = new ChangeDatabaseOptionsWrapper(options);
Expand Down
6 changes: 3 additions & 3 deletions MarkMpn.Sql4Cds.Engine/Ado/Sql4CdsDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,9 @@ public override DataTable GetSchemaTable()
DBNull.Value, // BaseColumnName
DBNull.Value, // BaseSchemaName
DBNull.Value, // BaseTableName
column.DataType, // DataType
ToClrType(column.DataType), // DataType
false, // AllowDBNull
column.DataType, // ProviderType
ToClrType(column.DataType), // ProviderType
false, // IsAliased
false, // IsExpression
false, // IsIdentity
Expand All @@ -426,7 +426,7 @@ public override DataTable GetSchemaTable()
false, // IsLong
true, // IsReadOnly
column.DataType, // ProviderSpecificDataType
column.DataType.Name, // DataTypeName TODO: Convert to T-SQL data type name
GetDataTypeName(column.Ordinal), // DataTypeName
DBNull.Value, // XmlSchemaCollectionDatabase
DBNull.Value, // XmlSchemaCollectionOwningSchema
DBNull.Value, // XmlSchemaCollectionName
Expand Down
4 changes: 2 additions & 2 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/AliasNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ public override string ToString()
return "Subquery Alias";
}

public override int EstimateRowsOut(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
protected override int EstimateRowsOutInternal(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
{
return Source.EstimateRowsOut(dataSources, options, parameterTypes);
return Source.EstimatedRowsOut;
}

public override IEnumerable<IExecutionPlanNode> GetSources()
Expand Down
4 changes: 2 additions & 2 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/AssertNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ public override void AddRequiredColumns(IDictionary<string, DataSource> dataSour
Source.AddRequiredColumns(dataSources, parameterTypes, requiredColumns);
}

public override int EstimateRowsOut(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
protected override int EstimateRowsOutInternal(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
{
return Source.EstimateRowsOut(dataSources, options, parameterTypes);
return Source.EstimatedRowsOut;
}

public override object Clone()
Expand Down
4 changes: 2 additions & 2 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseAggregateNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,12 @@ protected bool IsAggregateQueryRetryable(OrganizationServiceFault fault)
return false;
}

public override int EstimateRowsOut(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
protected override int EstimateRowsOutInternal(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
{
if (GroupBy.Count == 0)
return 1;

return Source.EstimateRowsOut(dataSources, options, parameterTypes) * 4 / 10;
return Source.EstimatedRowsOut * 4 / 10;
}

public override void AddRequiredColumns(IDictionary<string, DataSource> dataSources, IDictionary<string, DataTypeReference> parameterTypes, IList<string> requiredColumns)
Expand Down
12 changes: 11 additions & 1 deletion MarkMpn.Sql4Cds.Engine/ExecutionPlan/BaseDataNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,17 @@ public IEnumerable<Entity> Execute(IDictionary<string, DataSource> dataSources,
/// <param name="parameterTypes">A mapping of parameter names to their related types</param>
/// <param name="tableSize">A cache of the number of records in each table</param>
/// <returns>The number of rows the node is estimated to return</returns>
public abstract int EstimateRowsOut(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes);
public virtual void EstimateRowsOut(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
{
foreach (var child in GetSources().OfType<IDataExecutionPlanNodeInternal>())
child.EstimateRowsOut(dataSources, options, parameterTypes);

EstimatedRowsOut = EstimateRowsOutInternal(dataSources, options, parameterTypes);
}

protected abstract int EstimateRowsOutInternal(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes);

public int EstimatedRowsOut { get; protected set; }

/// <summary>
/// Returns the number of times the node has been executed
Expand Down
4 changes: 2 additions & 2 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/ComputeScalarNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ public override void AddRequiredColumns(IDictionary<string, DataSource> dataSour
Source.AddRequiredColumns(dataSources, parameterTypes, requiredColumns);
}

public override int EstimateRowsOut(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
protected override int EstimateRowsOutInternal(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
{
return Source.EstimateRowsOut(dataSources, options, parameterTypes);
return Source.EstimatedRowsOut;
}

public override object Clone()
Expand Down
4 changes: 2 additions & 2 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/ConcatenateNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ public override void AddRequiredColumns(IDictionary<string, DataSource> dataSour
}
}

public override int EstimateRowsOut(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
protected override int EstimateRowsOutInternal(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
{
return Sources.Sum(s => s.EstimateRowsOut(dataSources, options, parameterTypes));
return Sources.Sum(s => s.EstimatedRowsOut);
}

public override object Clone()
Expand Down
2 changes: 1 addition & 1 deletion MarkMpn.Sql4Cds.Engine/ExecutionPlan/ConstantScanNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public override void AddRequiredColumns(IDictionary<string, DataSource> dataSour
{
}

public override int EstimateRowsOut(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
protected override int EstimateRowsOutInternal(IDictionary<string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary<string, DataTypeReference> parameterTypes)
{
return Values.Count;
}
Expand Down
Loading

0 comments on commit c23fd39

Please sign in to comment.