Skip to content

Commit e94b728

Browse files
committed
Experimental nil-Values-Patch
1 parent 20de677 commit e94b728

File tree

4 files changed

+55
-32
lines changed

4 files changed

+55
-32
lines changed

connection.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,13 @@ func (mc *mysqlConn) getSystemVar(name string) (val string, e error) {
258258
return
259259
}
260260

261-
var rows []*[][]byte
261+
var rows []*[]*[]byte
262262
rows, e = mc.readRows(int(n))
263263
if e != nil {
264264
return
265265
}
266266

267-
val = string((*rows[0])[0])
267+
val = string(*(*rows[0])[0])
268268
}
269269

270270
return

packets.go

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ func (mc *mysqlConn) readColumns(n int) (columns []mysqlField, e error) {
484484
}
485485

486486
var pos, n int
487-
var name []byte
487+
var name *[]byte
488488
//var catalog, database, table, orgTable, name, orgName []byte
489489
//var defaultVal uint64
490490

@@ -563,14 +563,14 @@ func (mc *mysqlConn) readColumns(n int) (columns []mysqlField, e error) {
563563
// defaultVal, _, e = bytesToLengthCodedBinary(data[pos:])
564564
//}
565565

566-
columns = append(columns, mysqlField{name: string(name), fieldType: fieldType, flags: flags})
566+
columns = append(columns, mysqlField{name: string(*name), fieldType: fieldType, flags: flags})
567567
}
568568

569569
return
570570
}
571571

