@@ -11,6 +11,7 @@ internal sealed class OkPayload
1111 public ulong LastInsertId { get ; }
1212 public ServerStatus ServerStatus { get ; }
1313 public int WarningCount { get ; }
14+ public string ? StatusInfo { get ; }
1415 public string ? NewSchema { get ; }
1516
1617 public const byte Signature = 0x00 ;
@@ -36,12 +37,13 @@ public static OkPayload Create(ReadOnlySpan<byte> span, bool deprecateEof, bool
3637 var serverStatus = ( ServerStatus ) reader . ReadUInt16 ( ) ;
3738 var warningCount = ( int ) reader . ReadUInt16 ( ) ;
3839 string ? newSchema = null ;
40+ ReadOnlySpan < byte > statusBytes ;
3941
4042 if ( clientSessionTrack )
4143 {
4244 if ( reader . BytesRemaining > 0 )
4345 {
44- reader . ReadLengthEncodedByteString ( ) ; // human-readable info
46+ statusBytes = reader . ReadLengthEncodedByteString ( ) ; // human-readable info
4547
4648 if ( ( serverStatus & ServerStatus . SessionStateChanged ) == ServerStatus . SessionStateChanged && reader . BytesRemaining > 0 )
4749 {
@@ -65,33 +67,46 @@ public static OkPayload Create(ReadOnlySpan<byte> span, bool deprecateEof, bool
6567 }
6668 }
6769 }
70+ else
71+ {
72+ statusBytes = default ;
73+ }
6874 }
6975 else
7076 {
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 ) ;
7284 }
7385
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 )
7589 {
7690 if ( serverStatus == ServerStatus . AutoCommit )
7791 return s_autoCommitOk ;
7892 if ( serverStatus == ( ServerStatus . AutoCommit | ServerStatus . SessionStateChanged ) )
7993 return s_autoCommitSessionStateChangedOk ;
8094 }
8195
82- return new OkPayload ( affectedRowCount , lastInsertId , serverStatus , warningCount , newSchema ) ;
96+ return new OkPayload ( affectedRowCount , lastInsertId , serverStatus , warningCount , statusInfo , newSchema ) ;
8397 }
8498
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 )
86100 {
87101 AffectedRowCount = affectedRowCount ;
88102 LastInsertId = lastInsertId ;
89103 ServerStatus = serverStatus ;
90104 WarningCount = warningCount ;
105+ StatusInfo = statusInfo ;
91106 NewSchema = newSchema ;
92107 }
93108
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 ) ;
96111 }
97112}
0 commit comments