Skip to content

Commit c0f261d

Browse files
Port dotnet#603 changes
1 parent d5b7a5b commit c0f261d

File tree

1 file changed

+80
-68
lines changed

1 file changed

+80
-68
lines changed

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs

+80-68
Original file line numberDiff line numberDiff line change
@@ -2171,45 +2171,45 @@ internal bool TryGetBytesInternalSequential(int i, byte[] buffer, int index, int
21712171
{
21722172
tdsReliabilitySection.Start();
21732173
#endif //DEBUG
2174-
if ((_sharedState._columnDataBytesRemaining == 0) || (length == 0))
2175-
{
2176-
// No data left or nothing requested, return 0
2177-
bytesRead = 0;
2178-
return true;
2179-
}
2180-
else
2174+
if ((_sharedState._columnDataBytesRemaining == 0) || (length == 0))
2175+
{
2176+
// No data left or nothing requested, return 0
2177+
bytesRead = 0;
2178+
return true;
2179+
}
2180+
else
2181+
{
2182+
// if plp columns, do partial reads. Don't read the entire value in one shot.
2183+
if (_metaData[i].metaType.IsPlp)
21812184
{
2182-
// if plp columns, do partial reads. Don't read the entire value in one shot.
2183-
if (_metaData[i].metaType.IsPlp)
2185+
// Read in data
2186+
bool result = _stateObj.TryReadPlpBytes(ref buffer, index, length, out bytesRead);
2187+
_columnDataBytesRead += bytesRead;
2188+
if (!result)
21842189
{
2185-
// Read in data
2186-
bool result = _stateObj.TryReadPlpBytes(ref buffer, index, length, out bytesRead);
2187-
_columnDataBytesRead += bytesRead;
2188-
if (!result)
2189-
{
2190-
return false;
2191-
}
2192-
2193-
// Query for number of bytes left
2194-
ulong left;
2195-
if (!_parser.TryPlpBytesLeft(_stateObj, out left))
2196-
{
2197-
_sharedState._columnDataBytesRemaining = -1;
2198-
return false;
2199-
}
2200-
_sharedState._columnDataBytesRemaining = (long)left;
2201-
return true;
2190+
return false;
22022191
}
2203-
else
2192+
2193+
// Query for number of bytes left
2194+
ulong left;
2195+
if (!_parser.TryPlpBytesLeft(_stateObj, out left))
22042196
{
2205-
// Read data (not exceeding the total amount of data available)
2206-
int bytesToRead = (int)Math.Min((long)length, _sharedState._columnDataBytesRemaining);
2207-
bool result = _stateObj.TryReadByteArray(buffer, index, bytesToRead, out bytesRead);
2208-
_columnDataBytesRead += bytesRead;
2209-
_sharedState._columnDataBytesRemaining -= bytesRead;
2210-
return result;
2197+
_sharedState._columnDataBytesRemaining = -1;
2198+
return false;
22112199
}
2200+
_sharedState._columnDataBytesRemaining = (long)left;
2201+
return true;
22122202
}
2203+
else
2204+
{
2205+
// Read data (not exceeding the total amount of data available)
2206+
int bytesToRead = (int)Math.Min((long)length, _sharedState._columnDataBytesRemaining);
2207+
bool result = _stateObj.TryReadByteArray(buffer, index, bytesToRead, out bytesRead);
2208+
_columnDataBytesRead += bytesRead;
2209+
_sharedState._columnDataBytesRemaining -= bytesRead;
2210+
return result;
2211+
}
2212+
}
22132213
#if DEBUG
22142214
}
22152215
finally
@@ -4156,7 +4156,7 @@ private bool TryReadColumnHeader(int i)
41564156
{
41574157
tdsReliabilitySection.Start();
41584158
#endif //DEBUG
4159-
return TryReadColumnInternal(i, readHeaderOnly: true);
4159+
return TryReadColumnInternal(i, readHeaderOnly: true);
41604160
#if DEBUG
41614161
}
41624162
finally
@@ -5074,14 +5074,25 @@ private Task<int> GetBytesAsyncReadDataStage(GetBytesAsyncCallContext context, b
50745074
SetTimeout(_defaultTimeoutMilliseconds);
50755075

50765076
// Try to read without any continuations (all the data may already be in the stateObj's buffer)
5077-
if (!TryGetBytesInternalSequential(context.columnIndex, context.buffer, context.index, context.length, out bytesRead))
5077+
bool filledBuffer = context._reader.TryGetBytesInternalSequential(
5078+
context.columnIndex,
5079+
context.buffer,
5080+
context.index + context.totalBytesRead,
5081+
context.length - context.totalBytesRead,
5082+
out bytesRead
5083+
);
5084+
context.totalBytesRead += bytesRead;
5085+
Debug.Assert(context.totalBytesRead <= context.length, "Read more bytes than required");
5086+
5087+
if (!filledBuffer)
50785088
{
50795089
// This will be the 'state' for the callback
50805090
int totalBytesRead = bytesRead;
50815091

50825092
if (!isContinuation)
50835093
{
50845094
// This is the first async operation which is happening - setup the _currentTask and timeout
5095+
Debug.Assert(context._source == null, "context._source should not be non-null when trying to change to async");
50855096
source = new TaskCompletionSource<int>();
50865097
Task original = Interlocked.CompareExchange(ref _currentTask, source.Task, null);
50875098
if (original != null)
@@ -5090,6 +5101,7 @@ private Task<int> GetBytesAsyncReadDataStage(GetBytesAsyncCallContext context, b
50905101
return source.Task;
50915102
}
50925103

5104+
context._source = source;
50935105
// Check if cancellation due to close is requested (this needs to be done after setting _currentTask)
50945106
if (_cancelAsyncOnCloseToken.IsCancellationRequested)
50955107
{
@@ -5118,7 +5130,7 @@ private Task<int> GetBytesAsyncReadDataStage(GetBytesAsyncCallContext context, b
51185130
}
51195131
else
51205132
{
5121-
Debug.Assert(context._source != null, "context.source shuld not be null when continuing");
5133+
Debug.Assert(context._source != null, "context._source shuld not be null when continuing");
51225134
// setup for cleanup\completing
51235135
retryTask.ContinueWith(
51245136
continuationAction: AAsyncCallContext<int>.s_completeCallback,
@@ -5177,42 +5189,42 @@ public override Task<bool> ReadAsync(CancellationToken cancellationToken)
51775189
{
51785190
_stateObj._shouldHaveEnoughData = true;
51795191
#endif
5180-
if (_sharedState._dataReady)
5181-
{
5182-
// Clean off current row
5183-
CleanPartialReadReliable();
5184-
}
5192+
if (_sharedState._dataReady)
5193+
{
5194+
// Clean off current row
5195+
CleanPartialReadReliable();
5196+
}
51855197

5186-
// If there a ROW token ready (as well as any metadata for the row)
5187-
if (_stateObj.IsRowTokenReady())
5188-
{
5189-
// Read the ROW token
5190-
bool result = TryReadInternal(true, out more);
5191-
Debug.Assert(result, "Should not have run out of data");
5198+
// If there a ROW token ready (as well as any metadata for the row)
5199+
if (_stateObj.IsRowTokenReady())
5200+
{
5201+
// Read the ROW token
5202+
bool result = TryReadInternal(true, out more);
5203+
Debug.Assert(result, "Should not have run out of data");
51925204

5193-
rowTokenRead = true;
5194-
if (more)
5205+
rowTokenRead = true;
5206+
if (more)
5207+
{
5208+
// Sequential mode, nothing left to do
5209+
if (IsCommandBehavior(CommandBehavior.SequentialAccess))
51955210
{
5196-
// Sequential mode, nothing left to do
5197-
if (IsCommandBehavior(CommandBehavior.SequentialAccess))
5198-
{
5199-
return ADP.TrueTask;
5200-
}
5201-
// For non-sequential, check if we can read the row data now
5202-
else if (WillHaveEnoughData(_metaData.Length - 1))
5203-
{
5204-
// Read row data
5205-
result = TryReadColumn(_metaData.Length - 1, setTimeout: true);
5206-
Debug.Assert(result, "Should not have run out of data");
5207-
return ADP.TrueTask;
5208-
}
5211+
return ADP.TrueTask;
52095212
}
5210-
else
5213+
// For non-sequential, check if we can read the row data now
5214+
else if (WillHaveEnoughData(_metaData.Length - 1))
52115215
{
5212-
// No data left, return
5213-
return ADP.FalseTask;
5216+
// Read row data
5217+
result = TryReadColumn(_metaData.Length - 1, setTimeout: true);
5218+
Debug.Assert(result, "Should not have run out of data");
5219+
return ADP.TrueTask;
52145220
}
52155221
}
5222+
else
5223+
{
5224+
// No data left, return
5225+
return ADP.FalseTask;
5226+
}
5227+
}
52165228
#if DEBUG
52175229
}
52185230
finally
@@ -5373,8 +5385,8 @@ override public Task<bool> IsDBNullAsync(int i, CancellationToken cancellationTo
53735385
{
53745386
_stateObj._shouldHaveEnoughData = true;
53755387
#endif
5376-
ReadColumnHeader(i);
5377-
return _data[i].IsNull ? ADP.TrueTask : ADP.FalseTask;
5388+
ReadColumnHeader(i);
5389+
return _data[i].IsNull ? ADP.TrueTask : ADP.FalseTask;
53785390
#if DEBUG
53795391
}
53805392
finally
@@ -5510,7 +5522,7 @@ override public Task<T> GetFieldValueAsync<T>(int i, CancellationToken cancellat
55105522
{
55115523
_stateObj._shouldHaveEnoughData = true;
55125524
#endif
5513-
return Task.FromResult(GetFieldValueInternal<T>(i));
5525+
return Task.FromResult(GetFieldValueInternal<T>(i));
55145526
#if DEBUG
55155527
}
55165528
finally

0 commit comments

Comments
 (0)