572572
// Read Packets as Field Packets until EOF-Packet or an Error appears
573-
func (mc *mysqlConn) readRows(columnsCount int) (rows []*[][]byte, e error) {
573+
func (mc *mysqlConn) readRows(columnsCount int) (rows []*[]*[]byte, e error) {
574574
var data []byte
575575
var i, pos, n int
576576
var isNull bool
@@ -587,7 +587,7 @@ func (mc *mysqlConn) readRows(columnsCount int) (rows []*[][]byte, e error) {
587587
}
588588

589589
// RowSet Packet
590-
row := make([][]byte, columnsCount)
590+
row := make([]*[]byte, columnsCount)
591591
pos = 0
592592
for i = 0; i < columnsCount; i++ {
593593
// Read bytes and convert to string
@@ -862,7 +862,7 @@ func (mc *mysqlConn) readBinaryRows(rc *rowsContent) (e error) {
862862
pos++
863863

864864
// BinaryRowSet Packet
865-
row := make([][]byte, columnsCount)
865+
row := make([]*[]byte, columnsCount)
866866

867867
nullBitMap = data[pos : pos+(columnsCount+7+2)/8]
868868
pos += (columnsCount + 7 + 2) / 8
@@ -883,47 +883,60 @@ func (mc *mysqlConn) readBinaryRows(rc *rowsContent) (e error) {
883883

884884
// Numeric Typs
885885
case FIELD_TYPE_TINY:
886+
var val []byte
886887
if unsigned {
887-
row[i] = uintToByteStr(uint64(byteToUint8(data[pos])))
888+
val = uintToByteStr(uint64(byteToUint8(data[pos])))
888889
} else {
889-
row[i] = intToByteStr(int64(int8(byteToUint8(data[pos]))))
890+
val = intToByteStr(int64(int8(byteToUint8(data[pos]))))
890891
}
892+
row[i] = &val
891893
pos++
892894

893895
case FIELD_TYPE_SHORT, FIELD_TYPE_YEAR:
896+
var val []byte
894897
if unsigned {
895-
row[i] = uintToByteStr(uint64(bytesToUint16(data[pos : pos+2])))
898+
val = uintToByteStr(uint64(bytesToUint16(data[pos : pos+2])))
896899
} else {
897-
row[i] = intToByteStr(int64(int16(bytesToUint16(data[pos : pos+2]))))
900+
val = intToByteStr(int64(int16(bytesToUint16(data[pos : pos+2]))))
898901
}
902+
row[i] = &val
899903
pos += 2
900904

901905
case FIELD_TYPE_INT24, FIELD_TYPE_LONG:
906+
var val []byte
902907
if unsigned {
903-
row[i] = uintToByteStr(uint64(bytesToUint32(data[pos : pos+4])))
908+
val = uintToByteStr(uint64(bytesToUint32(data[pos : pos+4])))
904909
} else {
905-
row[i] = intToByteStr(int64(int32(bytesToUint32(data[pos : pos+4]))))
910+
val = intToByteStr(int64(int32(bytesToUint32(data[pos : pos+4]))))
906911
}
912+
row[i] = &val
907913
pos += 4
908914

909915
case FIELD_TYPE_LONGLONG:
916+
var val []byte
910917
if unsigned {
911-
row[i] = uintToByteStr(bytesToUint64(data[pos : pos+8]))
918+
val = uintToByteStr(bytesToUint64(data[pos : pos+8]))
912919
} else {
913-
row[i] = intToByteStr(int64(bytesToUint64(data[pos : pos+8])))
920+
val = intToByteStr(int64(bytesToUint64(data[pos : pos+8])))
914921
}
922+
row[i] = &val
915923
pos += 8
916924

917925
case FIELD_TYPE_FLOAT:
918-
row[i] = float32ToByteStr(bytesToFloat32(data[pos : pos+4]))
926+
var val []byte
927+
val = float32ToByteStr(bytesToFloat32(data[pos : pos+4]))
928+
row[i] = &val
919929
pos += 4
920930

921931
case FIELD_TYPE_DOUBLE:
922-
row[i] = float64ToByteStr(bytesToFloat64(data[pos : pos+8]))
932+
var val []byte
933+
val = float64ToByteStr(bytesToFloat64(data[pos : pos+8]))
934+
row[i] = &val
923935
pos += 8
924936

925937
case FIELD_TYPE_DECIMAL, FIELD_TYPE_NEWDECIMAL:
926938
row[i], n, isNull, e = readLengthCodedBinary(data[pos:])
939+
927940
if e != nil {
928941
return
929942
}
@@ -957,14 +970,16 @@ func (mc *mysqlConn) readBinaryRows(rc *rowsContent) (e error) {
957970
}
958971
pos += n
959972

973+
var val []byte
960974
if num == 0 {
961-
row[i] = []byte("0000-00-00")
975+
val = []byte("0000-00-00")
962976
} else {
963-
row[i] = []byte(fmt.Sprintf("%04d-%02d-%02d",
977+
val = []byte(fmt.Sprintf("%04d-%02d-%02d",
964978
bytesToUint16(data[pos:pos+2]),
965979
data[pos+2],
966980
data[pos+3]))
967981
}
982+
row[i] = &val
968983
pos += int(num)
969984

970985
// Time HH:MM:SS
@@ -975,14 +990,16 @@ func (mc *mysqlConn) readBinaryRows(rc *rowsContent) (e error) {
975990
return
976991
}
977992

993+
var val []byte
978994
if num == 0 {
979-
row[i] = []byte("00:00:00")
995+
val = []byte("00:00:00")
980996
} else {
981-
row[i] = []byte(fmt.Sprintf("%02d:%02d:%02d",
997+
val = []byte(fmt.Sprintf("%02d:%02d:%02d",
982998
data[pos+6],
983999
data[pos+7],
9841000
data[pos+8]))
9851001
}
1002+
row[i] = &val
9861003
pos += n + int(num)
9871004

9881005
// Timestamp YYYY-MM-DD HH:MM:SS
@@ -994,26 +1011,28 @@ func (mc *mysqlConn) readBinaryRows(rc *rowsContent) (e error) {
9941011
}
9951012
pos += n
9961013

1014+
var val []byte
9971015
switch num {
9981016
case 0:
999-
row[i] = []byte("0000-00-00 00:00:00")
1017+
val = []byte("0000-00-00 00:00:00")
10001018
case 4:
1001-
row[i] = []byte(fmt.Sprintf("%04d-%02d-%02d 00:00:00",
1019+
val = []byte(fmt.Sprintf("%04d-%02d-%02d 00:00:00",
10021020
bytesToUint16(data[pos:pos+2]),
10031021
data[pos+2],
10041022
data[pos+3]))
10051023
default:
10061024
if num < 7 {
10071025
return fmt.Errorf("Invalid datetime-packet length %d", num)
10081026
}
1009-
row[i] = []byte(fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d",
1027+
val = []byte(fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d",
10101028
bytesToUint16(data[pos:pos+2]),
10111029
data[pos+2],
10121030
data[pos+3],
10131031
data[pos+4],
10141032
data[pos+5],
10151033
data[pos+6]))
10161034
}
1035+
row[i] = &val
10171036
pos += int(num)
10181037

10191038
// Please report if this happens!

rows.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type mysqlField struct {
2222

2323
type rowsContent struct {
2424
columns []mysqlField
25-
rows []*[][]byte
25+
rows []*[]*[]byte
2626
}
2727

2828
type mysqlRows struct {
@@ -49,7 +49,11 @@ func (rows mysqlRows) Close() error {
4949
func (rows mysqlRows) Next(dest []driver.Value) error {
5050
if len(rows.content.rows) > 0 {
5151
for i := 0; i < cap(dest); i++ {
52-
dest[i] = (*rows.content.rows[0])[i]
52+
if (*rows.content.rows[0])[i] == nil {
53+
dest[i] = nil
54+
} else {
55+
dest[i] = *(*rows.content.rows[0])[i]
56+
}
5357
}
5458
rows.content.rows = rows.content.rows[1:]
5559
} else {

utils.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,30 +132,30 @@ func readSlice(data []byte, delim byte) (slice []byte, e error) {
132132
return
133133
}
134134

135-
func readLengthCodedBinary(data []byte) (b []byte, n int, isNull bool, e error) {
135+
func readLengthCodedBinary(data []byte) (*[]byte, int, bool, error) {
136136
// Get length
137137
num, n, e := bytesToLengthCodedBinary(data)
138138
if e != nil {
139-
return
139+
return nil, n, true, e
140140
}
141141

142142
// Check data length
143143
if len(data) < n+int(num) {
144-
e = io.EOF
145-
return
144+
return nil, n, true, io.EOF
146145
}
147146

148147
// Check if null
148+
var isNull bool
149149
if data[0] == 251 {
150150
isNull = true
151151
} else {
152152
isNull = false
153153
}
154154

155155
// Get bytes
156-
b = data[n : n+int(num)]
156+
b := data[n : n+int(num)]
157157
n += int(num)
158-
return
158+
return &b, n, isNull, e
159159
}
160160

161161
func readAndDropLengthCodedBinary(data []byte) (n int, e error) {

0 commit comments

Comments
 (0)