@@ -11,6 +11,7 @@ internal sealed class OkPayload
11
11
public ulong LastInsertId { get ; }
12
12
public ServerStatus ServerStatus { get ; }
13
13
public int WarningCount { get ; }
14
+ public string ? StatusInfo { get ; }
14
15
public string ? NewSchema { get ; }
15
16
16
17
public const byte Signature = 0x00 ;
@@ -36,12 +37,13 @@ public static OkPayload Create(ReadOnlySpan<byte> span, bool deprecateEof, bool
36
37
var serverStatus = ( ServerStatus ) reader . ReadUInt16 ( ) ;
37
38
var warningCount = ( int ) reader . ReadUInt16 ( ) ;
38
39
string ? newSchema = null ;
40
+ ReadOnlySpan < byte > statusBytes ;
39
41
40
42
if ( clientSessionTrack )
41
43
{
42
44
if ( reader . BytesRemaining > 0 )
43
45
{
44
- reader . ReadLengthEncodedByteString ( ) ; // human-readable info
46
+ statusBytes = reader . ReadLengthEncodedByteString ( ) ; // human-readable info
45
47
46
48
if ( ( serverStatus & ServerStatus . SessionStateChanged ) == ServerStatus . SessionStateChanged && reader . BytesRemaining > 0 )
47
49
{
@@ -65,33 +67,46 @@ public static OkPayload Create(ReadOnlySpan<byte> span, bool deprecateEof, bool
65
67
}
66
68
}
67
69
}
70
+ else
71
+ {
72
+ statusBytes = default ;
73
+ }
68
74
}
69
75
else
70
76
{
71
- // ignore "string<EOF> info" human-readable string
77
+ // read EOF-terminated string
78
+ statusBytes = reader . ReadByteString ( reader . BytesRemaining ) ;
79
+
80
+ // try to detect if it was actually a length-prefixed string (up to 250 bytes); some servers send
81
+ // a length-prefixed status string even when CLIENT_SESSION_TRACK is not specified
82
+ if ( statusBytes . Length != 0 && statusBytes [ 0 ] == statusBytes . Length - 1 )
83
+ statusBytes = statusBytes . Slice ( 1 ) ;
72
84
}
73
85
74
- if ( affectedRowCount == 0 && lastInsertId == 0 && warningCount == 0 && newSchema is null )
86
+ var statusInfo = statusBytes . Length == 0 ? null : Encoding . UTF8 . GetString ( statusBytes ) ;
87
+
88
+ if ( affectedRowCount == 0 && lastInsertId == 0 && warningCount == 0 && statusInfo is null && newSchema is null )
75
89
{
76
90
if ( serverStatus == ServerStatus . AutoCommit )
77
91
return s_autoCommitOk ;
78
92
if ( serverStatus == ( ServerStatus . AutoCommit | ServerStatus . SessionStateChanged ) )
79
93
return s_autoCommitSessionStateChangedOk ;
80
94
}
81
95
82
- return new OkPayload ( affectedRowCount , lastInsertId , serverStatus , warningCount , newSchema ) ;
96
+ return new OkPayload ( affectedRowCount , lastInsertId , serverStatus , warningCount , statusInfo , newSchema ) ;
83
97
}
84
98
85
- private OkPayload ( int affectedRowCount , ulong lastInsertId , ServerStatus serverStatus , int warningCount , string ? newSchema )
99
+ private OkPayload ( int affectedRowCount , ulong lastInsertId , ServerStatus serverStatus , int warningCount , string ? statusInfo , string ? newSchema )
86
100
{
87
101
AffectedRowCount = affectedRowCount ;
88
102
LastInsertId = lastInsertId ;
89
103
ServerStatus = serverStatus ;
90
104
WarningCount = warningCount ;
105
+ StatusInfo = statusInfo ;
91
106
NewSchema = newSchema ;
92
107
}
93
108
94
- static readonly OkPayload s_autoCommitOk = new ( 0 , 0 , ServerStatus . AutoCommit , 0 , null ) ;
95
- static readonly OkPayload s_autoCommitSessionStateChangedOk = new ( 0 , 0 , ServerStatus . AutoCommit | ServerStatus . SessionStateChanged , 0 , null ) ;
109
+ static readonly OkPayload s_autoCommitOk = new ( 0 , 0 , ServerStatus . AutoCommit , 0 , null , null ) ;
110
+ static readonly OkPayload s_autoCommitSessionStateChangedOk = new ( 0 , 0 , ServerStatus . AutoCommit | ServerStatus . SessionStateChanged , 0 , null , null ) ;
96
111
}
97
112
}
0 commit comments