private void WriteMetaData(BulkCopySimpleResultSet internalResults) { this._stateObj.SetTimeoutSeconds(this.BulkCopyTimeout); _SqlMetaDataSet metaData = internalResults[1].MetaData; this._stateObj._outputMessageType = 7; this._parser.WriteBulkCopyMetaData(metaData, this._sortedColumnMappings.Count, this._stateObj); }
// Main parse loop for the top-level tds tokens, calls back into the I*Handler interfaces internal bool TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, out bool dataReady) { Debug.Assert((SniContext.Undefined != stateObj.SniContext) && // SniContext must not be Undefined ((stateObj._attentionSent) || ((SniContext.Snix_Execute != stateObj.SniContext) && (SniContext.Snix_SendRows != stateObj.SniContext))), // SniContext should not be Execute or SendRows unless attention was sent (and, therefore, we are looking for an ACK) String.Format("Unexpected SniContext on call to TryRun; SniContext={0}", stateObj.SniContext)); if (TdsParserState.Broken == State || TdsParserState.Closed == State) { dataReady = true; return true; // Just in case this is called in a loop, expecting data to be returned. } dataReady = false; do { // If there is data ready, but we didn't exit the loop, then something is wrong Debug.Assert(!dataReady, "dataReady not expected - did we forget to skip the row?"); if (stateObj._internalTimeout) { runBehavior = RunBehavior.Attention; } if (TdsParserState.Broken == State || TdsParserState.Closed == State) break; // jump out of the loop if the state is already broken or closed. if (!stateObj._accumulateInfoEvents && (stateObj._pendingInfoEvents != null)) { if (RunBehavior.Clean != (RunBehavior.Clean & runBehavior)) { SqlConnection connection = null; if (_connHandler != null) connection = _connHandler.Connection; // SqlInternalConnection holds the user connection object as a weak ref // We are omitting checks for error.Class in the code below (see processing of INFO) since we know (and assert) that error class // error.Class < TdsEnums.MIN_ERROR_CLASS for info message. // Also we know that TdsEnums.MIN_ERROR_CLASS<TdsEnums.MAX_USER_CORRECTABLE_ERROR_CLASS if ((connection != null) && connection.FireInfoMessageEventOnUserErrors) { foreach (SqlError error in stateObj._pendingInfoEvents) FireInfoMessageEvent(connection, stateObj, error); } else foreach (SqlError error in stateObj._pendingInfoEvents) stateObj.AddWarning(error); } stateObj._pendingInfoEvents = null; } byte token; if (!stateObj.TryReadByte(out token)) { return false; } if (!IsValidTdsToken(token)) { Debug.Assert(false, String.Format((IFormatProvider)null, "unexpected token; token = {0,-2:X2}", token)); _state = TdsParserState.Broken; _connHandler.BreakConnection(); throw SQL.ParsingError(); } int tokenLength; if (!TryGetTokenLength(token, stateObj, out tokenLength)) { return false; } switch (token) { case TdsEnums.SQLERROR: case TdsEnums.SQLINFO: { if (token == TdsEnums.SQLERROR) { stateObj._errorTokenReceived = true; // Keep track of the fact error token was received - for Done processing. } SqlError error; if (!TryProcessError(token, stateObj, out error)) { return false; } if (token == TdsEnums.SQLINFO && stateObj._accumulateInfoEvents) { Debug.Assert(error.Class < TdsEnums.MIN_ERROR_CLASS, "INFO with class > TdsEnums.MIN_ERROR_CLASS"); if (stateObj._pendingInfoEvents == null) stateObj._pendingInfoEvents = new List<SqlError>(); stateObj._pendingInfoEvents.Add(error); stateObj._syncOverAsync = true; break; } if (RunBehavior.Clean != (RunBehavior.Clean & runBehavior)) { // If FireInfoMessageEventOnUserErrors is true, we have to fire event without waiting. // Otherwise we can go ahead and add it to errors/warnings collection. SqlConnection connection = null; if (_connHandler != null) connection = _connHandler.Connection; // SqlInternalConnection holds the user connection object as a weak ref if ((connection != null) && (connection.FireInfoMessageEventOnUserErrors == true) && (error.Class <= TdsEnums.MAX_USER_CORRECTABLE_ERROR_CLASS)) { // Fire SqlInfoMessage here FireInfoMessageEvent(connection, stateObj, error); } else { // insert error/info into the appropriate exception - warning if info, exception if error if (error.Class < TdsEnums.MIN_ERROR_CLASS) { stateObj.AddWarning(error); } else if (error.Class < TdsEnums.FATAL_ERROR_CLASS) { // Continue results processing for all non-fatal errors (<20) stateObj.AddError(error); // Add it to collection - but do NOT change run behavior UNLESS // we are in an ExecuteReader call - at which time we will be throwing // anyways so we need to consume all errors. This is not the case // if we have already given out a reader. If we have already given out // a reader we need to throw the error but not halt further processing. We used to // halt processing. if (null != dataStream) { if (!dataStream.IsInitialized) { runBehavior = RunBehavior.UntilDone; } } } else { stateObj.AddError(error); // Else we have a fatal error and we need to change the behavior // since we want the complete error information in the exception. // Besides - no further results will be received. runBehavior = RunBehavior.UntilDone; } } } else if (error.Class >= TdsEnums.FATAL_ERROR_CLASS) { stateObj.AddError(error); } break; } case TdsEnums.SQLCOLINFO: { if (null != dataStream) { _SqlMetaDataSet metaDataSet; if (!TryProcessColInfo(dataStream.MetaData, dataStream, stateObj, out metaDataSet)) { return false; } if (!dataStream.TrySetMetaData(metaDataSet, false)) { return false; } dataStream.BrowseModeInfoConsumed = true; } else { // no dataStream if (!stateObj.TrySkipBytes(tokenLength)) { return false; } } break; } case TdsEnums.SQLDONE: case TdsEnums.SQLDONEPROC: case TdsEnums.SQLDONEINPROC: { // RunBehavior can be modified if (!TryProcessDone(cmdHandler, dataStream, ref runBehavior, stateObj)) { return false; } if ((token == TdsEnums.SQLDONEPROC) && (cmdHandler != null)) { cmdHandler.OnDoneProc(); } break; } case TdsEnums.SQLORDER: { // don't do anything with the order token so read off the pipe if (!stateObj.TrySkipBytes(tokenLength)) { return false; } break; } case TdsEnums.SQLALTMETADATA: { stateObj.CloneCleanupAltMetaDataSetArray(); if (stateObj._cleanupAltMetaDataSetArray == null) { // create object on demand (lazy creation) stateObj._cleanupAltMetaDataSetArray = new _SqlMetaDataSetCollection(); } _SqlMetaDataSet cleanupAltMetaDataSet; if (!TryProcessAltMetaData(tokenLength, stateObj, out cleanupAltMetaDataSet)) { return false; } stateObj._cleanupAltMetaDataSetArray.SetAltMetaData(cleanupAltMetaDataSet); if (null != dataStream) { byte metadataConsumedByte; if (!stateObj.TryPeekByte(out metadataConsumedByte)) { return false; } if (!dataStream.TrySetAltMetaDataSet(cleanupAltMetaDataSet, (TdsEnums.SQLALTMETADATA != metadataConsumedByte))) { return false; } } break; } case TdsEnums.SQLALTROW: { if (!stateObj.TryStartNewRow(isNullCompressed: false)) { // altrows are not currently null compressed return false; } // read will call run until dataReady. Must not read any data if returnimmetiately set if (RunBehavior.ReturnImmediately != (RunBehavior.ReturnImmediately & runBehavior)) { ushort altRowId; if (!stateObj.TryReadUInt16(out altRowId)) { // get altRowId return false; } if (!TrySkipRow(stateObj._cleanupAltMetaDataSetArray.GetAltMetaData(altRowId), stateObj)) { // skip altRow return false; } } else { dataReady = true; } break; } case TdsEnums.SQLENVCHANGE: { // ENVCHANGE must be processed synchronously (since it can modify the state of many objects) stateObj._syncOverAsync = true; SqlEnvChange[] env; if (!TryProcessEnvChange(tokenLength, stateObj, out env)) { return false; } for (int ii = 0; ii < env.Length; ii++) { if (env[ii] != null && !this.Connection.IgnoreEnvChange) { switch (env[ii].type) { case TdsEnums.ENV_BEGINTRAN: // When we get notification from the server of a new // transaction, we move any pending transaction over to // the current transaction, then we store the token in it. // if there isn't a pending transaction, then it's either // a TSQL transaction or a distributed transaction. Debug.Assert(null == _currentTransaction, "non-null current transaction with an ENV Change"); _currentTransaction = _pendingTransaction; _pendingTransaction = null; if (null != _currentTransaction) { _currentTransaction.TransactionId = env[ii].newLongValue; // this is defined as a ULongLong in the server and in the TDS Spec. } else { TransactionType transactionType = TransactionType.LocalFromTSQL; _currentTransaction = new SqlInternalTransaction(_connHandler, transactionType, null, env[ii].newLongValue); } if (null != _statistics && !_statisticsIsInTransaction) { _statistics.SafeIncrement(ref _statistics._transactions); } _statisticsIsInTransaction = true; break; case TdsEnums.ENV_COMMITTRAN: // SQLHOT 483 // Must clear the retain id if the server-side transaction ends by anything other // than rollback. goto case TdsEnums.ENV_ROLLBACKTRAN; case TdsEnums.ENV_ROLLBACKTRAN: // When we get notification of a completed transaction // we null out the current transaction. if (null != _currentTransaction) { #if DEBUG // Check null for case where Begin and Rollback obtained in the same message. if (SqlInternalTransaction.NullTransactionId != _currentTransaction.TransactionId) { Debug.Assert(_currentTransaction.TransactionId != env[ii].newLongValue, "transaction id's are not equal!"); } #endif if (TdsEnums.ENV_COMMITTRAN == env[ii].type) { _currentTransaction.Completed(TransactionState.Committed); } else if (TdsEnums.ENV_ROLLBACKTRAN == env[ii].type) { // Hold onto transaction id if distributed tran is rolled back. This must // be sent to the server on subsequent executions even though the transaction // is considered to be rolled back. _currentTransaction.Completed(TransactionState.Aborted); } else { _currentTransaction.Completed(TransactionState.Unknown); } _currentTransaction = null; } _statisticsIsInTransaction = false; break; case TdsEnums.ENV_ENLISTDTC: case TdsEnums.ENV_DEFECTDTC: case TdsEnums.ENV_TRANSACTIONENDED: Debug.Assert(false, "Should have thrown if DTC token encountered"); break; default: _connHandler.OnEnvChange(env[ii]); break; } } } break; } case TdsEnums.SQLLOGINACK: { SqlLoginAck ack; if (!TryProcessLoginAck(stateObj, out ack)) { return false; } _connHandler.OnLoginAck(ack); break; } case TdsEnums.SQLFEATUREEXTACK: { if (!TryProcessFeatureExtAck(stateObj)) { return false; } break; } case TdsEnums.SQLSESSIONSTATE: { if (!TryProcessSessionState(stateObj, tokenLength, _connHandler._currentSessionData)) { return false; } break; } case TdsEnums.SQLCOLMETADATA: { if (tokenLength != TdsEnums.VARNULL) { _SqlMetaDataSet metadata; if (!TryProcessMetaData(tokenLength, stateObj, out metadata)) { return false; } stateObj._cleanupMetaData = metadata; } else { if (cmdHandler != null) { stateObj._cleanupMetaData = cmdHandler.MetaData; } } if (null != dataStream) { byte peekedToken; if (!stateObj.TryPeekByte(out peekedToken)) { // temporarily cache next byte return false; } if (!dataStream.TrySetMetaData(stateObj._cleanupMetaData, (TdsEnums.SQLTABNAME == peekedToken || TdsEnums.SQLCOLINFO == peekedToken))) { return false; } } else if (null != bulkCopyHandler) { bulkCopyHandler.SetMetaData(stateObj._cleanupMetaData); } break; } case TdsEnums.SQLROW: case TdsEnums.SQLNBCROW: { Debug.Assert(stateObj._cleanupMetaData != null, "Reading a row, but the metadata is null"); if (token == TdsEnums.SQLNBCROW) { if (!stateObj.TryStartNewRow(isNullCompressed: true, nullBitmapColumnsCount: stateObj._cleanupMetaData.Length)) { return false; } } else { if (!stateObj.TryStartNewRow(isNullCompressed: false)) { return false; } } if (null != bulkCopyHandler) { if (!TryProcessRow(stateObj._cleanupMetaData, bulkCopyHandler.CreateRowBuffer(), bulkCopyHandler.CreateIndexMap(), stateObj)) { return false; } } else if (RunBehavior.ReturnImmediately != (RunBehavior.ReturnImmediately & runBehavior)) { if (!TrySkipRow(stateObj._cleanupMetaData, stateObj)) { // skip rows return false; } } else { dataReady = true; } if (_statistics != null) { _statistics.WaitForDoneAfterRow = true; } break; } case TdsEnums.SQLRETURNSTATUS: int status; if (!stateObj.TryReadInt32(out status)) { return false; } if (cmdHandler != null) { cmdHandler.OnReturnStatus(status); } break; case TdsEnums.SQLRETURNVALUE: { SqlReturnValue returnValue; if (!TryProcessReturnValue(tokenLength, stateObj, out returnValue)) { return false; } if (cmdHandler != null) { cmdHandler.OnReturnValue(returnValue); } break; } case TdsEnums.SQLSSPI: { // token length is length of SSPI data - call ProcessSSPI with it Debug.Assert(stateObj._syncOverAsync, "ProcessSSPI does not support retry, do not attempt asynchronously"); stateObj._syncOverAsync = true; ProcessSSPI(tokenLength); break; } case TdsEnums.SQLTABNAME: { { if (!stateObj.TrySkipBytes(tokenLength)) { return false; } } break; } default: Debug.Assert(false, "Unhandled token: " + token.ToString(CultureInfo.InvariantCulture)); break; } Debug.Assert(stateObj._pendingData || !dataReady, "dataReady is set, but there is no pending data"); } // Loop while data pending & runbehavior not return immediately, OR // if in attention case, loop while no more pending data & attention has not yet been // received. while ((stateObj._pendingData && (RunBehavior.ReturnImmediately != (RunBehavior.ReturnImmediately & runBehavior))) || (!stateObj._pendingData && stateObj._attentionSent && !stateObj._attentionReceived)); #if DEBUG if ((stateObj._pendingData) && (!dataReady)) { byte token; if (!stateObj.TryPeekByte(out token)) { return false; } Debug.Assert(IsValidTdsToken(token), string.Format("DataReady is false, but next token is not valid: {0,-2:X2}", token)); } #endif if (!stateObj._pendingData) { if (null != CurrentTransaction) { CurrentTransaction.Activate(); } } // if we recieved an attention (but this thread didn't send it) then // we throw an Operation Cancelled error if (stateObj._attentionReceived) { // Dev11 #344723: SqlClient stress hang System_Data!Tcp::ReadSync via a call to SqlDataReader::Close // Spin until SendAttention has cleared _attentionSending, this prevents a race condition between receiving the attention ACK and setting _attentionSent SpinWait.SpinUntil(() => !stateObj._attentionSending); Debug.Assert(stateObj._attentionSent, "Attention ACK has been received without attention sent"); if (stateObj._attentionSent) { // Reset attention state. stateObj._attentionSent = false; stateObj._attentionReceived = false; if (RunBehavior.Clean != (RunBehavior.Clean & runBehavior) && !stateObj._internalTimeout) { // Add attention error to collection - if not RunBehavior.Clean! stateObj.AddError(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, _server, SQLMessage.OperationCancelled(), "", 0)); } } } if (stateObj.HasErrorOrWarning) { ThrowExceptionAndWarning(stateObj); } return true; }
internal bool Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) { bool syncOverAsync = stateObj._syncOverAsync; try { stateObj._syncOverAsync = true; bool dataReady; bool result = TryRun(runBehavior, cmdHandler, dataStream, bulkCopyHandler, stateObj, out dataReady); Debug.Assert(result == true, "Should never return false when _syncOverAsync is set"); return dataReady; } finally { stateObj._syncOverAsync = syncOverAsync; } }
private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet internalResults) { bool hasLocalTransaction; this._sortedColumnMappings = new ArrayList(); StringBuilder query = new StringBuilder(); if (this._connection.IsShiloh && (internalResults[2].Count == 0)) { throw SQL.BulkLoadNoCollation(); } query.Append("insert bulk " + this.DestinationTableName + " ("); int num3 = 0; int num6 = 0; if (this._parser.IsYukonOrNewer) { hasLocalTransaction = this._connection.HasLocalTransaction; } else { hasLocalTransaction = 0 < ((SqlInt32) internalResults[0][0][0]); } if (((hasLocalTransaction && (this._externalTransaction == null)) && ((this._internalTransaction == null) && (this._connection.Parser != null))) && ((this._connection.Parser.CurrentTransaction != null) && this._connection.Parser.CurrentTransaction.IsLocal)) { throw SQL.BulkLoadExistingTransaction(); } for (int i = 0; i < internalResults[1].MetaData.Length; i++) { _SqlMetaData metadata = internalResults[1].MetaData[i]; bool flag2 = false; if ((metadata.type == SqlDbType.Timestamp) || (metadata.isIdentity && !this.IsCopyOption(SqlBulkCopyOptions.KeepIdentity))) { internalResults[1].MetaData[i] = null; flag2 = true; } int num = 0; while (num < this._localColumnMappings.Count) { if ((this._localColumnMappings[num]._destinationColumnOrdinal == metadata.ordinal) || (this.UnquotedName(this._localColumnMappings[num]._destinationColumnName) == metadata.column)) { if (flag2) { num6++; break; } this._sortedColumnMappings.Add(new _ColumnMapping(this._localColumnMappings[num]._internalSourceColumnOrdinal, metadata)); num3++; if (num3 > 1) { query.Append(", "); } if (metadata.type == SqlDbType.Variant) { this.AppendColumnNameAndTypeName(query, metadata.column, "sql_variant"); } else if (metadata.type == SqlDbType.Udt) { this.AppendColumnNameAndTypeName(query, metadata.column, "varbinary"); } else { this.AppendColumnNameAndTypeName(query, metadata.column, metadata.type.ToString()); } switch (metadata.metaType.NullableType) { case 0x29: case 0x2a: case 0x2b: query.Append("(" + metadata.scale.ToString((IFormatProvider) null) + ")"); break; case 0x6a: case 0x6c: query.Append("(" + metadata.precision.ToString((IFormatProvider) null) + "," + metadata.scale.ToString((IFormatProvider) null) + ")"); break; case 240: if (metadata.IsLargeUdt) { query.Append("(max)"); } else { query.Append("(" + metadata.length.ToString((IFormatProvider) null) + ")"); } break; default: if (!metadata.metaType.IsFixed && !metadata.metaType.IsLong) { int length = metadata.length; switch (metadata.metaType.NullableType) { case 0x63: case 0xe7: case 0xef: length /= 2; break; } query.Append("(" + length.ToString((IFormatProvider) null) + ")"); } else if (metadata.metaType.IsPlp && (metadata.metaType.SqlDbType != SqlDbType.Xml)) { query.Append("(max)"); } break; } if (!this._connection.IsShiloh) { break; } Result result = internalResults[2]; object obj2 = result[i][3]; if (obj2 == null) { break; } SqlString str = (SqlString) obj2; if (str.IsNull) { break; } query.Append(" COLLATE " + str.ToString()); if ((this._SqlDataReaderRowSource == null) || (metadata.collation == null)) { break; } int num9 = this._localColumnMappings[num]._internalSourceColumnOrdinal; int lCID = metadata.collation.LCID; int localeId = this._SqlDataReaderRowSource.GetLocaleId(num9); if (localeId == lCID) { break; } throw SQL.BulkLoadLcidMismatch(localeId, this._SqlDataReaderRowSource.GetName(num9), lCID, metadata.column); } num++; } if (num == this._localColumnMappings.Count) { internalResults[1].MetaData[i] = null; } } if ((num3 + num6) != this._localColumnMappings.Count) { throw SQL.BulkLoadNonMatchingColumnMapping(); } query.Append(")"); if ((this._copyOptions & (SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.KeepNulls | SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.CheckConstraints)) != SqlBulkCopyOptions.Default) { bool flag = false; query.Append(" with ("); if (this.IsCopyOption(SqlBulkCopyOptions.KeepNulls)) { query.Append("KEEP_NULLS"); flag = true; } if (this.IsCopyOption(SqlBulkCopyOptions.TableLock)) { query.Append((flag ? ", " : "") + "TABLOCK"); flag = true; } if (this.IsCopyOption(SqlBulkCopyOptions.CheckConstraints)) { query.Append((flag ? ", " : "") + "CHECK_CONSTRAINTS"); flag = true; } if (this.IsCopyOption(SqlBulkCopyOptions.FireTriggers)) { query.Append((flag ? ", " : "") + "FIRE_TRIGGERS"); flag = true; } query.Append(")"); } return query.ToString(); }
private void SubmitUpdateBulkCommand(BulkCopySimpleResultSet internalResults, string TDSCommand) { this._parser.TdsExecuteSQLBatch(TDSCommand, this.BulkCopyTimeout, null, this._stateObj); this._parser.Run(RunBehavior.UntilDone, null, null, null, this._stateObj); }
private BulkCopySimpleResultSet CreateAndExecuteInitialQuery() { string[] strArray; try { strArray = MultipartIdentifier.ParseMultipartIdentifier(this.DestinationTableName, "[\"", "]\"", "SQL_BulkCopyDestinationTableName", true); } catch (Exception exception) { throw SQL.BulkLoadInvalidDestinationTable(this.DestinationTableName, exception); } if (ADP.IsEmpty(strArray[3])) { throw SQL.BulkLoadInvalidDestinationTable(this.DestinationTableName, null); } BulkCopySimpleResultSet bulkCopyHandler = new BulkCopySimpleResultSet(); string str3 = "select @@trancount; SET FMTONLY ON select * from " + this.DestinationTableName + " SET FMTONLY OFF "; if (this._connection.IsShiloh) { string str5; if (this._connection.IsKatmaiOrNewer) { str5 = "sp_tablecollations_100"; } else if (this._connection.IsYukonOrNewer) { str5 = "sp_tablecollations_90"; } else { str5 = "sp_tablecollations"; } string str = strArray[3]; bool flag = (str.Length > 0) && ('#' == str[0]); if (!ADP.IsEmpty(str)) { str = SqlServerEscapeHelper.EscapeIdentifier(SqlServerEscapeHelper.EscapeStringAsLiteral(str)); } string str2 = strArray[2]; if (!ADP.IsEmpty(str2)) { str2 = SqlServerEscapeHelper.EscapeIdentifier(SqlServerEscapeHelper.EscapeStringAsLiteral(str2)); } string str4 = strArray[1]; if (flag && ADP.IsEmpty(str4)) { str3 = str3 + string.Format(null, "exec tempdb..{0} N'{1}.{2}'", new object[] { str5, str2, str }); } else { if (!ADP.IsEmpty(str4)) { str4 = SqlServerEscapeHelper.EscapeIdentifier(str4); } str3 = str3 + string.Format(null, "exec {0}..{1} N'{2}.{3}'", new object[] { str4, str5, str2, str }); } } Bid.Trace("<sc.SqlBulkCopy.CreateAndExecuteInitialQuery|INFO> Initial Query: '%ls' \n", str3); this._parser.TdsExecuteSQLBatch(str3, this.BulkCopyTimeout, null, this._stateObj); this._parser.Run(RunBehavior.UntilDone, null, null, bulkCopyHandler, this._stateObj); return bulkCopyHandler; }
internal bool RunReliably(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) { RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); RuntimeHelpers.PrepareConstrainedRegions(); try { tdsReliabilitySection.Start(); #endif //DEBUG return Run(runBehavior, cmdHandler, dataStream, bulkCopyHandler, stateObj); #if DEBUG } finally { tdsReliabilitySection.Stop(); } #endif //DEBUG } catch (OutOfMemoryException) { _connHandler.DoomThisConnection(); throw; } catch (StackOverflowException) { _connHandler.DoomThisConnection(); throw; } catch (ThreadAbortException) { _connHandler.DoomThisConnection(); throw; } }
internal bool Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) { if ((TdsParserState.Broken == this.State) || (this.State == TdsParserState.Closed)) { return true; } bool flag = false; Label_0016: if (stateObj._internalTimeout) { runBehavior = RunBehavior.Attention; } if ((TdsParserState.Broken == this.State) || (this.State == TdsParserState.Closed)) { goto Label_0705; } byte token = stateObj.ReadByte(); if ((((((token != 170) && (token != 0xab)) && ((token != 0xad) && (token != 0xe3))) && (((token != 0xac) && (token != 0x79)) && ((token != 160) && (token != 0xa1)))) && ((((token != 0x81) && (token != 0x88)) && ((token != 0xa4) && (token != 0xa5))) && (((token != 0xa9) && (token != 0xd3)) && ((token != 0xd1) && (token != 0xfd))))) && ((((token != 0xfe) && (token != 0xff)) && ((token != 0x39) && (token != 0xed))) && (((token != 0xae) && (token != 0x7c)) && ((token != 120) && (token != 0xed))))) { this._state = TdsParserState.Broken; this._connHandler.BreakConnection(); Bid.Trace("<sc.TdsParser.Run|ERR> Potential multi-threaded misuse of connection, unexpected TDS token found %d#\n", this.ObjectID); throw SQL.ParsingError(); } int tokenLength = this.GetTokenLength(token, stateObj); switch (token) { case 0xa4: if (dataStream == null) { this.SkipBytes(tokenLength, stateObj); } else { dataStream.TableNames = this.ProcessTableName(tokenLength, stateObj); } goto Label_06D5; case 0xa5: if (dataStream == null) { this.SkipBytes(tokenLength, stateObj); } else { _SqlMetaDataSet metaData = this.ProcessColInfo(dataStream.MetaData, dataStream, stateObj); dataStream.SetMetaData(metaData, false); dataStream.BrowseModeInfoConsumed = true; } goto Label_06D5; case 0xa9: this.SkipBytes(tokenLength, stateObj); goto Label_06D5; case 170: case 0xab: { if (token == 170) { stateObj._errorTokenReceived = true; } SqlError error = this.ProcessError(token, stateObj); if (RunBehavior.Clean == (RunBehavior.Clean & runBehavior)) { if (error.Class >= 20) { this.Errors.Add(error); } } else { SqlConnection connection = null; if (this._connHandler != null) { connection = this._connHandler.Connection; } if (((connection != null) && connection.FireInfoMessageEventOnUserErrors) && (error.Class <= 0x10)) { this.FireInfoMessageEvent(connection, stateObj, error); } else if (error.Class < 11) { this.Warnings.Add(error); } else if (error.Class < 20) { this.Errors.Add(error); if ((dataStream != null) && !dataStream.IsInitialized) { runBehavior = RunBehavior.UntilDone; } } else { this.Errors.Add(error); runBehavior = RunBehavior.UntilDone; } } goto Label_06D5; } case 0xac: { SqlReturnValue rec = this.ProcessReturnValue(tokenLength, stateObj); if (cmdHandler != null) { cmdHandler.OnReturnValue(rec); } goto Label_06D5; } case 0xad: { SqlLoginAck ack = this.ProcessLoginAck(stateObj); this._connHandler.OnLoginAck(ack); goto Label_06D5; } case 0x88: { if (stateObj._cleanupAltMetaDataSetArray == null) { stateObj._cleanupAltMetaDataSetArray = new _SqlMetaDataSetCollection(); } _SqlMetaDataSet altMetaDataSet = this.ProcessAltMetaData(tokenLength, stateObj); stateObj._cleanupAltMetaDataSetArray.SetAltMetaData(altMetaDataSet); if (dataStream != null) { dataStream.SetAltMetaDataSet(altMetaDataSet, 0x88 != stateObj.PeekByte()); } goto Label_06D5; } case 0x79: { int status = stateObj.ReadInt32(); if (cmdHandler != null) { cmdHandler.OnReturnStatus(status); } goto Label_06D5; } case 0x81: if (tokenLength != 0xffff) { stateObj._cleanupMetaData = this.ProcessMetaData(tokenLength, stateObj); } else if (cmdHandler != null) { stateObj._cleanupMetaData = cmdHandler.MetaData; } if (dataStream != null) { byte num5 = stateObj.PeekByte(); dataStream.SetMetaData(stateObj._cleanupMetaData, (0xa4 == num5) || (0xa5 == num5)); } else if (bulkCopyHandler != null) { bulkCopyHandler.SetMetaData(stateObj._cleanupMetaData); } goto Label_06D5; case 0xd1: if (bulkCopyHandler == null) { if (RunBehavior.ReturnImmediately != (RunBehavior.ReturnImmediately & runBehavior)) { this.SkipRow(stateObj._cleanupMetaData, stateObj); } break; } this.ProcessRow(stateObj._cleanupMetaData, bulkCopyHandler.CreateRowBuffer(), bulkCopyHandler.CreateIndexMap(), stateObj); break; case 0xd3: if (RunBehavior.ReturnImmediately != (RunBehavior.ReturnImmediately & runBehavior)) { int id = stateObj.ReadUInt16(); this.SkipRow(stateObj._cleanupAltMetaDataSetArray.GetAltMetaData(id), stateObj); } flag = true; goto Label_06D5; case 0xe3: { SqlEnvChange[] changeArray = this.ProcessEnvChange(tokenLength, stateObj); for (int i = 0; i < changeArray.Length; i++) { if ((changeArray[i] == null) || this.Connection.IgnoreEnvChange) { continue; } switch (changeArray[i].type) { case 8: case 11: this._currentTransaction = this._pendingTransaction; this._pendingTransaction = null; if (this._currentTransaction == null) { break; } this._currentTransaction.TransactionId = changeArray[i].newLongValue; goto Label_04B4; case 9: case 12: case 0x11: this._retainedTransactionId = 0L; goto Label_04F7; case 10: goto Label_04F7; default: goto Label_0577; } TransactionType type = (8 == changeArray[i].type) ? TransactionType.LocalFromTSQL : TransactionType.Distributed; this._currentTransaction = new SqlInternalTransaction(this._connHandler, type, null, changeArray[i].newLongValue); Label_04B4: if ((this._statistics != null) && !this._statisticsIsInTransaction) { this._statistics.SafeIncrement(ref this._statistics._transactions); } this._statisticsIsInTransaction = true; this._retainedTransactionId = 0L; continue; Label_04F7: if (this._currentTransaction != null) { if (9 == changeArray[i].type) { this._currentTransaction.Completed(TransactionState.Committed); } else if (10 == changeArray[i].type) { if (this._currentTransaction.IsDistributed && this._currentTransaction.IsActive) { this._retainedTransactionId = changeArray[i].oldLongValue; } this._currentTransaction.Completed(TransactionState.Aborted); } else { this._currentTransaction.Completed(TransactionState.Unknown); } this._currentTransaction = null; } this._statisticsIsInTransaction = false; continue; Label_0577: this._connHandler.OnEnvChange(changeArray[i]); } goto Label_06D5; } case 0xfd: case 0xfe: case 0xff: this.ProcessDone(cmdHandler, dataStream, ref runBehavior, stateObj); if ((token == 0xfe) && (cmdHandler != null)) { cmdHandler.OnDoneProc(); } goto Label_06D5; case 0xed: this.ProcessSSPI(tokenLength); goto Label_06D5; default: goto Label_06D5; } if (this._statistics != null) { this._statistics.WaitForDoneAfterRow = true; } flag = true; Label_06D5: if ((stateObj._pendingData && (RunBehavior.ReturnImmediately != (RunBehavior.ReturnImmediately & runBehavior))) || ((!stateObj._pendingData && stateObj._attentionSent) && !stateObj._attentionReceived)) { goto Label_0016; } Label_0705: if (!stateObj._pendingData && (this.CurrentTransaction != null)) { this.CurrentTransaction.Activate(); } if (stateObj._attentionSent && stateObj._attentionReceived) { stateObj._attentionSent = false; stateObj._attentionReceived = false; if ((RunBehavior.Clean != (RunBehavior.Clean & runBehavior)) && !stateObj._internalTimeout) { this.Errors.Add(new SqlError(0, 0, 11, this._server, SQLMessage.OperationCancelled(), "", 0)); } } if ((this._errors != null) || (this._warnings != null)) { this.ThrowExceptionAndWarning(); } return flag; }
private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet internalResults) { bool hasLocalTransaction; this._sortedColumnMappings = new ArrayList(); StringBuilder query = new StringBuilder(); if (this._connection.IsShiloh && (internalResults[2].Count == 0)) { throw SQL.BulkLoadNoCollation(); } query.Append("insert bulk " + this.DestinationTableName + " ("); int num3 = 0; int num6 = 0; if (this._parser.IsYukonOrNewer) { hasLocalTransaction = this._connection.HasLocalTransaction; } else { hasLocalTransaction = 0 < ((SqlInt32)internalResults[0][0][0]); } if (((hasLocalTransaction && (this._externalTransaction == null)) && ((this._internalTransaction == null) && (this._connection.Parser != null))) && ((this._connection.Parser.CurrentTransaction != null) && this._connection.Parser.CurrentTransaction.IsLocal)) { throw SQL.BulkLoadExistingTransaction(); } for (int i = 0; i < internalResults[1].MetaData.Length; i++) { _SqlMetaData metadata = internalResults[1].MetaData[i]; bool flag2 = false; if ((metadata.type == SqlDbType.Timestamp) || (metadata.isIdentity && !this.IsCopyOption(SqlBulkCopyOptions.KeepIdentity))) { internalResults[1].MetaData[i] = null; flag2 = true; } int num = 0; while (num < this._localColumnMappings.Count) { if ((this._localColumnMappings[num]._destinationColumnOrdinal == metadata.ordinal) || (this.UnquotedName(this._localColumnMappings[num]._destinationColumnName) == metadata.column)) { if (flag2) { num6++; break; } this._sortedColumnMappings.Add(new _ColumnMapping(this._localColumnMappings[num]._internalSourceColumnOrdinal, metadata)); num3++; if (num3 > 1) { query.Append(", "); } if (metadata.type == SqlDbType.Variant) { this.AppendColumnNameAndTypeName(query, metadata.column, "sql_variant"); } else if (metadata.type == SqlDbType.Udt) { this.AppendColumnNameAndTypeName(query, metadata.column, "varbinary"); } else { this.AppendColumnNameAndTypeName(query, metadata.column, metadata.type.ToString()); } switch (metadata.metaType.NullableType) { case 0x29: case 0x2a: case 0x2b: query.Append("(" + metadata.scale.ToString((IFormatProvider)null) + ")"); break; case 0x6a: case 0x6c: query.Append("(" + metadata.precision.ToString((IFormatProvider)null) + "," + metadata.scale.ToString((IFormatProvider)null) + ")"); break; case 240: if (metadata.IsLargeUdt) { query.Append("(max)"); } else { query.Append("(" + metadata.length.ToString((IFormatProvider)null) + ")"); } break; default: if (!metadata.metaType.IsFixed && !metadata.metaType.IsLong) { int length = metadata.length; switch (metadata.metaType.NullableType) { case 0x63: case 0xe7: case 0xef: length /= 2; break; } query.Append("(" + length.ToString((IFormatProvider)null) + ")"); } else if (metadata.metaType.IsPlp && (metadata.metaType.SqlDbType != SqlDbType.Xml)) { query.Append("(max)"); } break; } if (!this._connection.IsShiloh) { break; } Result result = internalResults[2]; object obj2 = result[i][3]; if (obj2 == null) { break; } SqlString str = (SqlString)obj2; if (str.IsNull) { break; } query.Append(" COLLATE " + str.ToString()); if ((this._SqlDataReaderRowSource == null) || (metadata.collation == null)) { break; } int num9 = this._localColumnMappings[num]._internalSourceColumnOrdinal; int lCID = metadata.collation.LCID; int localeId = this._SqlDataReaderRowSource.GetLocaleId(num9); if (localeId == lCID) { break; } throw SQL.BulkLoadLcidMismatch(localeId, this._SqlDataReaderRowSource.GetName(num9), lCID, metadata.column); } num++; } if (num == this._localColumnMappings.Count) { internalResults[1].MetaData[i] = null; } } if ((num3 + num6) != this._localColumnMappings.Count) { throw SQL.BulkLoadNonMatchingColumnMapping(); } query.Append(")"); if ((this._copyOptions & (SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.KeepNulls | SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.CheckConstraints)) != SqlBulkCopyOptions.Default) { bool flag = false; query.Append(" with ("); if (this.IsCopyOption(SqlBulkCopyOptions.KeepNulls)) { query.Append("KEEP_NULLS"); flag = true; } if (this.IsCopyOption(SqlBulkCopyOptions.TableLock)) { query.Append((flag ? ", " : "") + "TABLOCK"); flag = true; } if (this.IsCopyOption(SqlBulkCopyOptions.CheckConstraints)) { query.Append((flag ? ", " : "") + "CHECK_CONSTRAINTS"); flag = true; } if (this.IsCopyOption(SqlBulkCopyOptions.FireTriggers)) { query.Append((flag ? ", " : "") + "FIRE_TRIGGERS"); flag = true; } query.Append(")"); } return(query.ToString()); }
private BulkCopySimpleResultSet CreateAndExecuteInitialQuery() { string[] strArray; try { strArray = MultipartIdentifier.ParseMultipartIdentifier(this.DestinationTableName, "[\"", "]\"", "SQL_BulkCopyDestinationTableName", true); } catch (Exception exception) { throw SQL.BulkLoadInvalidDestinationTable(this.DestinationTableName, exception); } if (ADP.IsEmpty(strArray[3])) { throw SQL.BulkLoadInvalidDestinationTable(this.DestinationTableName, null); } BulkCopySimpleResultSet bulkCopyHandler = new BulkCopySimpleResultSet(); string str3 = "select @@trancount; SET FMTONLY ON select * from " + this.DestinationTableName + " SET FMTONLY OFF "; if (this._connection.IsShiloh) { string str5; if (this._connection.IsKatmaiOrNewer) { str5 = "sp_tablecollations_100"; } else if (this._connection.IsYukonOrNewer) { str5 = "sp_tablecollations_90"; } else { str5 = "sp_tablecollations"; } string str = strArray[3]; bool flag = (str.Length > 0) && ('#' == str[0]); if (!ADP.IsEmpty(str)) { str = SqlServerEscapeHelper.EscapeIdentifier(SqlServerEscapeHelper.EscapeStringAsLiteral(str)); } string str2 = strArray[2]; if (!ADP.IsEmpty(str2)) { str2 = SqlServerEscapeHelper.EscapeIdentifier(SqlServerEscapeHelper.EscapeStringAsLiteral(str2)); } string str4 = strArray[1]; if (flag && ADP.IsEmpty(str4)) { str3 = str3 + string.Format(null, "exec tempdb..{0} N'{1}.{2}'", new object[] { str5, str2, str }); } else { if (!ADP.IsEmpty(str4)) { str4 = SqlServerEscapeHelper.EscapeIdentifier(str4); } str3 = str3 + string.Format(null, "exec {0}..{1} N'{2}.{3}'", new object[] { str4, str5, str2, str }); } } Bid.Trace("<sc.SqlBulkCopy.CreateAndExecuteInitialQuery|INFO> Initial Query: '%ls' \n", str3); this._parser.TdsExecuteSQLBatch(str3, this.BulkCopyTimeout, null, this._stateObj); this._parser.Run(RunBehavior.UntilDone, null, null, bulkCopyHandler, this._stateObj); return(bulkCopyHandler); }