diff --git a/bool.go b/bool.go index 81c72472..14bc2d6e 100644 --- a/bool.go +++ b/bool.go @@ -50,10 +50,7 @@ func (b *Bool) AssignTo(dst interface{}) error { // if dst is a pointer to pointer, strip the pointer and try again case reflect.Ptr: if b.Status == Null { - if !el.IsNil() { - // if the destination pointer is not nil, nil it out - el.Set(reflect.Zero(el.Type())) - } + el.Set(reflect.Zero(el.Type())) return nil } if el.IsNil() { diff --git a/bool_test.go b/bool_test.go index 53df1747..74140b5e 100644 --- a/bool_test.go +++ b/bool_test.go @@ -1,11 +1,14 @@ package pgtype_test import ( + "reflect" "testing" "github.com/jackc/pgx/pgtype" ) +type _bool bool + func TestBoolTranscode(t *testing.T) { testSuccessfulTranscode(t, "bool", []interface{}{ pgtype.Bool{Bool: false, Status: pgtype.Present}, @@ -15,18 +18,19 @@ func TestBoolTranscode(t *testing.T) { } func TestBoolConvertFrom(t *testing.T) { - type _int8 int8 - successfulTests := []struct { source interface{} result pgtype.Bool }{ + {source: pgtype.Bool{Bool: false, Status: pgtype.Null}, result: pgtype.Bool{Bool: false, Status: pgtype.Null}}, {source: true, result: pgtype.Bool{Bool: true, Status: pgtype.Present}}, {source: false, result: pgtype.Bool{Bool: false, Status: pgtype.Present}}, {source: "true", result: pgtype.Bool{Bool: true, Status: pgtype.Present}}, {source: "false", result: pgtype.Bool{Bool: false, Status: pgtype.Present}}, {source: "t", result: pgtype.Bool{Bool: true, Status: pgtype.Present}}, {source: "f", result: pgtype.Bool{Bool: false, Status: pgtype.Present}}, + {source: _bool(true), result: pgtype.Bool{Bool: true, Status: pgtype.Present}}, + {source: _bool(false), result: pgtype.Bool{Bool: false, Status: pgtype.Present}}, } for i, tt := range successfulTests { @@ -41,3 +45,54 @@ func TestBoolConvertFrom(t *testing.T) { } } } + +func TestBoolAssignTo(t *testing.T) { + var b bool + var _b _bool + var pb *bool + var _pb *_bool + + simpleTests := []struct { + src pgtype.Bool + dst interface{} + expected interface{} + }{ + {src: pgtype.Bool{Bool: false, Status: pgtype.Present}, dst: &b, expected: false}, + {src: pgtype.Bool{Bool: true, Status: pgtype.Present}, dst: &b, expected: true}, + {src: pgtype.Bool{Bool: false, Status: pgtype.Present}, dst: &_b, expected: _bool(false)}, + {src: pgtype.Bool{Bool: true, Status: pgtype.Present}, dst: &_b, expected: _bool(true)}, + {src: pgtype.Bool{Bool: false, Status: pgtype.Null}, dst: &pb, expected: ((*bool)(nil))}, + {src: pgtype.Bool{Bool: false, Status: pgtype.Null}, dst: &_pb, expected: ((*_bool)(nil))}, + } + + for i, tt := range simpleTests { + err := tt.src.AssignTo(tt.dst) + if err != nil { + t.Errorf("%d: %v", i, err) + } + + if dst := reflect.ValueOf(tt.dst).Elem().Interface(); dst != tt.expected { + t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst) + } + } + + pointerAllocTests := []struct { + src pgtype.Bool + dst interface{} + expected interface{} + }{ + {src: pgtype.Bool{Bool: true, Status: pgtype.Present}, dst: &pb, expected: true}, + {src: pgtype.Bool{Bool: true, Status: pgtype.Present}, dst: &_pb, expected: _bool(true)}, + } + + for i, tt := range pointerAllocTests { + err := tt.src.AssignTo(tt.dst) + if err != nil { + t.Errorf("%d: %v", i, err) + } + + if dst := reflect.ValueOf(tt.dst).Elem().Elem().Interface(); dst != tt.expected { + t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst) + } + } +}