|
|
@@ -224,6 +224,7 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
|
|
|
clientTransactions |
|
|
|
clientLocalFiles |
|
|
|
clientPluginAuth |
|
|
|
+ clientMultiResults |
|
|
|
mc.flags&clientLongFlag
|
|
|
|
|
|
if mc.cfg.ClientFoundRows {
|
|
|
@@ -519,6 +520,10 @@ func (mc *mysqlConn) handleErrorPacket(data []byte) error {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func readStatus(b []byte) statusFlag {
|
|
|
+ return statusFlag(b[0]) | statusFlag(b[1])<<8
|
|
|
+}
|
|
|
+
|
|
|
// Ok Packet
|
|
|
// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-OK_Packet
|
|
|
func (mc *mysqlConn) handleOkPacket(data []byte) error {
|
|
|
@@ -533,7 +538,7 @@ func (mc *mysqlConn) handleOkPacket(data []byte) error {
|
|
|
mc.insertId, _, m = readLengthEncodedInteger(data[1+n:])
|
|
|
|
|
|
// server_status [2 bytes]
|
|
|
- mc.status = statusFlag(data[1+n+m]) | statusFlag(data[1+n+m+1])<<8
|
|
|
+ mc.status = readStatus(data[1+n+m : 1+n+m+2])
|
|
|
|
|
|
// warning count [2 bytes]
|
|
|
if !mc.strict {
|
|
|
@@ -652,6 +657,11 @@ func (rows *textRows) readRow(dest []driver.Value) error {
|
|
|
|
|
|
// EOF Packet
|
|
|
if data[0] == iEOF && len(data) == 5 {
|
|
|
+ // server_status [2 bytes]
|
|
|
+ rows.mc.status = readStatus(data[3:])
|
|
|
+ if err := rows.mc.discardMoreResultsIfExists(); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
rows.mc = nil
|
|
|
return io.EOF
|
|
|
}
|
|
|
@@ -709,6 +719,10 @@ func (mc *mysqlConn) readUntilEOF() error {
|
|
|
if err == nil && data[0] != iEOF {
|
|
|
continue
|
|
|
}
|
|
|
+ if err == nil && data[0] == iEOF && len(data) == 5 {
|
|
|
+ mc.status = readStatus(data[3:])
|
|
|
+ }
|
|
|
+
|
|
|
return err // Err or EOF
|
|
|
}
|
|
|
}
|
|
|
@@ -1013,6 +1027,28 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|
|
return mc.writePacket(data)
|
|
|
}
|
|
|
|
|
|
+func (mc *mysqlConn) discardMoreResultsIfExists() error {
|
|
|
+ for mc.status&statusMoreResultsExists != 0 {
|
|
|
+ resLen, err := mc.readResultSetHeaderPacket()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if resLen > 0 {
|
|
|
+ // columns
|
|
|
+ if err := mc.readUntilEOF(); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ // rows
|
|
|
+ if err := mc.readUntilEOF(); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ mc.status &^= statusMoreResultsExists
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
// http://dev.mysql.com/doc/internals/en/binary-protocol-resultset-row.html
|
|
|
func (rows *binaryRows) readRow(dest []driver.Value) error {
|
|
|
data, err := rows.mc.readPacket()
|
|
|
@@ -1022,11 +1058,16 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
|
|
|
|
|
// packet indicator [1 byte]
|
|
|
if data[0] != iOK {
|
|
|
- rows.mc = nil
|
|
|
// EOF Packet
|
|
|
if data[0] == iEOF && len(data) == 5 {
|
|
|
+ rows.mc.status = readStatus(data[3:])
|
|
|
+ if err := rows.mc.discardMoreResultsIfExists(); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ rows.mc = nil
|
|
|
return io.EOF
|
|
|
}
|
|
|
+ rows.mc = nil
|
|
|
|
|
|
// Error otherwise
|
|
|
return rows.mc.handleErrorPacket(data)
|