Skip to content

Commit 9908c10

Browse files
committed
Implement clientDeprecateEOF flag. (not real performance improvement, but will permit further enhancement)
1 parent be6107b commit 9908c10

File tree

5 files changed

+89
-49
lines changed

5 files changed

+89
-49
lines changed

Diff for: AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Daniel Montoya <dsmontoyam at gmail.com>
3737
Daniel Nichter <nil at codenode.com>
3838
Daniël van Eeden <git at myname.nl>
3939
Dave Protasowski <dprotaso at gmail.com>
40+
Diego Dupin <diego.dupin at gmail.com>
4041
Dirkjan Bussink <d.bussink at gmail.com>
4142
DisposaBoy <disposaboy at dby.me>
4243
Egor Smolyakov <egorsmkv at gmail.com>

Diff for: connection.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -224,20 +224,20 @@ func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
224224
columnCount, err := stmt.readPrepareResultPacket()
225225
if err == nil {
226226
if stmt.paramCount > 0 {
227-
if err = mc.readUntilEOF(); err != nil {
227+
if err = mc.skipColumns(stmt.paramCount); err != nil {
228228
return nil, err
229229
}
230230
}
231231

232232
if columnCount > 0 {
233233
if mc.clientExtCapabilities&clientCacheMetadata != 0 {
234-
stmt.columns, err = mc.readColumns(int(columnCount))
235-
if err != nil {
234+
if stmt.columns, err = mc.readColumns(int(columnCount)); err != nil {
236235
return nil, err
237236
}
238237
} else {
239-
// skip column definition packets and intermediate EOF packet
240-
err = mc.readUntilEOF()
238+
if err = mc.skipColumns(int(columnCount)); err != nil {
239+
return nil, err
240+
}
241241
}
242242
}
243243
}
@@ -386,12 +386,12 @@ func (mc *mysqlConn) exec(query string) error {
386386

387387
if resLen > 0 {
388388
// columns
389-
if err := mc.readUntilEOF(); err != nil {
389+
if err := mc.skipColumns(resLen); err != nil {
390390
return err
391391
}
392392

393393
// rows
394-
if err := mc.readUntilEOF(); err != nil {
394+
if err := mc.skipResultSetRows(); err != nil {
395395
return err
396396
}
397397
}
@@ -470,14 +470,14 @@ func (mc *mysqlConn) getSystemVar(name string) ([]byte, error) {
470470

471471
if resLen > 0 {
472472
// Columns
473-
if err := mc.readUntilEOF(); err != nil {
473+
if err := mc.skipColumns(resLen); err != nil {
474474
return nil, err
475475
}
476476
}
477477

478478
dest := make([]driver.Value, resLen)
479479
if err = rows.readRow(dest); err == nil {
480-
return dest[0].([]byte), mc.readUntilEOF()
480+
return dest[0].([]byte), mc.skipResultSetRows()
481481
}
482482
}
483483
return nil, err

Diff for: packets.go

+73-31
Original file line numberDiff line numberDiff line change
@@ -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 {
709710
func (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

Diff for: rows.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func (rows *mysqlRows) Close() (err error) {
113113

114114
// Remove unread packets from stream
115115
if !rows.rs.done {
116-
err = mc.readUntilEOF()
116+
err = mc.skipResultSetRows()
117117
}
118118
if err == nil {
119119
handleOk := mc.clearResult()
@@ -143,7 +143,7 @@ func (rows *mysqlRows) nextResultSet() (int, error) {
143143

144144
// Remove unread packets from stream
145145
if !rows.rs.done {
146-
if err := rows.mc.readUntilEOF(); err != nil {
146+
if err := rows.mc.skipResultSetRows(); err != nil {
147147
return 0, err
148148
}
149149
rows.rs.done = true

Diff for: statement.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,12 @@ func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
7272

7373
if resLen > 0 {
7474
// Columns
75-
if err = mc.readUntilEOF(); err != nil {
75+
if err = mc.skipColumns(resLen); err != nil {
7676
return nil, err
7777
}
7878

7979
// Rows
80-
if err := mc.readUntilEOF(); err != nil {
80+
if err = mc.skipResultSetRows(); err != nil {
8181
return nil, err
8282
}
8383
}
@@ -118,15 +118,12 @@ func (stmt *mysqlStmt) query(args []driver.Value) (*binaryRows, error) {
118118
if resLen > 0 {
119119
rows.mc = mc
120120
if metadataFollows {
121-
rows.rs.columns, err = mc.readColumns(resLen)
122-
if err != nil {
121+
if rows.rs.columns, err = mc.readColumns(resLen); err != nil {
123122
return nil, err
124123
}
125124
stmt.columns = rows.rs.columns
126125
} else {
127-
// skip EOF Packet
128-
_, err := mc.readPacket()
129-
if err != nil {
126+
if err = mc.skipEof(); err != nil {
130127
return nil, err
131128
}
132129
rows.rs.columns = stmt.columns

0 commit comments

Comments
 (0)