Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nil slices and empty slices are considered the same #366

Open
Elojah opened this issue Jul 1, 2019 · 4 comments
Open

Nil slices and empty slices are considered the same #366

Elojah opened this issue Jul 1, 2019 · 4 comments

Comments

@Elojah
Copy link

Elojah commented Jul 1, 2019

Probably related to: #147

I have a struct with:

type Foo struct {
  Bar []string
}

I need to differentiate bar == nil or bar == []string{}.

When insert + findOne with a nil bar:

            	            	expected: []string(nil)
            	            	actual  : []string{}

When adding omitempty tag previous test will be okay but test on insert + findOne with a []string{} bar:

            	            	expected: []string{}
            	            	actual  : []string(nil)

I have to add a layer above to handle those cases properly, it would be more convenient (and not breaking ?) to handle this directly in the driver.


What version of MongoDB are you using (mongod --version)?

db version v3.6.3
git version: 9586e557d54ef70f9ca4b43c26892cd55257e1a5
OpenSSL version: OpenSSL 1.1.1  11 Sep 2018
allocator: tcmalloc
modules: none
build environment:
    distarch: x86_64
    target_arch: x86_64

What version of Go are you using (go version)?

go version go1.12.2 linux/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN="/home/foo/go/bin"
GOCACHE="/home/foo/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/foo/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build942599151=/tmp/go-build -gno-record-gcc-switches"

What did you do?

db.Insert + db.Find on an embed slice.

Can you reproduce the issue on the latest development branch?

yes

@KidLinus
Copy link

Any update on this? This creates wierd behaviour and requires us to write cutsom marshal code for many structs.

@carb
Copy link

carb commented Nov 18, 2020

Possibly related, and a quick way to see the error:

package main

import (
	"testing"

	"github.com/globalsign/mgo/bson"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

type TestStruct struct {
	Inner []bool
}

func TestUnmarshal(t *testing.T) {
	a := TestStruct{}
	aBSON, err := bson.Marshal(a)
	require.NoError(t, err)

	b := TestStruct{}
	require.NoError(t, bson.Unmarshal(aBSON, &b))

	assert.Equal(t, a, b)
}

Will give the following test failure:

=== RUN   TestUnmarshal
    prog.go:23: 
        	Error Trace:	prog.go:23
        	Error:      	Not equal: 
        	            	expected: main.TestStruct{Inner:[]bool(nil)}
        	            	actual  : main.TestStruct{Inner:[]bool{}}
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -1,3 +1,4 @@
        	            	 (main.TestStruct) {
        	            	- Inner: ([]bool) <nil>
        	            	+ Inner: ([]bool) {
        	            	+ }
        	            	 }
        	Test:       	TestUnmarshal
--- FAIL: TestUnmarshal (0.00s)
FAIL

@carb
Copy link

carb commented Nov 19, 2020

Oh, this isn't even an accident. This is on purpose.

bson.SetRespectNilValues(true) will fix this behavior.

@carb
Copy link

carb commented Nov 19, 2020

Workaround:

Wrap the bson package in your own local bson package and add this chunk top-level. Alternatively, add it wherever you use the bson library.

func init() {
       bson.SetRespectNilValues(true)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants