@@ -235,10 +235,15 @@ func (mc *mysqlConn) readHandshakePacket() (data []byte, plugin string, err erro
235
235
if len (data ) > pos {
236
236
// character set [1 byte]
237
237
// status flags [2 bytes]
238
+ pos += 1 + 2
239
+
238
240
// capability flags (upper 2 bytes) [2 bytes]
241
+ mc .flags += clientFlag (binary .LittleEndian .Uint16 (data [pos :pos + 2 ])) << 16
242
+ pos += 2
243
+
239
244
// length of auth-plugin-data [1 byte]
240
245
// reserved (all [00]) [10 bytes]
241
- pos += 1 + 2 + 2 + 1 + 10
246
+ pos += + 1 + 10
242
247
243
248
// second part of the password cipher [mininum 13 bytes],
244
249
// where len=MAX(13, length of auth-plugin-data - 8)
@@ -286,6 +291,7 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string
286
291
clientLocalFiles |
287
292
clientPluginAuth |
288
293
clientMultiResults |
294
+ mc .flags & clientDeprecateEOF |
289
295
mc .flags & clientLongFlag
290
296
291
297
if mc .cfg .ClientFoundRows {
@@ -610,18 +616,19 @@ func readStatus(b []byte) statusFlag {
610
616
// Ok Packet
611
617
// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-OK_Packet
612
618
func (mc * mysqlConn ) handleOkPacket (data []byte ) error {
613
- var n , m int
614
-
615
- // 0x00 [1 byte]
616
-
619
+ // 0x00 or 0xFE [1 byte]
620
+ n := 1
621
+ var l int
617
622
// Affected rows [Length Coded Binary]
618
- mc .affectedRows , _ , n = readLengthEncodedInteger (data [1 :])
623
+ mc .affectedRows , _ , l = readLengthEncodedInteger (data [n :])
624
+ n += l
619
625
620
626
// Insert id [Length Coded Binary]
621
- mc .insertId , _ , m = readLengthEncodedInteger (data [1 + n :])
627
+ mc .insertId , _ , l = readLengthEncodedInteger (data [n :])
628
+ n += l
622
629
623
630
// server_status [2 bytes]
624
- mc .status = readStatus (data [1 + n + m : 1 + n + m + 2 ])
631
+ mc .status = readStatus (data [n : n + 2 ])
625
632
if mc .status & statusMoreResultsExists != 0 {
626
633
return nil
627
634
}
@@ -631,19 +638,24 @@ func (mc *mysqlConn) handleOkPacket(data []byte) error {
631
638
return nil
632
639
}
633
640
641
+ // isEOFPacket will return true if the data is either a EOF-Packet or OK-Packet
642
+ // acting as an EOF.
643
+ func isEOFPacket (data []byte ) bool {
644
+ return data [0 ] == iEOF && len (data ) < 9
645
+ }
646
+
634
647
// Read Packets as Field Packets until EOF-Packet or an Error appears
635
648
// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnDefinition41
636
649
func (mc * mysqlConn ) readColumns (count int ) ([]mysqlField , error ) {
637
650
columns := make ([]mysqlField , count )
638
651
639
- for i := 0 ; ; i ++ {
652
+ for i := 0 ; i < count ; i ++ {
640
653
data , err := mc .readPacket ()
641
654
if err != nil {
642
655
return nil , err
643
656
}
644
657
645
- // EOF Packet
646
- if data [0 ] == iEOF && (len (data ) == 5 || len (data ) == 1 ) {
658
+ if mc .flags & clientDeprecateEOF == 0 && isEOFPacket (data ) {
647
659
if i == count {
648
660
return columns , nil
649
661
}
@@ -729,9 +741,10 @@ func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
729
741
// defaultVal, _, err = bytesToLengthCodedBinary(data[pos:])
730
742
//}
731
743
}
744
+ return columns , nil
732
745
}
733
746
734
- // Read Packets as Field Packets until EOF-Packet or an Error appears
747
+ // Read Packets as Field Packets until EOF/OK -Packet or an Error appears
735
748
// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-ProtocolText::ResultsetRow
736
749
func (rows * textRows ) readRow (dest []driver.Value ) error {
737
750
mc := rows .mc
@@ -746,9 +759,15 @@ func (rows *textRows) readRow(dest []driver.Value) error {
746
759
}
747
760
748
761
// EOF Packet
749
- if data [0 ] == iEOF && len (data ) == 5 {
750
- // server_status [2 bytes]
751
- rows .mc .status = readStatus (data [3 :])
762
+ if isEOFPacket (data ) {
763
+ if mc .flags & clientDeprecateEOF == 0 {
764
+ // server_status [2 bytes]
765
+ rows .mc .status = readStatus (data [3 :])
766
+ } else {
767
+ if err := mc .handleOkPacket (data ); err != nil {
768
+ return err
769
+ }
770
+ }
752
771
rows .rs .done = true
753
772
if ! rows .HasNextResultSet () {
754
773
rows .mc = nil
@@ -808,18 +827,44 @@ func (mc *mysqlConn) readUntilEOF() error {
808
827
return err
809
828
}
810
829
811
- switch data [ 0 ] {
812
- case iERR :
830
+ switch {
831
+ case data [ 0 ] == iERR :
813
832
return mc .handleErrorPacket (data )
814
- case iEOF :
815
- if len ( data ) == 5 {
833
+ case isEOFPacket ( data ) :
834
+ if mc . flags & clientDeprecateEOF == 0 {
816
835
mc .status = readStatus (data [3 :])
836
+ } else {
837
+ return mc .handleOkPacket (data )
817
838
}
818
839
return nil
819
840
}
820
841
}
821
842
}
822
843
844
+ func (mc * mysqlConn ) readPackets (num int ) error {
845
+
846
+ // we need to read EOF as well
847
+ if mc .flags & clientDeprecateEOF == 0 {
848
+ num ++
849
+ }
850
+
851
+ for i := 0 ; i < num ; i ++ {
852
+ data , err := mc .readPacket ()
853
+ if err != nil {
854
+ return err
855
+ }
856
+
857
+ switch {
858
+ case data [0 ] == iERR :
859
+ return mc .handleErrorPacket (data )
860
+ case mc .flags & clientDeprecateEOF == 0 && isEOFPacket (data ):
861
+ mc .status = readStatus (data [3 :])
862
+ return nil
863
+ }
864
+ }
865
+ return nil
866
+ }
867
+
823
868
/******************************************************************************
824
869
* Prepared Statements *
825
870
******************************************************************************/
@@ -1178,15 +1223,21 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
1178
1223
1179
1224
// packet indicator [1 byte]
1180
1225
if data [0 ] != iOK {
1181
- // EOF Packet
1182
- if data [0 ] == iEOF && len (data ) == 5 {
1183
- rows .mc .status = readStatus (data [3 :])
1226
+ if isEOFPacket (data ) {
1227
+ if rows .mc .flags & clientDeprecateEOF == 0 {
1228
+ rows .mc .status = readStatus (data [3 :])
1229
+ } else {
1230
+ if err := rows .mc .handleOkPacket (data ); err != nil {
1231
+ return err
1232
+ }
1233
+ }
1184
1234
rows .rs .done = true
1185
1235
if ! rows .HasNextResultSet () {
1186
1236
rows .mc = nil
1187
1237
}
1188
1238
return io .EOF
1189
1239
}
1240
+
1190
1241
mc := rows .mc
1191
1242
rows .mc = nil
1192
1243
0 commit comments