@@ -281,7 +281,8 @@ func (mc *mysqlConn) initClientCapabilities(serverCapabilities capabilityFlag, c
281281 clientLocalFiles |
282282 clientPluginAuth |
283283 clientMultiResults |
284- clientConnectAttrs
284+ clientConnectAttrs |
285+ clientDeprecateEOF
285286
286287 if cfg .ClientFoundRows {
287288 clientCapabilities |= clientFoundRows
@@ -709,20 +710,12 @@ func (mc *okHandler) handleOkPacket(data []byte) error {
709710func (mc * mysqlConn ) readColumns (count int ) ([]mysqlField , error ) {
710711 columns := make ([]mysqlField , count )
711712
712- for i := 0 ; ; i ++ {
713+ for i := 0 ; i < count ; i ++ {
713714 data , err := mc .readPacket ()
714715 if err != nil {
715716 return nil , err
716717 }
717718
718- // EOF Packet
719- if data [0 ] == iEOF && (len (data ) == 5 || len (data ) == 1 ) {
720- if i == count {
721- return columns , nil
722- }
723- return nil , fmt .Errorf ("column count mismatch n:%d len:%d" , count , len (columns ))
724- }
725-
726719 // Catalog
727720 pos := int (data [0 ]) + 1
728721 // Database [len coded string]
@@ -780,13 +773,13 @@ func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
780773
781774 // Decimals [uint8]
782775 columns [i ].decimals = data [pos ]
783- //pos++
776+ }
784777
785- // Default value [len coded binary]
786- //if pos < len(data) {
787- // defaultVal, _, err = bytesToLengthCodedBinary(data[pos:])
788- //}
778+ // skip EOF packet if client does not support deprecateEOF
779+ if err := mc .skipEof (); err != nil {
780+ return nil , err
789781 }
782+ return columns , nil
790783}
791784
792785// Read Packets as Field Packets until EOF-Packet or an Error appears
@@ -804,9 +797,16 @@ func (rows *textRows) readRow(dest []driver.Value) error {
804797 }
805798
806799 // EOF Packet
807- if data [0 ] == iEOF && len (data ) == 5 {
808- // server_status [2 bytes]
809- rows .mc .status = readStatus (data [3 :])
800+ if data [0 ] == iEOF && len (data ) < 0xffffff {
801+ if mc .clientCapabilities & clientDeprecateEOF == 0 {
802+ // EOF packet
803+ mc .status = readStatus (data [3 :])
804+ } else {
805+ // Ok Packet with an 0xFE header
806+ _ , _ , n := readLengthEncodedInteger (data [1 :])
807+ _ , _ , m := readLengthEncodedInteger (data [1 + n :])
808+ mc .status = readStatus (data [1 + n + m :])
809+ }
810810 rows .rs .done = true
811811 if ! rows .HasNextResultSet () {
812812 rows .mc = nil
@@ -826,7 +826,7 @@ func (rows *textRows) readRow(dest []driver.Value) error {
826826 )
827827
828828 for i := range dest {
829- // Read bytes and convert to string
829+ // Read field bytes
830830 var buf []byte
831831 buf , isNull , n , err = readLengthEncodedBytes (data [pos :])
832832 pos += n
@@ -871,6 +871,7 @@ func (rows *textRows) readRow(dest []driver.Value) error {
871871
872872 default :
873873 dest [i ] = buf
874+ continue
874875 }
875876 if err != nil {
876877 return err
@@ -880,8 +881,33 @@ func (rows *textRows) readRow(dest []driver.Value) error {
880881 return nil
881882}
882883
883- // Reads Packets until EOF-Packet or an Error appears. Returns count of Packets read
884- func (mc * mysqlConn ) readUntilEOF () error {
884+ func (mc * mysqlConn ) skipPackets (number int ) error {
885+ for i := 0 ; i < number ; i ++ {
886+ if _ , err := mc .readPacket (); err != nil {
887+ return err
888+ }
889+ }
890+ return nil
891+ }
892+
893+ func (mc * mysqlConn ) skipEof () error {
894+ if mc .clientCapabilities & clientDeprecateEOF == 0 {
895+ if _ , err := mc .readPacket (); err != nil {
896+ return err
897+ }
898+ }
899+ return nil
900+ }
901+
902+ func (mc * mysqlConn ) skipColumns (resLen int ) error {
903+ if err := mc .skipPackets (resLen ); err != nil {
904+ return err
905+ }
906+ return mc .skipEof ()
907+ }
908+
909+ // Reads Packets until EOF-Packet or an Error appears.
910+ func (mc * mysqlConn ) skipResultSetRows () error {
885911 for {
886912 data , err := mc .readPacket ()
887913 if err != nil {
@@ -892,10 +918,18 @@ func (mc *mysqlConn) readUntilEOF() error {
892918 case iERR :
893919 return mc .handleErrorPacket (data )
894920 case iEOF :
895- if len (data ) == 5 {
896- mc .status = readStatus (data [3 :])
921+ if len (data ) < 0xffffff {
922+ if mc .clientCapabilities & clientDeprecateEOF == 0 {
923+ // EOF packet
924+ mc .status = readStatus (data [3 :])
925+ } else {
926+ // OK packet with an 0xFE header
927+ _ , _ , n := readLengthEncodedInteger (data [1 :])
928+ _ , _ , m := readLengthEncodedInteger (data [1 + n :])
929+ mc .status = readStatus (data [1 + n + m :])
930+ }
931+ return nil
897932 }
898- return nil
899933 }
900934 }
901935}
@@ -1192,11 +1226,11 @@ func (mc *okHandler) discardResults() error {
11921226 }
11931227 if resLen > 0 {
11941228 // columns
1195- if err := mc .conn ().readUntilEOF ( ); err != nil {
1229+ if err := mc .conn ().skipColumns ( resLen ); err != nil {
11961230 return err
11971231 }
11981232 // rows
1199- if err := mc .conn ().readUntilEOF (); err != nil {
1233+ if err := mc .conn ().skipResultSetRows (); err != nil {
12001234 return err
12011235 }
12021236 }
@@ -1213,19 +1247,27 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
12131247
12141248 // packet indicator [1 byte]
12151249 if data [0 ] != iOK {
1216- // EOF Packet
1217- if data [0 ] == iEOF && len (data ) == 5 {
1218- rows .mc .status = readStatus (data [3 :])
1250+ // EOF/OK Packet
1251+ if data [0 ] == iEOF {
1252+ if rows .mc .clientCapabilities & clientDeprecateEOF == 0 {
1253+ // EOF packet
1254+ rows .mc .status = readStatus (data [3 :])
1255+ } else {
1256+ // OK Packet with an 0xFE header
1257+ _ , _ , n := readLengthEncodedInteger (data [1 :])
1258+ _ , _ , m := readLengthEncodedInteger (data [1 + n :])
1259+ rows .mc .status = readStatus (data [1 + n + m :])
1260+ }
12191261 rows .rs .done = true
12201262 if ! rows .HasNextResultSet () {
12211263 rows .mc = nil
12221264 }
12231265 return io .EOF
12241266 }
1225- mc := rows .mc
1226- rows .mc = nil
12271267
12281268 // Error otherwise
1269+ mc := rows .mc
1270+ rows .mc = nil
12291271 return mc .handleErrorPacket (data )
12301272 }
12311273
0 commit comments