@@ -24,6 +24,7 @@ public async Task<ResultSet> ReadResultSetHeaderAsync(IOBehavior ioBehavior)
2424 LastInsertId = 0 ;
2525 RecordsAffected = 0 ;
2626 State = ResultSetState . None ;
27+ m_columnDefinitionPayloadUsedBytes = 0 ;
2728 m_dataLengths = null ;
2829 m_dataOffsets = null ;
2930 m_readBuffer . Clear ( ) ;
@@ -83,14 +84,25 @@ public async Task<ResultSet> ReadResultSetHeaderAsync(IOBehavior ioBehavior)
8384 if ( reader . BytesRemaining != 0 )
8485 throw new MySqlException ( "Unexpected data at end of column_count packet; see https://github.com/mysql-net/MySqlConnector/issues/324" ) ;
8586
87+ // reserve adequate space to hold a copy of all column definitions (but note that this can be resized below if we guess too small)
88+ Array . Resize ( ref m_columnDefinitionPayloads , columnCount * 96 ) ;
89+
8690 ColumnDefinitions = new ColumnDefinitionPayload [ columnCount ] ;
8791 m_dataOffsets = new int [ columnCount ] ;
8892 m_dataLengths = new int [ columnCount ] ;
8993
9094 for ( var column = 0 ; column < ColumnDefinitions . Length ; column ++ )
9195 {
9296 payload = await Session . ReceiveReplyAsync ( ioBehavior , CancellationToken . None ) . ConfigureAwait ( false ) ;
93- ColumnDefinitions [ column ] = ColumnDefinitionPayload . Create ( payload ) ;
97+ var arraySegment = payload . ArraySegment ;
98+
99+ // 'Session.ReceiveReplyAsync' reuses a shared buffer; make a copy so that the column definitions can always be safely read at any future point
100+ if ( m_columnDefinitionPayloadUsedBytes + arraySegment . Count > m_columnDefinitionPayloads . Length )
101+ Array . Resize ( ref m_columnDefinitionPayloads , Math . Max ( m_columnDefinitionPayloadUsedBytes + arraySegment . Count , m_columnDefinitionPayloadUsedBytes * 2 ) ) ;
102+ Buffer . BlockCopy ( arraySegment . Array , arraySegment . Offset , m_columnDefinitionPayloads , m_columnDefinitionPayloadUsedBytes , arraySegment . Count ) ;
103+
104+ ColumnDefinitions [ column ] = ColumnDefinitionPayload . Create ( new ArraySegment < byte > ( m_columnDefinitionPayloads , m_columnDefinitionPayloadUsedBytes , arraySegment . Count ) ) ;
105+ m_columnDefinitionPayloadUsedBytes += arraySegment . Count ;
94106 }
95107
96108 if ( ! Session . SupportsDeprecateEof )
@@ -421,6 +433,8 @@ public Row GetCurrentRow()
421433 public int RecordsAffected { get ; private set ; }
422434 public ResultSetState State { get ; private set ; }
423435
436+ byte [ ] m_columnDefinitionPayloads ;
437+ int m_columnDefinitionPayloadUsedBytes ;
424438 int [ ] m_dataLengths ;
425439 int [ ] m_dataOffsets ;
426440 readonly Queue < Row > m_readBuffer = new Queue < Row > ( ) ;
0 commit comments