-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Add DataTable support to SqlBulkCopy. #16884
Conversation
@@ -471,8 +471,6 @@ internal TdsParserStateObject GetSession(object owner) | |||
else | |||
{ | |||
session = _physicalStateObj; | |||
// But for CoreCLR we are now relying on the owner to ensure that cancellation owner comes from one source | |||
session.Owner = owner; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line was causing assert failures in the bulk copy tests. Removing it doesn't cause any test failures, and it's not present in the .NET Framework version of TdsParser.
@saurabh500 Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you point me to the assert ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bulkcopy.Close(); | ||
} | ||
} | ||
catch (SqlException) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed these generic catches. I'll see if I can replace these with more specific asserts or message checking.
@@ -827,10 +857,24 @@ internal static Exception TransactionZombied(DbTransaction obj) | |||
internal const float FailoverTimeoutStep = 0.08F; // fraction of timeout to use for fast failover connections | |||
|
|||
// security issue, don't rely upon public static readonly values - AS/URT 109635 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: You may want to remove these internal bug numbers
{ | ||
Debug.Assert(false, "valid CommandType " + value.ToString()); | ||
} | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: could just be a Debug.Assert with the inverted condition rather than having Assert(false, ...) and using #if DEBUG.
I'm also a little confused by the condition being checked, as it differs from the condition being checked in ValidateCommandBehavior below; I'd have expected them to be identical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like InvalidCommandBehavior is only referenced by ValidateCommandBehavior, so I can just combine the two.
@@ -827,10 +857,24 @@ internal static Exception TransactionZombied(DbTransaction obj) | |||
internal const float FailoverTimeoutStep = 0.08F; // fraction of timeout to use for fast failover connections | |||
|
|||
// security issue, don't rely upon public static readonly values - AS/URT 109635 | |||
internal static readonly String StrEmpty = ""; // String.Empty | |||
internal static readonly string StrEmpty = ""; // String.Empty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed, rather than just using string.Empty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll replace references to this field in a separate PR
Debug.Assert(_SqlDataReaderRowSource != null, "Should not be reading row as an XmlReader if bulk copy source is not a SqlDataReader"); | ||
return new XmlDataFeed(_SqlDataReaderRowSource.GetXmlReader(sourceOrdinal)); | ||
default: | ||
Debug.Assert(false, string.Format("Current column is marked as being a DataFeed, but no DataFeed compatible method was provided. Method: {0}", _currentRowMetadata[destRowIndex].Method)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Debug.Assert(false, ...) can instead be Debug.Fail(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(same applies to other uses like this throughout)
if (null != mcd) | ||
{ | ||
Delegate[] d = mcd.GetInvocationList(); | ||
for (int i = 0; i < d.Length; i++) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: foreach (Delegate del in d)
} | ||
|
||
// Unified method to read a value from the current row | ||
// unified method to read a value from the current row |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Why lowercase?
} | ||
resultTask = source.Task; | ||
return resultTask; // nothing to do. user passed us an empty array. Return a completed Task. | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TaskCompletionSource<T>
allocation can be avoided and the above can be simplified as:
if (rows.Length == 0)
{
return cancellationToken.IsCancellationRequested ?
Task.FromCanceled(cancellationToken) :
Task.CompletedTask;
}
{ | ||
if (0 > value) | ||
{ | ||
throw ADP.ArgumentOutOfRange("UpdateBatchSize"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: nameof(UpdateBatchSize)
} | ||
|
||
// Unified method to read a value from the current row | ||
// unified method to read a value from the current row |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Capitalize unified.
@@ -1440,12 +1800,57 @@ public Task WriteToServerAsync(DbDataReader reader, CancellationToken cancellati | |||
return resultTask; | |||
} | |||
|
|||
public Task WriteToServerAsync(DataTable table) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: => WriteToServerAsync(table, 0, CancellationToken.None);
return WriteToServerAsync(table, 0, CancellationToken.None); | ||
} | ||
|
||
public Task WriteToServerAsync(DataTable table, CancellationToken cancellationToken) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: => WriteToServerAsync(table, 0, cancellationToken);
return WriteToServerAsync(table, 0, cancellationToken); | ||
} | ||
|
||
public Task WriteToServerAsync(DataTable table, DataRowState rowState) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: => WriteToServerAsync(table, rowState, CancellationToken.None);
@@ -471,8 +471,6 @@ internal TdsParserStateObject GetSession(object owner) | |||
else | |||
{ | |||
session = _physicalStateObj; | |||
// But for CoreCLR we are now relying on the owner to ensure that cancellation owner comes from one source | |||
session.Owner = owner; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you point me to the assert ?
dstConn.Open(); | ||
if (dstConn.ServerVersion.StartsWith("07")) | ||
{ | ||
// test skipped on 7.0 server |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which is Version 7.0 of Sql Server? Can we get rid of the condition? If its anything before 2008 R2, I think this can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
7.0 is the version right before SQL 2000, so I'll get rid of this check.
|
||
namespace System.Data.SqlClient | ||
{ | ||
public sealed class SqlDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the SqlDataAdapter
here? Is this only being used in tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's used in the tests. I only included the APIs that are relevant to these changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think that SqlAdapter surface can be brought in completely so that the customers can use all the APIs?
You don't need to address this comment as part of this PR, but I think that you might as well drive this class to completion in case any APIs are left out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure
} | ||
} | ||
|
||
public void WriteToServer(IDataReader reader) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this in the contract. You should add this method in the ref assembly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
Test Failures with
Did you miss a file in the commit? |
|
||
IDataReader rowSourceAsIDataReader = (IDataReader)_rowSource; | ||
|
||
// Back-compat with 4.0 and 4.5 - only use IsDbNull when streaming is enabled and only for non-SqlDataReader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this comment still make sense?
@@ -212,8 +212,17 @@ public sealed partial class SqlBulkCopy : System.IDisposable | |||
public void Close() { } | |||
void System.IDisposable.Dispose() { } | |||
public void WriteToServer(System.Data.Common.DbDataReader reader) { } | |||
public void WriteToServer(System.Data.DataTable table) { } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These new APIs will need a version update to SqlClient ref assembly.
I am not sure how that mechanism is handled now. The versions used to reside in the csproj file.
@weshaggard What is the guidance here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @stephentoub In case you can help with the information here?
@saurabh500 That file is present in the commit: https://github.com/corivera/corefx/blob/f96dcc07b555d58e268063adbf76f2c1dbc4bd2b/src/System.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/CopySomeFromRowarray.cs I'll investigate the test failures. |
} | ||
resultTask = source.Task; | ||
return resultTask; // Nothing to do. user passed us an empty array. Return a completed Task. | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like my previous comment was missed... Any reason why the above couldn't be simplified as follows?
if (rows.Length == 0)
{
return cancellationToken.IsCancellationRequested ?
Task.FromCanceled(cancellationToken) :
Task.CompletedTask;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, missed this. I'll fix it.
@saurabh500 Test failures were due to some uncapitalized filenames. |
/// <summary> | ||
/// Column Encryption Setting to be used for the SqlCommand. | ||
/// </summary> | ||
public enum SqlCommandColumnEncryptionSetting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed since this wasn't actually being used anywhere. (originally introduced with an earlier commit in this PR)
@weshaggard @ericstj Do we need a version bump for SqlClient due to the contract changes here? We're adding in APIs already present in Framework SqlClient |
Given that this package will have a version that runs on .NET Framework (although just a facade) I do think we should bump the minor version of the assembly (and the package assuming that isn't already bumped). @ericstj is that your assessment as well? |
@weshaggard @ericstj Where is the version bump made for the libraries? The information used to be with the folder of the assemblies in the csproj files. But the version information doesn't exist there any more. |
@corivera I cant reply to my comments in the review above.
Is this assert still an issue? |
@saurabh500 No, removing this line resolves the failing Assert. This line isn't found in Framework, either. |
https://github.com/dotnet/corefx/blob/master/src/System.Data.SqlClient/dir.props#L5 change that to 4.2.0.0 |
@weshaggard where do we update the version for the nuget package? |
They were globally updated in master after the fork of our last release (https://github.com/dotnet/corefx/blob/master/Packaging.props#L23) so you don't need to update it. |
|
@danmosemsft Looking into it |
@corivera, As discussed I am OK with the removal of the LGTM otherwise. |
Work for adding remaining SqlDataAdapter APIs: https://github.com/dotnet/corefx/issues/17459 |
CC @saurabh500 @geleems