diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs
index 6956e3ae61..4f71e27949 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs
@@ -2350,8 +2350,7 @@ private static void ChangePassword(string connectionString, SqlConnectionString
}
finally
{
- if (con != null)
- con.Dispose();
+ con?.Dispose();
}
SqlConnectionPoolKey key = new SqlConnectionPoolKey(connectionString, credential, accessToken: null, accessTokenCallback: null);
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs
index b337483592..7509d97121 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs
@@ -251,8 +251,6 @@ internal EncryptionOptions EncryptionOptions
}
}
- internal bool Is2005OrNewer => true;
-
internal bool Is2008OrNewer
{
get
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
index 26f975171c..810487f52d 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs
@@ -112,14 +112,6 @@ internal object[] CreateRowBuffer()
///
public sealed class SqlBulkCopy : IDisposable
{
- private enum TableNameComponents
- {
- Server = 0,
- Catalog,
- Owner,
- TableName,
- }
-
private enum ValueSourceType
{
Unspecified = 0,
@@ -161,10 +153,6 @@ public SourceColumnMetadata(ValueMethod method, bool isSqlType, bool isDataFeed)
// MetaData has n columns but no rows
// Collation has 4 columns and n rows
- private const int TranCountResultId = 0;
- private const int TranCountRowId = 0;
- private const int TranCountValueId = 0;
-
private const int MetaDataResultId = 1;
private const int CollationResultId = 2;
@@ -439,66 +427,60 @@ private string CreateInitialQuery()
string TDSCommand;
TDSCommand = "select @@trancount; SET FMTONLY ON select * from " + ADP.BuildMultiPartName(parts) + " SET FMTONLY OFF ";
- if (_connection.Is2000)
- {
- // If its a temp DB then try to connect
- string TableCollationsStoredProc;
- if (_connection.Is2008OrNewer)
- {
- TableCollationsStoredProc = "sp_tablecollations_100";
- }
- else if (_connection.Is2005OrNewer)
- {
- TableCollationsStoredProc = "sp_tablecollations_90";
- }
- else
- {
- TableCollationsStoredProc = "sp_tablecollations";
- }
+ // If its a temp DB then try to connect
- string TableName = parts[MultipartIdentifier.TableIndex];
- bool isTempTable = TableName.Length > 0 && '#' == TableName[0];
- if (!ADP.IsEmpty(TableName))
- {
- // Escape table name to be put inside TSQL literal block (within N'').
- TableName = SqlServerEscapeHelper.EscapeStringAsLiteral(TableName);
- // VSDD 581951 - escape the table name
- TableName = SqlServerEscapeHelper.EscapeIdentifier(TableName);
- }
+ string TableCollationsStoredProc;
+ if (_connection.Is2008OrNewer)
+ {
+ TableCollationsStoredProc = "sp_tablecollations_100";
+ }
+ else
+ {
+ TableCollationsStoredProc = "sp_tablecollations_90";
+ }
- string SchemaName = parts[MultipartIdentifier.SchemaIndex];
- if (!ADP.IsEmpty(SchemaName))
- {
- // Escape schema name to be put inside TSQL literal block (within N'').
- SchemaName = SqlServerEscapeHelper.EscapeStringAsLiteral(SchemaName);
- // VSDD 581951 - escape the schema name
- SchemaName = SqlServerEscapeHelper.EscapeIdentifier(SchemaName);
- }
+ string TableName = parts[MultipartIdentifier.TableIndex];
+ bool isTempTable = TableName.Length > 0 && '#' == TableName[0];
+ if (!ADP.IsEmpty(TableName))
+ {
+ // Escape table name to be put inside TSQL literal block (within N'').
+ TableName = SqlServerEscapeHelper.EscapeStringAsLiteral(TableName);
+ // VSDD 581951 - escape the table name
+ TableName = SqlServerEscapeHelper.EscapeIdentifier(TableName);
+ }
- string CatalogName = parts[MultipartIdentifier.CatalogIndex];
- if (isTempTable && ADP.IsEmpty(CatalogName))
- {
- TDSCommand += string.Format("exec tempdb..{0} N'{1}.{2}'",
- TableCollationsStoredProc,
- SchemaName,
- TableName
- );
- }
- else
+ string SchemaName = parts[MultipartIdentifier.SchemaIndex];
+ if (!ADP.IsEmpty(SchemaName))
+ {
+ // Escape schema name to be put inside TSQL literal block (within N'').
+ SchemaName = SqlServerEscapeHelper.EscapeStringAsLiteral(SchemaName);
+ // VSDD 581951 - escape the schema name
+ SchemaName = SqlServerEscapeHelper.EscapeIdentifier(SchemaName);
+ }
+
+ string CatalogName = parts[MultipartIdentifier.CatalogIndex];
+ if (isTempTable && ADP.IsEmpty(CatalogName))
+ {
+ TDSCommand += string.Format("exec tempdb..{0} N'{1}.{2}'",
+ TableCollationsStoredProc,
+ SchemaName,
+ TableName
+ );
+ }
+ else
+ {
+ // VSDD 581951 - escape the catalog name
+ if (!ADP.IsEmpty(CatalogName))
{
- // VSDD 581951 - escape the catalog name
- if (!ADP.IsEmpty(CatalogName))
- {
- CatalogName = SqlServerEscapeHelper.EscapeIdentifier(CatalogName);
- }
- TDSCommand += string.Format("exec {0}..{1} N'{2}.{3}'",
- CatalogName,
- TableCollationsStoredProc,
- SchemaName,
- TableName
- );
+ CatalogName = SqlServerEscapeHelper.EscapeIdentifier(CatalogName);
}
+ TDSCommand += string.Format("exec {0}..{1} N'{2}.{3}'",
+ CatalogName,
+ TableCollationsStoredProc,
+ SchemaName,
+ TableName
+ );
}
return TDSCommand;
}
@@ -549,7 +531,7 @@ private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet i
StringBuilder updateBulkCommandText = new StringBuilder();
- if (_connection.Is2000 && 0 == internalResults[CollationResultId].Count)
+ if (0 == internalResults[CollationResultId].Count)
{
throw SQL.BulkLoadNoCollation();
}
@@ -562,15 +544,7 @@ private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet i
bool isInTransaction;
- if (_parser.Is2005OrNewer)
- {
- isInTransaction = _connection.HasLocalTransaction;
- }
- else
- {
- isInTransaction = (bool)(0 < (SqlInt32)(internalResults[TranCountResultId][TranCountRowId][TranCountValueId]));
- }
-
+ isInTransaction = _connection.HasLocalTransaction;
// Throw if there is a transaction but no flag is set
if (isInTransaction &&
_externalTransaction == null &&
@@ -701,50 +675,45 @@ private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet i
}
}
- if (_connection.Is2000)
- {
- // 2000 or above!
- // get collation for column i
+ // Get collation for column i
+ Result rowset = internalResults[CollationResultId];
+ object rowvalue = rowset[i][CollationId];
- Result rowset = internalResults[CollationResultId];
- object rowvalue = rowset[i][CollationId];
+ bool shouldSendCollation;
+ switch (metadata.type)
+ {
+ case SqlDbType.Char:
+ case SqlDbType.NChar:
+ case SqlDbType.VarChar:
+ case SqlDbType.NVarChar:
+ case SqlDbType.Text:
+ case SqlDbType.NText:
+ shouldSendCollation = true;
+ break;
- bool shouldSendCollation;
- switch (metadata.type)
- {
- case SqlDbType.Char:
- case SqlDbType.NChar:
- case SqlDbType.VarChar:
- case SqlDbType.NVarChar:
- case SqlDbType.Text:
- case SqlDbType.NText:
- shouldSendCollation = true;
- break;
+ default:
+ shouldSendCollation = false;
+ break;
+ }
- default:
- shouldSendCollation = false;
- break;
- }
+ if (rowvalue != null && shouldSendCollation)
+ {
+ Debug.Assert(rowvalue is SqlString);
+ SqlString collation_name = (SqlString)rowvalue;
- if (rowvalue != null && shouldSendCollation)
+ if (!collation_name.IsNull)
{
- Debug.Assert(rowvalue is SqlString);
- SqlString collation_name = (SqlString)rowvalue;
-
- if (!collation_name.IsNull)
+ updateBulkCommandText.Append(" COLLATE " + collation_name.Value);
+ // VSTFDEVDIV 461426: compare collations only if the collation value was set on the metadata
+ if (_sqlDataReaderRowSource != null && metadata.collation != null)
{
- updateBulkCommandText.Append(" COLLATE " + collation_name.Value);
- // VSTFDEVDIV 461426: compare collations only if the collation value was set on the metadata
- if (_sqlDataReaderRowSource != null && metadata.collation != null)
+ // On SqlDataReader we can verify the sourcecolumn collation!
+ int sourceColumnId = _localColumnMappings[assocId]._internalSourceColumnOrdinal;
+ int destinationLcid = metadata.collation.LCID;
+ int sourceLcid = _sqlDataReaderRowSource.GetLocaleId(sourceColumnId);
+ if (sourceLcid != destinationLcid)
{
- // On SqlDataReader we can verify the sourcecolumn collation!
- int sourceColumnId = _localColumnMappings[assocId]._internalSourceColumnOrdinal;
- int destinationLcid = metadata.collation.LCID;
- int sourceLcid = _sqlDataReaderRowSource.GetLocaleId(sourceColumnId);
- if (sourceLcid != destinationLcid)
- {
- throw SQL.BulkLoadLcidMismatch(sourceLcid, _sqlDataReaderRowSource.GetName(sourceColumnId), destinationLcid, metadata.column);
- }
+ throw SQL.BulkLoadLcidMismatch(sourceLcid, _sqlDataReaderRowSource.GetName(sourceColumnId), destinationLcid, metadata.column);
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs
index 4e6d7d0099..147be61b59 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs
@@ -598,17 +598,6 @@ private SqlInternalConnectionTds InternalTdsConnection
}
}
- private bool Is2000
- {
- get
- {
- Debug.Assert(_activeConnection != null, "The active connection is null!");
- if (_activeConnection == null)
- return false;
- return _activeConnection.Is2000;
- }
- }
-
private bool IsProviderRetriable => SqlConfigurableRetryFactory.IsRetriable(RetryLogicProvider);
///
@@ -3441,16 +3430,8 @@ internal void DeriveParameters()
}
else
{
- if (this.Connection.Is2005OrNewer)
- {
- // Procedure - [sp_procedure_params_managed]
- cmdText.Append("[sys].[").Append(TdsEnums.SP_PARAMS_MANAGED).Append("]");
- }
- else
- {
- // Procedure - [sp_procedure_params_rowset]
- cmdText.Append(".[").Append(TdsEnums.SP_PARAMS).Append("]");
- }
+ // Procedure - [sp_procedure_params_managed]
+ cmdText.Append("[sys].[").Append(TdsEnums.SP_PARAMS_MANAGED).Append("]");
colNames = PreSql2008ProcParamsNames;
useManagedDataType = false;
@@ -3567,9 +3548,6 @@ internal void DeriveParameters()
// type name for Udt
if (SqlDbType.Udt == p.SqlDbType)
{
-
- Debug.Assert(this._activeConnection.Is2005OrNewer, "Invalid datatype token received from pre-2005 server");
-
string udtTypeName;
if (useManagedDataType)
{
@@ -3693,19 +3671,16 @@ private void CheckNotificationStateAndAutoEnlist()
// present. If so, auto enlist to the dependency ID given in the context data.
if (NotificationAutoEnlist)
{
- if (_activeConnection.Is2005OrNewer)
- { // Only supported for 2005...
- string notifyContext = SqlNotificationContext();
- if (!ADP.IsEmpty(notifyContext))
- {
- // Map to dependency by ID set in context data.
- SqlDependency dependency = SqlDependencyPerAppDomainDispatcher.SingletonInstance.LookupDependencyEntry(notifyContext);
+ string notifyContext = SqlNotificationContext();
+ if (!ADP.IsEmpty(notifyContext))
+ {
+ // Map to dependency by ID set in context data.
+ SqlDependency dependency = SqlDependencyPerAppDomainDispatcher.SingletonInstance.LookupDependencyEntry(notifyContext);
- if (dependency != null)
- {
- // Add this command to the dependency.
- dependency.AddCommandDependency(this);
- }
+ if (dependency != null)
+ {
+ // Add this command to the dependency.
+ dependency.AddCommandDependency(this);
}
}
}
@@ -5342,7 +5317,6 @@ private SqlDataReader RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavi
}
else if (_execType == EXECTYPE.PREPAREPENDING)
{
- Debug.Assert(_activeConnection.Is2000, "Invalid attempt to call sp_prepexec on non 7.x server");
rpc = BuildPrepExec(cmdBehavior);
// next time through, only do an exec
_execType = EXECTYPE.PREPARED;
@@ -5358,8 +5332,7 @@ private SqlDataReader RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavi
}
// if 2000, then set NOMETADATA_UNLESSCHANGED flag
- if (_activeConnection.Is2000)
- rpc.options = TdsEnums.RPC_NOMETADATA;
+ rpc.options = TdsEnums.RPC_NOMETADATA;
if (returnStream)
{
SqlClientEventSource.Log.TryTraceEvent(" {0}, Command executed as RPC.", ObjectID);
@@ -5372,10 +5345,6 @@ private SqlDataReader RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavi
else
{
Debug.Assert(this.CommandType == System.Data.CommandType.StoredProcedure, "unknown command type!");
- // note: invalid asserts on 2000. On 8.0 (2000) and above a command is ALWAYS prepared
- // and IsDirty is always set if there are changes and the command is marked Prepared!
- Debug.Assert(Is2000 || !IsPrepared, "RPC should not be prepared!");
- Debug.Assert(Is2000 || !IsDirty, "RPC should not be marked as dirty!");
BuildRPC(inSchema, _parameters, ref rpc);
@@ -5813,12 +5782,6 @@ private void ValidateCommand(string method, bool async)
throw ADP.CommandTextRequired(method);
}
- // Notification property must be null for pre-2005 connections
- if ((Notification != null) && !_activeConnection.Is2005OrNewer)
- {
- throw SQL.NotificationsRequire2005();
- }
-
if ((async) && (_activeConnection.IsContextConnection))
{
// Async not supported on Context Connections
@@ -6849,14 +6812,7 @@ internal string BuildParamList(TdsParser parser, SqlParameterCollection paramete
if (0 == precision)
{
- if (Is2000)
- {
- precision = TdsEnums.DEFAULT_NUMERIC_PRECISION;
- }
- else
- {
- precision = TdsEnums.SQL70_DEFAULT_NUMERIC_PRECISION;
- }
+ precision = TdsEnums.DEFAULT_NUMERIC_PRECISION;
}
paramList.Append(precision);
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs
index a4663d8530..ae4a61c65b 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs
@@ -2198,30 +2198,6 @@ internal bool HasLocalTransactionFromAPI
}
}
- internal bool Is2000
- {
- get
- {
- if (_currentReconnectionTask != null)
- { // holds true even if task is completed
- return true; // if CR is enabled, connection, if established, will be 2008+
- }
- return GetOpenConnection().Is2000;
- }
- }
-
- internal bool Is2005OrNewer
- {
- get
- {
- if (_currentReconnectionTask != null)
- { // holds true even if task is completed
- return true; // if CR is enabled, connection, if established, will be 2008+
- }
- return GetOpenConnection().Is2005OrNewer;
- }
- }
-
internal bool Is2008OrNewer
{
get
@@ -2538,12 +2514,14 @@ private static void ChangePassword(string connectionString, SqlConnectionString
// Normally we would simply create a regular connectoin and open it but there is no other way to pass the
// new password down to the constructor. Also it would have an unwanted impact on the connection pool
//
- using (SqlInternalConnectionTds con = new SqlInternalConnectionTds(null, connectionOptions, credential, null, newPassword, newSecurePassword, false, null, null, null, null))
+ SqlInternalConnectionTds con = null;
+ try
{
- if (!con.Is2005OrNewer)
- {
- throw SQL.ChangePasswordRequires2005();
- }
+ con = new SqlInternalConnectionTds(null, connectionOptions, credential, null, newPassword, newSecurePassword, false, null, null, null, null);
+ }
+ finally
+ {
+ con?.Dispose();
}
SqlConnectionPoolKey key = new SqlConnectionPoolKey(connectionString, credential, accessToken: null, accessTokenCallback: null);
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs
index 60a8cf6153..a316b8763c 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs
@@ -641,12 +641,10 @@ internal DataTable BuildSchemaTable()
if (col.type == SqlDbType.Udt)
{ // Additional metadata for UDTs.
- Debug.Assert(Connection.Is2005OrNewer, "Invalid Column type received from the server");
schemaRow[udtAssemblyQualifiedName] = col.udt?.AssemblyQualifiedName;
}
else if (col.type == SqlDbType.Xml)
{ // Additional metadata for Xml.
- Debug.Assert(Connection.Is2005OrNewer, "Invalid DataType (Xml) for the column");
schemaRow[xmlSchemaCollectionDatabase] = col.xmlSchemaCollection?.Database;
schemaRow[xmlSchemaCollectionOwningSchema] = col.xmlSchemaCollection?.OwningSchema;
schemaRow[xmlSchemaCollectionName] = col.xmlSchemaCollection?.Name;
@@ -1339,7 +1337,6 @@ private string GetDataTypeNameInternal(_SqlMetaData metaData)
if (metaData.type == SqlDbType.Udt)
{
- Debug.Assert(Connection.Is2005OrNewer, "Invalid Column type received from the server");
dataTypeName = metaData.udt?.DatabaseName + "." + metaData.udt?.SchemaName + "." + metaData.udt?.TypeName;
}
else
@@ -1428,7 +1425,6 @@ private Type GetFieldTypeInternal(_SqlMetaData metaData)
// TypeSystem.SQLServer2005 and above
if (metaData.type == SqlDbType.Udt)
{
- Debug.Assert(Connection.Is2005OrNewer, "Invalid Column type received from the server");
Connection.CheckGetExtendedUDTInfo(metaData, false);
fieldType = metaData.udt?.Type;
}
@@ -1541,7 +1537,6 @@ private Type GetProviderSpecificFieldTypeInternal(_SqlMetaData metaData)
// TypeSystem.SQLServer2005 and above
if (metaData.type == SqlDbType.Udt)
{
- Debug.Assert(Connection.Is2005OrNewer, "Invalid Column type received from the server");
Connection.CheckGetExtendedUDTInfo(metaData, false);
providerSpecificFieldType = metaData.udt?.Type;
}
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs
index 8a164eba37..59181ff602 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs
@@ -162,22 +162,6 @@ override internal bool IsLockedForBulkCopy
}
}
- override internal bool Is2000
- {
- get
- {
- return false; // Can't be direct connecting to 2000.
- }
- }
-
- override internal bool Is2005OrNewer
- {
- get
- {
- return true; // Must be direct connecting to 2005 or newer.
- }
- }
-
override internal bool Is2008OrNewer
{
get
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs
index 0659148c83..75a0f574f0 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs
@@ -714,16 +714,6 @@ override protected internal bool IsNonPoolableTransactionRoot
return IsTransactionRoot && (!Is2008OrNewer || Pool == null);
}
}
-
- override internal bool Is2000 => true;
-
- override internal bool Is2005OrNewer
- {
- get
- {
- return _parser.Is2005OrNewer;
- }
- }
override internal bool Is2008OrNewer
{
@@ -1028,39 +1018,11 @@ private void ResetConnection()
if (_fResetConnection)
{
- // Ensure we are either going against 2000, or we are not enlisted in a
- // distributed transaction - otherwise don't reset!
- if (Is2000)
- {
- // Pooled connections that are enlisted in a transaction must have their transaction
- // preserved when reseting the connection state. Otherwise, future uses of the connection
- // from the pool will execute outside of the transaction, in auto-commit mode.
- // https://github.com/dotnet/SqlClient/issues/2970
- _parser.PrepareResetConnection(EnlistedTransaction is not null && Pool is not null);
- }
- else if (!IsEnlistedInTransaction)
- {
- // If not 2000, we are going against 7.0. On 7.0, we
- // may only reset if not enlisted in a distributed transaction.
- try
- {
- // execute sp
- System.Threading.Tasks.Task executeTask = _parser.TdsExecuteSQLBatch("sp_reset_connection", 30, null, _parser._physicalStateObj, sync: true);
- Debug.Assert(executeTask == null, "Shouldn't get a task when doing sync writes");
- _parser.Run(RunBehavior.UntilDone, null, null, null, _parser._physicalStateObj);
- }
- catch (Exception e)
- {
- // UNDONE - should not be catching all exceptions!!!
- if (!ADP.IsCatchableExceptionType(e))
- {
- throw;
- }
-
- DoomThisConnection();
- ADP.TraceExceptionWithoutRethrow(e);
- }
- }
+ // Pooled connections that are enlisted in a transaction must have their transaction
+ // preserved when reseting the connection state. Otherwise, future uses of the connection
+ // from the pool will execute outside of the transaction, in auto-commit mode.
+ // https://github.com/dotnet/SqlClient/issues/2970
+ _parser.PrepareResetConnection(EnlistedTransaction is not null && Pool is not null);
// Reset hashtable values, since calling reset will not send us env_changes.
CurrentDatabase = _originalDatabase;
@@ -1123,103 +1085,7 @@ override internal void ExecuteTransaction(TransactionRequest transactionRequest,
string transactionName = name == null ? string.Empty : name;
- if (!_parser.Is2005OrNewer)
- {
- ExecuteTransactionPre2005(transactionRequest, transactionName, iso, internalTransaction);
- }
- else
- {
- ExecuteTransaction2005(transactionRequest, transactionName, iso, internalTransaction, isDelegateControlRequest);
- }
- }
-
- // This function will not handle idle connection resiliency, as older servers will not support it
- internal void ExecuteTransactionPre2005(
- TransactionRequest transactionRequest,
- string transactionName,
- System.Data.IsolationLevel iso,
- SqlInternalTransaction internalTransaction)
- {
- StringBuilder sqlBatch = new StringBuilder();
-
- switch (iso)
- {
- case System.Data.IsolationLevel.Unspecified:
- break;
- case System.Data.IsolationLevel.ReadCommitted:
- sqlBatch.Append(TdsEnums.TRANS_READ_COMMITTED);
- sqlBatch.Append(";");
- break;
- case System.Data.IsolationLevel.ReadUncommitted:
- sqlBatch.Append(TdsEnums.TRANS_READ_UNCOMMITTED);
- sqlBatch.Append(";");
- break;
- case System.Data.IsolationLevel.RepeatableRead:
- sqlBatch.Append(TdsEnums.TRANS_REPEATABLE_READ);
- sqlBatch.Append(";");
- break;
- case System.Data.IsolationLevel.Serializable:
- sqlBatch.Append(TdsEnums.TRANS_SERIALIZABLE);
- sqlBatch.Append(";");
- break;
- case System.Data.IsolationLevel.Snapshot:
- throw SQL.SnapshotNotSupported(System.Data.IsolationLevel.Snapshot);
-
- case System.Data.IsolationLevel.Chaos:
- throw SQL.NotSupportedIsolationLevel(iso);
-
- default:
- throw ADP.InvalidIsolationLevel(iso);
- }
-
- if (!ADP.IsEmpty(transactionName))
- {
- transactionName = " " + SqlConnection.FixupDatabaseTransactionName(transactionName);
- }
-
- switch (transactionRequest)
- {
- case TransactionRequest.Begin:
- sqlBatch.Append(TdsEnums.TRANS_BEGIN);
- sqlBatch.Append(transactionName);
- break;
- case TransactionRequest.Promote:
- Debug.Assert(false, "Promote called with transaction name or on pre-2005!");
- break;
- case TransactionRequest.Commit:
- sqlBatch.Append(TdsEnums.TRANS_COMMIT);
- sqlBatch.Append(transactionName);
- break;
- case TransactionRequest.Rollback:
- sqlBatch.Append(TdsEnums.TRANS_ROLLBACK);
- sqlBatch.Append(transactionName);
- break;
- case TransactionRequest.IfRollback:
- sqlBatch.Append(TdsEnums.TRANS_IF_ROLLBACK);
- sqlBatch.Append(transactionName);
- break;
- case TransactionRequest.Save:
- sqlBatch.Append(TdsEnums.TRANS_SAVE);
- sqlBatch.Append(transactionName);
- break;
- default:
- Debug.Fail("Unknown transaction type");
- break;
- }
-
- System.Threading.Tasks.Task executeTask = _parser.TdsExecuteSQLBatch(sqlBatch.ToString(), ConnectionOptions.ConnectTimeout, null, _parser._physicalStateObj, sync: true);
- Debug.Assert(executeTask == null, "Shouldn't get a task when doing sync writes");
- _parser.Run(RunBehavior.UntilDone, null, null, null, _parser._physicalStateObj);
-
- // Prior to 2005, we didn't have any transaction tokens to manage,
- // or any feedback to know when one was created, so we just presume
- // that successful execution of the request caused the transaction
- // to be created, and we set that on the parser.
- if (TransactionRequest.Begin == transactionRequest)
- {
- Debug.Assert(internalTransaction != null, "Begin Transaction request without internal transaction");
- _parser.CurrentTransaction = internalTransaction;
- }
+ ExecuteTransaction2005(transactionRequest, transactionName, iso, internalTransaction, isDelegateControlRequest);
}
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs
index b0ed5edee2..f45ec2415f 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs
@@ -269,8 +269,6 @@ internal EncryptionOptions EncryptionOptions
}
}
- internal bool Is2005OrNewer => true;
-
internal bool Is2008OrNewer
{
get
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs
index bd7e0ece1b..d8950280ed 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs
@@ -198,19 +198,6 @@ internal bool IsGlobalTransactionsEnabledForServer
private bool _isAzureSQLConnection = false; // If connected to Azure SQL
-#if NETFRAMEWORK
-
- abstract internal bool Is2000
- {
- get;
- }
-
-
- abstract internal bool Is2005OrNewer
- {
- get;
- }
-#endif
internal bool IsAzureSQLConnection
{
get
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs
index 18291aca27..31884f4b96 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs
@@ -231,21 +231,7 @@ internal void Commit()
// COMMIT ignores transaction names, and so there is no reason to pass it anything. COMMIT
// simply commits the transaction from the most recent BEGIN, nested or otherwise.
_innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Commit, null, IsolationLevel.Unspecified, null, false);
-#if NETFRAMEWORK
- // SQL BU DT 291159 - perform full Zombie on pre-2005, but do not actually
- // complete internal transaction until informed by server in the case of 2005
- // or later.
- if (!IsZombied && !_innerConnection.Is2005OrNewer)
- {
- // Since nested transactions are no longer allowed, set flag to false.
- // This transaction has been completed.
- Zombie();
- }
- else
-#endif
- {
- ZombieParent();
- }
+ ZombieParent();
}
catch (Exception e)
{
@@ -395,15 +381,6 @@ internal void Rollback(string transactionName)
try
{
_innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Rollback, transactionName, IsolationLevel.Unspecified, null, false);
-#if NETFRAMEWORK
- if (!IsZombied && !_innerConnection.Is2005OrNewer)
- {
- // Check if Zombied before making round-trip to server.
- // Against 2005 we receive an envchange on the ExecuteTransaction above on the
- // parser that calls back into SqlTransaction for the Zombie() call.
- CheckTransactionLevelAndZombie();
- }
-#endif
}
catch (Exception e)
{
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.Common.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.Common.cs
index e96f854e50..e099712fc2 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.Common.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.Common.cs
@@ -110,11 +110,7 @@ internal void Zombie()
// Of course, if the connection is already closed,
// then we're free to zombify...
SqlInternalConnection internalConnection = (_connection.InnerConnection as SqlInternalConnection);
- if (internalConnection != null
-#if NETFRAMEWORK
- && internalConnection.Is2005OrNewer
-#endif
- && !_isFromAPI)
+ if (internalConnection != null && !_isFromAPI)
{
SqlClientEventSource.Log.TryAdvancedTraceEvent("SqlTransaction.Zombie | ADV | Object Id {0} yukon deferred zombie", ObjectID);
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs
index aa4836a930..58460aface 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs
@@ -341,29 +341,22 @@ public enum ActiveDirectoryWorkflow : byte
0x72xx0002 -> 2005 RTM
*/
- // Pre 2000 SP1 versioning scheme:
- public const int SQL70OR2000_MAJOR = 0x07; // The high byte (b3) is not sufficient to distinguish
- public const int SQL70_INCREMENT = 0x00; // 7.0 and 2000
- public const int SQL2000_INCREMENT = 0x01; // So we need to look at the high-mid byte (b2) as well
- public const int DEFAULT_MINOR = 0x0000;
-
// Majors:
- public const int SQL2000SP1_MAJOR = 0x71; // For 2000 SP1 and later the versioning schema changed and
- public const int SQL2005_MAJOR = 0x72; // the high-byte is sufficient to distinguish later versions
+ // For 2000 SP1 and later the versioning schema changed and
+ // the high-byte is sufficient to distinguish later versions
+ public const int SQL2005_MAJOR = 0x72;
public const int SQL2008_MAJOR = 0x73;
public const int SQL2012_MAJOR = 0x74;
public const int TDS8_MAJOR = 0x08; // TDS8 version to be used at login7
public const string TDS8_Protocol = "tds/8.0"; //TDS8
// Increments:
- public const int SQL2000SP1_INCREMENT = 0x00;
public const int SQL2005_INCREMENT = 0x09;
public const int SQL2008_INCREMENT = 0x0b;
public const int SQL2012_INCREMENT = 0x00;
public const int TDS8_INCREMENT = 0x00;
// Minors:
- public const int SQL2000SP1_MINOR = 0x0001;
public const int SQL2005_RTM_MINOR = 0x0002;
public const int SQL2008_MINOR = 0x0003;
public const int SQL2012_MINOR = 0x0004;
@@ -548,22 +541,7 @@ public enum ActiveDirectoryWorkflow : byte
public const ushort RPC_PROCID_PREPEXECRPC = 14;
public const ushort RPC_PROCID_UNPREPARE = 15;
- // For Transactions
- public const string TRANS_BEGIN = "BEGIN TRANSACTION";
- public const string TRANS_COMMIT = "COMMIT TRANSACTION";
- public const string TRANS_ROLLBACK = "ROLLBACK TRANSACTION";
- public const string TRANS_IF_ROLLBACK = "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION";
- public const string TRANS_SAVE = "SAVE TRANSACTION";
-
- // For Transactions - isolation levels
- public const string TRANS_READ_COMMITTED = "SET TRANSACTION ISOLATION LEVEL READ COMMITTED";
- public const string TRANS_READ_UNCOMMITTED = "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED";
- public const string TRANS_REPEATABLE_READ = "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ";
- public const string TRANS_SERIALIZABLE = "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE";
- public const string TRANS_SNAPSHOT = "SET TRANSACTION ISOLATION LEVEL SNAPSHOT";
-
- // Batch RPC flags
- public const byte SQL2000_RPCBATCHFLAG = 0x80;
+ // Batch RPC flag
public const byte SQL2005_RPCBATCHFLAG = 0xFF;
// RPC flags
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs
index 6cd3900906..98fbb72188 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs
@@ -1116,7 +1116,6 @@ internal bool SetPacketSize(int size)
Debug.Assert(_inBuff == null
||
(
- _parser.Is2005OrNewer &&
_outBytesUsed == (_outputHeaderLen + BitConverter.ToInt32(_outBuff, _outputHeaderLen)) &&
_outputPacketNumber == 1)
||