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) ||