Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
52102e8
Merge AsyncState class, _cachedAsyncState and CachedAsyncState
benrr101 Sep 4, 2025
e980e0f
Add partial for batch RPC mode methods
benrr101 Sep 11, 2025
9332cf6
Merge:
benrr101 Sep 11, 2025
06ec76e
Merge AddBatchCommand
benrr101 Sep 12, 2025
d47b9d2
Merge SetBatchRPCMode and SetBatchRPCModeReadyToExecute
benrr101 Sep 12, 2025
09d6cc9
Merge ClearBatchCommand (and make it private)
benrr101 Sep 12, 2025
e6b56c2
Merging _RPCList and _currentlyExecutingBatch
benrr101 Sep 12, 2025
54af4d5
Merge DebugForceAsyncWriteDelay
benrr101 Sep 12, 2025
f7b4bd9
Merge MaxRPCNameLength, s_cancelIgnoreFailure, CancelIgnoreFailureCal…
benrr101 Sep 12, 2025
f906eb1
Merge: s_diagnosticListener, _parentOperationStarted, _rpcArrayOf1, _…
benrr101 Sep 12, 2025
5473e48
Merge WriteBeginExecuteEvent and WriteEndExecuteEvent (interted if an…
benrr101 Sep 12, 2025
8aeab64
Merge CheckThrowSNIException (made private, rewritten as ?.), OnConne…
benrr101 Sep 12, 2025
28d7c31
Merge BuildParamList (combine a bunch of StringBuilder.Append into Ap…
benrr101 Sep 12, 2025
c2a3f95
Merge ParseAndQuoteIdentifier and QuoteIdentifier (using netcore vers…
benrr101 Sep 12, 2025
b871633
Merge GetRPCObject
benrr101 Sep 12, 2025
1d34c06
Merge SetUpRPCParameters
benrr101 Sep 15, 2025
32feb5a
Merge ShouldSendParameter, CountSendableParameters (inverted logic), …
benrr101 Sep 15, 2025
7700e4e
Merge GetSetOptionsString (made static, renamed to GetOptionsSetStrin…
benrr101 Sep 15, 2025
29ee4fa
Merging GetParameterForOutputValueExtraction (made static, rewrote to…
benrr101 Sep 15, 2025
a2c2953
Merge ReliablePutStateObject, PutStateObject, GetCurrentParameterColl…
benrr101 Sep 15, 2025
7b94854
Merge GetStateObject
benrr101 Sep 15, 2025
7528548
Merge ValidateCommand, ValidateAsyncCommand
benrr101 Sep 15, 2025
dac10ad
Merge CheckNotificationStateAndAutoEnlist, RegisterForConnectionClose…
benrr101 Sep 15, 2025
96132fa
Merge DeriveParameters, GetParameterDirectionFromOleDbDirection
benrr101 Sep 15, 2025
13eae89
Merge TriggerInternalEndAndRetryIfNecessary and CreateLocalCompletion…
benrr101 Sep 15, 2025
1a881c6
Merge OnStatementCompleted
benrr101 Sep 15, 2025
8f55436
Merge UnquoteProcedureName and UnquoteProcedurePart
benrr101 Sep 17, 2025
c743710
Merge ThrowIfReconnectionHasBeenCanceled (inverted, using conditional…
benrr101 Sep 17, 2025
87cfc4f
Merge WaitForAsyncResults
benrr101 Sep 17, 2025
7a079cf
Merge VerifyEndExecuteState (THE LAST ONE)
benrr101 Sep 17, 2025
0088f9d
Delete pre-merge (and now empty) SqlCommand files
benrr101 Sep 18, 2025
c7c6a77
PR comments from copilot
benrr101 Oct 31, 2025
fd6d1c2
Revert a couple changes on BuildParamList
benrr101 Oct 31, 2025
6e2188e
Found a bug in BuildParamList, rolling back a couple changes that wer…
benrr101 Nov 3, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,9 @@
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\SqlCommand.cs">
<Link>Microsoft\Data\SqlClient\SqlCommand.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\SqlCommand.Batch.cs">
<Link>Microsoft\Data\SqlClient\SqlCommand.Batch.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\SqlCommand.Encryption.cs">
<Link>Microsoft\Data\SqlClient\SqlCommand.Encryption.cs</Link>
</Compile>
Expand Down Expand Up @@ -840,8 +843,7 @@
<Compile Include="$(CommonSourceRoot)System\Diagnostics\CodeAnalysis.cs">
<Link>System\Diagnostics\CodeAnalysis.cs</Link>
</Compile>

<Compile Include="Microsoft\Data\SqlClient\SqlCommand.netcore.cs" />

<Compile Include="Microsoft\Data\SqlClient\SqlInternalConnectionTds.cs" />
<Compile Include="Microsoft.Data.SqlClient.TypeForwards.cs" />
</ItemGroup>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,9 @@
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\SqlCommand.cs">
<Link>Microsoft\Data\SqlClient\SqlCommand.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\SqlCommand.Batch.cs">
<Link>Microsoft\Data\SqlClient\SqlCommand.Batch.cs</Link>
</Compile>
<Compile Include="$(CommonSourceRoot)Microsoft\Data\SqlClient\SqlCommand.Encryption.cs">
<Link>Microsoft\Data\SqlClient\SqlCommand.Encryption.cs</Link>
</Compile>
Expand Down Expand Up @@ -1014,8 +1017,7 @@
<Compile Include="$(CommonSourceRoot)System\Runtime\CompilerServices\IsExternalInit.netfx.cs">
<Link>System\Runtime\CompilerServices\IsExternalInit.netfx.cs</Link>
</Compile>

<Compile Include="Microsoft\Data\SqlClient\SqlCommand.netfx.cs" />

<Compile Include="Microsoft\Data\SqlClient\SqlInternalConnectionTds.cs" />
</ItemGroup>
<!-- Resources -->
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.Data;
using System.Diagnostics;

namespace Microsoft.Data.SqlClient
{
// @TODO: There's a good question here - should this be a separate type of SqlCommand?
public sealed partial class SqlCommand
{
#region Internal Methods

internal void AddBatchCommand(SqlBatchCommand batchCommand)
{
Debug.Assert(_batchRPCMode, "Command is not in batch RPC Mode");
Debug.Assert(_RPCList is not null);

_SqlRPC rpc = new _SqlRPC { batchCommand = batchCommand };
string commandText = batchCommand.CommandText;
CommandType cmdType = batchCommand.CommandType;

CommandText = commandText;
CommandType = cmdType;

SetColumnEncryptionSetting(batchCommand.ColumnEncryptionSetting);

// @TODO: Hmm, maybe we could have get/put become a IDisposable thing
GetStateObject();
if (cmdType is CommandType.StoredProcedure)
{
BuildRPC(inSchema: false, batchCommand.Parameters, ref rpc);
}
else
{
// All batch sql statements must be executed inside sp_executesql, including those
// without parameters
BuildExecuteSql(CommandBehavior.Default, commandText, batchCommand.Parameters, ref rpc);
}

_RPCList.Add(rpc);
ReliablePutStateObject();
}

internal SqlBatchCommand GetBatchCommand(int index) =>
_RPCList[index].batchCommand;

// @TODO: This should be a property.
internal SqlBatchCommand GetCurrentBatchCommand()
{
return _batchRPCMode
? _RPCList[_currentlyExecutingBatch].batchCommand
: _rpcArrayOf1?[0].batchCommand;
}

// @TODO: 1) This should be a property
// @TODO: 2) This could be a `int?`
internal int GetCurrentBatchIndex() =>
_batchRPCMode ? _currentlyExecutingBatch : -1;

// @TODO: Indicate this is for batch RPC usage
internal SqlException GetErrors(int commandIndex)
{
SqlException result = null;

_SqlRPC rpc = _RPCList[commandIndex];
int length = rpc.errorsIndexEnd - rpc.errorsIndexStart;
if (length > 0)
{
SqlErrorCollection errors = new SqlErrorCollection();
for (int i = rpc.errorsIndexStart; i < rpc.errorsIndexEnd; i++)
{
errors.Add(rpc.errors[i]);
}
for (int i = rpc.warningsIndexStart; i < rpc.warningsIndexEnd; i++)
{
errors.Add(rpc.warnings[i]);
}

result = SqlException.CreateException(
errors,
_activeConnection.ServerVersion,
_activeConnection.ClientConnectionId,
innerException: null,
batchCommand: null);
}

return result;
}

// @TODO: Should be renamed to indicate only applies to batch RPC mode
internal int? GetRecordsAffected(int commandIndex)
{
Debug.Assert(_batchRPCMode, "Command is not in batch RPC mode");
Debug.Assert(_RPCList is not null, "Batch commands have been cleared");
return _RPCList[commandIndex].recordsAffected;
}

// @TODO: Rename to match naming conventions
internal void SetBatchRPCMode(bool value, int commandCount = 1)
{
_batchRPCMode = value;
ClearBatchCommand();
if (_batchRPCMode)
{
if (_RPCList is null)
{
// @TODO: Could this be done with an array?
_RPCList = new List<_SqlRPC>(commandCount);
}
else
{
_RPCList.Capacity = commandCount;
}
}
}

// @TODO: Rename to match naming conventions
internal void SetBatchRPCModeReadyToExecute()
{
Debug.Assert(_batchRPCMode, "Command is not in batch RPC Mode");
Debug.Assert(_RPCList is not null, "No batch commands specified");

_currentlyExecutingBatch = 0;
}

#endregion

#region Private Methods

private void ClearBatchCommand()
{
_RPCList?.Clear();
_currentlyExecutingBatch = 0;
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1351,7 +1351,11 @@ private SqlDataReader TryFetchInputParameterEncryptionInfo(
_sqlRPCParameterEncryptionReqArray = new _SqlRPC[1];

_SqlRPC rpc = null;
GetRPCObject(systemParamCount: 0, GetParameterCount(_parameters), ref rpc);
GetRPCObject(
systemParamCount: 0,
GetParameterCount(_parameters),
ref rpc,
forSpDescribeParameterEncryption: false);
Debug.Assert(rpc is not null, "GetRPCObject should not return rpc as null.");

rpc.rpcName = CommandText;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public override int ExecuteNonQuery()
finally
{
SqlStatistics.StopTimer(statistics);
WriteEndExecuteEvent(success, sqlExceptionNumber, synchronous: true);
WriteEndExecuteEvent(success, sqlExceptionNumber, isSynchronous: true);
}
}

Expand Down Expand Up @@ -414,7 +414,7 @@ private int EndExecuteNonQueryInternal(IAsyncResult asyncResult)
finally
{
SqlStatistics.StopTimer(statistics);
WriteEndExecuteEvent(success, sqlExceptionNumber, synchronous: false);
WriteEndExecuteEvent(success, sqlExceptionNumber, isSynchronous: false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public SqlDataReader EndExecuteReader(IAsyncResult asyncResult)
finally
{
SqlStatistics.StopTimer(statistics);
WriteEndExecuteEvent(success, sqlExceptionNumber, synchronous: true);
WriteEndExecuteEvent(success, sqlExceptionNumber, isSynchronous: true);

if (e is not null)
{
Expand Down Expand Up @@ -409,7 +409,11 @@ private _SqlRPC BuildExecute(bool inSchema)
int userParameterCount = CountSendableParameters(_parameters);

_SqlRPC rpc = null;
GetRPCObject(systemParameterCount, userParameterCount, ref rpc);
GetRPCObject(
systemParameterCount,
userParameterCount,
ref rpc,
forSpDescribeParameterEncryption: false);
rpc.ProcID = TdsEnums.RPC_PROCID_EXECUTE;
rpc.rpcName = TdsEnums.SP_EXECUTE;

Expand Down Expand Up @@ -445,7 +449,11 @@ private void BuildExecuteSql(
int userParamCount = CountSendableParameters(parameters);
int systemParamCount = userParamCount > 0 ? 2 : 1;

GetRPCObject(systemParamCount, userParamCount, ref rpc);
GetRPCObject(
systemParamCount,
userParamCount,
ref rpc,
forSpDescribeParameterEncryption: false);
rpc.ProcID = TdsEnums.RPC_PROCID_EXECUTESQL;
rpc.rpcName = TdsEnums.SP_EXECUTESQL;

Expand All @@ -465,7 +473,10 @@ private void BuildExecuteSql(
if (userParamCount > 0)
{
// @TODO: Why does batch RPC mode use different parameters?
string paramList = BuildParamList(_stateObj.Parser, _batchRPCMode ? parameters : _parameters);
string paramList = BuildParamList(
_stateObj.Parser,
_batchRPCMode ? parameters : _parameters,
includeReturnValue: false);
sqlParam = rpc.systemParams[1];
sqlParam.SqlDbType = (paramList.Length << 1) <= TdsEnums.TYPE_SIZE_LIMIT
? SqlDbType.NVarChar
Expand All @@ -488,7 +499,11 @@ private _SqlRPC BuildPrepExec(CommandBehavior behavior)
int userParameterCount = CountSendableParameters(_parameters);

_SqlRPC rpc = null;
GetRPCObject(systemParameterCount, userParameterCount, ref rpc);
GetRPCObject(
systemParameterCount,
userParameterCount,
ref rpc,
forSpDescribeParameterEncryption: false);
rpc.ProcID = TdsEnums.RPC_PROCID_PREPEXEC;
rpc.rpcName = TdsEnums.SP_PREPEXEC;

Expand All @@ -503,7 +518,10 @@ private _SqlRPC BuildPrepExec(CommandBehavior behavior)
rpc.systemParamOptions[0] = TdsEnums.RPC_PARAM_BYREF;

// @batch_params
string paramList = BuildParamList(_stateObj.Parser, _parameters);
string paramList = BuildParamList(
_stateObj.Parser,
_parameters,
includeReturnValue: false);
sqlParam = rpc.systemParams[1];
// @TODO: This pattern is used quite a bit - it could be factored out
sqlParam.SqlDbType = (paramList.Length << 1) <= TdsEnums.TYPE_SIZE_LIMIT
Expand All @@ -519,8 +537,8 @@ private _SqlRPC BuildPrepExec(CommandBehavior behavior)
sqlParam.SqlDbType = (text.Length << 1) <= TdsEnums.TYPE_SIZE_LIMIT
? SqlDbType.NVarChar
: SqlDbType.NText;
sqlParam.Size = text.Length;
sqlParam.Value = text;
sqlParam.Size = text.Length;
sqlParam.Direction = ParameterDirection.Input;

SetUpRPCParameters(rpc, inSchema: false, _parameters);
Expand All @@ -538,7 +556,11 @@ private void BuildRPC(bool inSchema, SqlParameterCollection parameters, ref _Sql
Debug.Assert(CommandType is CommandType.StoredProcedure, "Command must be a stored proc to execute an RPC");

int userParameterCount = CountSendableParameters(parameters);
GetRPCObject(systemParamCount: 0, userParameterCount, ref rpc);
GetRPCObject(
systemParamCount: 0,
userParameterCount,
ref rpc,
forSpDescribeParameterEncryption: false);
rpc.ProcID = 0;

// TDS Protocol allows rpc name with maximum length of 1046 bytes for ProcName
Expand Down Expand Up @@ -710,7 +732,7 @@ private SqlDataReader EndExecuteReaderInternal(IAsyncResult asyncResult)
finally
{
SqlStatistics.StopTimer(statistics);
WriteEndExecuteEvent(success, sqlExceptionNumber, synchronous: false);
WriteEndExecuteEvent(success, sqlExceptionNumber, isSynchronous: false);
}
}

Expand Down Expand Up @@ -1359,7 +1381,7 @@ private SqlDataReader RunExecuteReaderTds(
$"Command Text '{CommandText}'");
}

string text = GetCommandText(cmdBehavior) + GetResetOptionsString(cmdBehavior);
string text = GetCommandText(cmdBehavior) + GetOptionsResetString(cmdBehavior);

// If the query requires enclave computations, pass the enclave package in the
// SqlBatch TDS stream
Expand Down Expand Up @@ -1467,7 +1489,7 @@ private SqlDataReader RunExecuteReaderTds(
// If we need to augment the command because a user has changed the command
// behavior (e.g. FillSchema) then batch sql them over. This is inefficient (3
// round trips) but the only way we can get metadata only from a stored proc.
optionSettings = GetSetOptionsString(cmdBehavior);
optionSettings = GetOptionsSetString(cmdBehavior);

if (returnStream)
{
Expand Down Expand Up @@ -1506,7 +1528,7 @@ private SqlDataReader RunExecuteReaderTds(
}

// And turn OFF when the ds exhausts the stream on Close()
optionSettings = GetResetOptionsString(cmdBehavior);
optionSettings = GetOptionsResetString(cmdBehavior);
}

// Execute sproc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public override object ExecuteScalar()
finally
{
SqlStatistics.StopTimer(statistics);
WriteEndExecuteEvent(success, sqlExceptionNumber, synchronous: true);
WriteEndExecuteEvent(success, sqlExceptionNumber, isSynchronous: true);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public XmlReader ExecuteXmlReader()
finally
{
SqlStatistics.StopTimer(statistics);
WriteEndExecuteEvent(success, sqlExceptionNumber, synchronous: true);
WriteEndExecuteEvent(success, sqlExceptionNumber, isSynchronous: true);
}
}

Expand Down Expand Up @@ -448,7 +448,7 @@ private XmlReader EndExecuteXmlReaderInternal(IAsyncResult asyncResult)
}
finally
{
WriteEndExecuteEvent(success, sqlExceptionNumber, synchronous: false);
WriteEndExecuteEvent(success, sqlExceptionNumber, isSynchronous: false);
}
}

Expand Down
Loading
Loading