Skip to content

Commit 481a2c4

Browse files
authored
Add continue request usage (#3605)
1 parent 37d8a3f commit 481a2c4

File tree

4 files changed

+65
-67
lines changed

4 files changed

+65
-67
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6571,25 +6571,10 @@ internal TdsOperationStatus TryReadSqlValue(SqlBuffer value,
65716571
case TdsEnums.SQLVARBINARY:
65726572
case TdsEnums.SQLIMAGE:
65736573
byte[] b = null;
6574-
6575-
// If varbinary(max), we only read the first chunk here, expecting the caller to read the rest
6576-
if (isPlp)
6577-
{
6578-
// If we are given -1 for length, then we read the entire value,
6579-
// otherwise only the requested amount, usually first chunk.
6580-
result = stateObj.TryReadPlpBytes(ref b, 0, length, out _);
6581-
if (result != TdsOperationStatus.Done)
6582-
{
6583-
return result;
6584-
}
6585-
}
6586-
else
6574+
result = stateObj.TryReadByteArrayWithContinue(length, isPlp, out b);
6575+
if (result != TdsOperationStatus.Done)
65876576
{
6588-
result = stateObj.TryReadByteArrayWithContinue(length, out b);
6589-
if (result != TdsOperationStatus.Done)
6590-
{
6591-
return result;
6592-
}
6577+
return result;
65936578
}
65946579

65956580
if (md.isEncrypted
@@ -6656,7 +6641,7 @@ internal TdsOperationStatus TryReadSqlValue(SqlBuffer value,
66566641
case TdsEnums.SQLVECTOR:
66576642
// Vector data is read as non-plp binary value.
66586643
// This is same as reading varbinary(8000).
6659-
result = stateObj.TryReadByteArrayWithContinue(length, out b);
6644+
result = stateObj.TryReadByteArrayWithContinue(length, isPlp: false, out b);
66606645
if (result != TdsOperationStatus.Done)
66616646
{
66626647
return result;
@@ -6987,7 +6972,7 @@ internal TdsOperationStatus TryReadSqlValueInternal(SqlBuffer value, byte tdsTyp
69876972
// Note: Better not come here with plp data!!
69886973
Debug.Assert(length <= TdsEnums.MAXSIZE);
69896974
byte[] b = new byte[length];
6990-
result = stateObj.TryReadByteArray(b, length);
6975+
result = stateObj.TryReadByteArrayWithContinue(length, isPlp: false, out b);
69916976
if (result != TdsOperationStatus.Done)
69926977
{
69936978
return result;

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

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6635,24 +6635,10 @@ internal TdsOperationStatus TryReadSqlValue(SqlBuffer value,
66356635
case TdsEnums.SQLIMAGE:
66366636
byte[] b = null;
66376637

6638-
// If varbinary(max), we only read the first chunk here, expecting the caller to read the rest
6639-
if (isPlp)
6640-
{
6641-
// If we are given -1 for length, then we read the entire value,
6642-
// otherwise only the requested amount, usually first chunk.
6643-
result = stateObj.TryReadPlpBytes(ref b, 0, length, out _);
6644-
if (result != TdsOperationStatus.Done)
6645-
{
6646-
return result;
6647-
}
6648-
}
6649-
else
6638+
result = stateObj.TryReadByteArrayWithContinue(length, isPlp, out b);
6639+
if (result != TdsOperationStatus.Done)
66506640
{
6651-
result = stateObj.TryReadByteArrayWithContinue(length, out b);
6652-
if (result != TdsOperationStatus.Done)
6653-
{
6654-
return result;
6655-
}
6641+
return result;
66566642
}
66576643

66586644
if (md.isEncrypted
@@ -6719,7 +6705,7 @@ internal TdsOperationStatus TryReadSqlValue(SqlBuffer value,
67196705
case TdsEnums.SQLVECTOR:
67206706
// Vector data is read as non-plp binary value.
67216707
// This is same as reading varbinary(8000).
6722-
result = stateObj.TryReadByteArrayWithContinue(length, out b);
6708+
result = stateObj.TryReadByteArrayWithContinue(length, isPlp: false, out b);
67236709
if (result != TdsOperationStatus.Done)
67246710
{
67256711
return result;

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCachedBuffer.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ internal static TdsOperationStatus TryCreate(SqlMetaDataPriv metadata, TdsParser
3939
{
4040
buffer = null;
4141

42+
stateObj.RequestContinue(true);
4243
(bool canContinue, bool isStarting, bool isContinuing) = stateObj.GetSnapshotStatuses();
4344

4445
List<byte[]> cachedBytes = null;
@@ -81,13 +82,17 @@ internal static TdsOperationStatus TryCreate(SqlMetaDataPriv metadata, TdsParser
8182
result = stateObj.TryReadPlpBytes(ref byteArr, 0, cb, out cb, canContinue, writeDataSizeToSnapshot: false, compatibilityMode: false);
8283
if (result != TdsOperationStatus.Done)
8384
{
84-
if (result == TdsOperationStatus.NeedMoreData && canContinue && cb == byteArr.Length && (isContinuing || !isStarting))
85+
if (result == TdsOperationStatus.NeedMoreData && canContinue && cb == byteArr.Length)
8586
{
8687
// succeeded in getting the data but failed to find the next plp length
8788
returnAfterAdd = true;
8889
}
8990
else
9091
{
92+
if (canContinue)
93+
{
94+
stateObj.SetSnapshotStorage(cachedBytes);
95+
}
9196
return result;
9297
}
9398
}

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,45 +1568,67 @@ public TdsOperationStatus TryReadByteArray(Span<byte> buff, int len, out int tot
15681568
return TdsOperationStatus.Done;
15691569
}
15701570

1571-
public TdsOperationStatus TryReadByteArrayWithContinue(int length, out byte[] bytes)
1571+
internal TdsOperationStatus TryReadByteArrayWithContinue(int length, bool isPlp, out byte[] value)
15721572
{
1573-
bytes = null;
1574-
int offset = 0;
1575-
byte[] temp = null;
1576-
(bool canContinue, bool isStarting, bool isContinuing) = GetSnapshotStatuses();
1577-
if (canContinue)
1573+
Debug.Assert(_syncOverAsync || !_asyncReadWithoutSnapshot, "This method is not safe to call when doing sync over async");
1574+
1575+
byte[] buf = null;
1576+
RequestContinue(true);
1577+
(bool canContinue, bool _, bool isContinuing) = GetSnapshotStatuses();
1578+
1579+
if (isPlp)
15781580
{
1579-
temp = TryTakeSnapshotStorage() as byte[];
1580-
Debug.Assert(temp != null || !isContinuing, "if continuing stored buffer must be present to contain previous data to continue from");
1581-
Debug.Assert(bytes == null || bytes.Length == length, "stored buffer length must be null or must have been created with the correct length");
1582-
1583-
if (temp != null)
1581+
bool compatibilityMode = LocalAppContextSwitches.UseCompatibilityAsyncBehaviour;
1582+
TdsOperationStatus result = TryReadPlpBytes(ref buf, 0, int.MaxValue, out length, canContinue && !compatibilityMode, canContinue && !compatibilityMode, compatibilityMode);
1583+
if (result != TdsOperationStatus.Done)
15841584
{
1585-
offset = GetSnapshotTotalSize();
1585+
value = null;
1586+
return result;
15861587
}
1588+
1589+
AssertValidState();
15871590
}
1591+
else
1592+
{
1593+
int startOffset = 0;
1594+
if (canContinue)
1595+
{
1596+
buf = TryTakeSnapshotStorage() as byte[];
1597+
Debug.Assert(buf != null || !isContinuing, "if continuing stored buffer must be present to contain previous data to continue from");
1598+
Debug.Assert(buf == null || buf.Length == length, "stored buffer length must be null or must have been created with the correct length");
15881599

1600+
if (buf != null)
1601+
{
1602+
startOffset = GetSnapshotTotalSize();
1603+
}
1604+
}
15891605

1590-
if (temp == null)
1591-
{
1592-
temp = new byte[length];
1593-
}
1606+
if (buf == null || buf.Length < length)
1607+
{
1608+
buf = new byte[length];
1609+
}
15941610

1595-
TdsOperationStatus result = TryReadByteArray(temp, length, out _, offset, isStarting || isContinuing);
1611+
TdsOperationStatus result = TryReadByteArray(buf, length, out _, startOffset, canContinue);
15961612

1597-
if (result == TdsOperationStatus.Done)
1598-
{
1599-
bytes = temp;
1600-
}
1601-
else if (result == TdsOperationStatus.NeedMoreData)
1602-
{
1603-
if (canContinue)
1613+
if (result != TdsOperationStatus.Done)
16041614
{
1605-
SetSnapshotStorage(temp);
1615+
if (result == TdsOperationStatus.NeedMoreData)
1616+
{
1617+
if (canContinue)
1618+
{
1619+
SetSnapshotStorage(buf);
1620+
}
1621+
}
1622+
value = null;
1623+
return result;
16061624
}
1625+
1626+
AssertValidState();
1627+
16071628
}
16081629

1609-
return result;
1630+
value = buf;
1631+
return TdsOperationStatus.Done;
16101632
}
16111633

16121634
// Takes no arguments and returns a byte from the buffer. If the buffer is empty, it is filled
@@ -1955,7 +1977,7 @@ internal TdsOperationStatus TryReadString(int length, out string value)
19551977

19561978
if (((_inBytesUsed + cBytes) > _inBytesRead) || (_inBytesPacket < cBytes))
19571979
{
1958-
TdsOperationStatus result = TryReadByteArrayWithContinue(cBytes, out buf);
1980+
TdsOperationStatus result = TryReadByteArrayWithContinue(cBytes, isPlp: false, out buf);
19591981
if (result != TdsOperationStatus.Done)
19601982
{
19611983
value = null;
@@ -2849,7 +2871,7 @@ internal TdsOperationStatus TryReadNetworkPacket()
28492871
}
28502872

28512873
// previous buffer is in snapshot
2852-
_inBuff = new byte[_inBuff.Length];
2874+
NewBuffer(_inBuff.Length);
28532875
result = TdsOperationStatus.NeedMoreData;
28542876
}
28552877

0 commit comments

Comments
 (0)