Skip to content

Commit

Permalink
fix: write nulls to Nullable Enums
Browse files Browse the repository at this point in the history
  • Loading branch information
kshvakov committed Nov 7, 2017
1 parent 81a24df commit 95e4a6a
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 5 deletions.
2 changes: 1 addition & 1 deletion clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (ch *clickhouse) CheckNamedValue(nv *driver.NamedValue) error {
switch nv.Value.(type) {
case IP, *types.Array, UUID:
return nil
case []byte, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64, string, time.Time:
case nil, []byte, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64, string, time.Time:
return nil
}

Expand Down
74 changes: 74 additions & 0 deletions issues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,77 @@ func TestBytes(t *testing.T) {
_, err = tx.Exec(`INSERT INTO TestBytes (s) VALUES (?)`, []byte("foo"))
assert.NoError(t, err)
}

func TestNullableEnumWithoutLeadZero(t *testing.T) {
const (
ddl = `
CREATE TABLE test_nullable_enum_without_lead_zero (
value Nullable(Enum8('A' = 1, 'B' = 2)),
value2 Nullable(Enum16('A' = 1, 'B' = 2))
) Engine=Memory
`
dml = "INSERT INTO test_nullable_enum_without_lead_zero (value, value2) VALUES (?, ?)"
query = "SELECT value, value2 FROM test_nullable_enum_without_lead_zero"
)
var data = [][]interface{}{
{"A", nil},
{"A", "B"},
{nil, "B"},
}
if connect, err := sql.Open("clickhouse", "tcp://127.0.0.1:9000?debug=true"); assert.NoError(t, err) && assert.NoError(t, connect.Ping()) {
if _, err := connect.Exec("DROP TABLE IF EXISTS test_nullable_enum_without_lead_zero"); assert.NoError(t, err) {
if _, err := connect.Exec(ddl); assert.NoError(t, err) {
if tx, err := connect.Begin(); assert.NoError(t, err) {

if stmt, err := tx.Prepare(dml); assert.NoError(t, err) {
for _, v := range data {
if _, err = stmt.Exec(v...); !assert.NoError(t, err) {
return
}
}

}
if assert.NoError(t, tx.Commit()) {
var item struct {
Value *string
Value2 *string
}
if rows, err := connect.Query(query); assert.NoError(t, err) {
var i int
for rows.Next() {
err := rows.Scan(
&item.Value,
&item.Value2,
)
if !assert.NoError(t, err) {
return
}
switch v := item.Value; true {
case v != nil:
if !assert.Equal(t, data[i][0], *v) {
return
}
default:
if !assert.Equal(t, (*string)(nil), v) {
return
}
}
switch v := item.Value2; true {
case v != nil:
if !assert.Equal(t, data[i][1], *v) {
return
}
default:
if !assert.Equal(t, (*string)(nil), v) {
return
}
}
i++
}
}
}
}
}
}
}
}
12 changes: 8 additions & 4 deletions lib/column/enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ func (enum *Enum) Write(encoder *binary.Encoder, v interface{}) error {
}
}

func (enum *Enum) defaultValue() interface{} {
return enum.baseType
}

func parseEnum(name, chType string) (*Enum, error) {
var (
data string
Expand Down Expand Up @@ -114,12 +118,12 @@ func parseEnum(name, chType string) (*Enum, error) {
ident = ident[1 : len(ident)-1]
value interface{} = int16(value)
)
if isEnum16 {
enum.baseType = int16(0)
} else {
enum.baseType = int8(0)
if !isEnum16 {
value = int8(value.(int16))
}
if enum.baseType == nil {
enum.baseType = value
}
enum.iv[ident] = value
enum.vi[value] = ident
}
Expand Down
5 changes: 5 additions & 0 deletions lib/column/int8.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ func (i *Int8) Write(encoder *binary.Encoder, v interface{}) error {
return encoder.Int8(int8(v))
case int:
return encoder.Int8(int8(v))
case bool:
if v {
return encoder.Int8(int8(1))
}
return encoder.Int8(int8(0))
}
return &ErrUnexpectedType{
T: v,
Expand Down

0 comments on commit 95e4a6a

Please sign in to comment.