Validator: Unique tag doesn't work with pointer fields

Created on 13 Jun 2020  路  4Comments  路  Source: go-playground/validator

Package version eg. v8, v9:

v10

Issue, Question or Enhancement:

When using the unique tag with a pointer field, it compares the addresses of the pointers for uniqueness rather than the underlying values. I think this breaks the expectation of the tag, because structs often use pointer fields as an implementation detail to control marshaling, and the user would not want/expect this tag to fail to identify duplicates in those situations. We could either amend the unique tag (my preference, since I consider this to be a bug), or alternatively add something like a new uniqueValue tag to use for pointer fields.

Code sample, to showcase or reproduce:

type A struct {
    B []B `validate:"unique=Value"`
}

type B struct {
    Value *string
}

func main() {
    v := validator.New()
    value1 := "duplicate"
    value2 := "duplicate"
    a := A{B:[]B{{Value:&value1},{Value:&value2}}}
    if err := v.Struct(a); err != nil {
        fmt.Println(err, "(Correct)")
    } else {
        fmt.Println("No duplicates! (Incorrect)")
    }
}

Prints: No duplicates! (Incorrect)
Playground sample

bug enhancement

Most helpful comment

I agree this should be corrected.

It may take some time for me to look at it. Happy to accept a PR in the meantime.

All 4 comments

I agree this should be corrected.

It may take some time for me to look at it. Happy to accept a PR in the meantime.

There is an issue when using "Unique" on an array of structure pointers.
Is "Unique" tag not supported for a structure pointer?

With the below code (which is similar to the one by Jake above), I get an error:

type A struct {
        B []*B `validate:"unique=Value"`
}

type B struct {
        Value *string
}

func main() {
        v := validator.New()
        value1 := "duplicate"
        value2 := "duplicate"
        a := A{B:[]*B{{Value:&value1},{Value:&value2}}}
        if err := v.Struct(a); err != nil {
                fmt.Println(err, "(Correct)")
        } else {
                fmt.Println("No duplicates! (Incorrect)")
        }
}

Error:

panic: reflect: FieldByName of non-struct type *main.B

goroutine 1 [running]:
reflect.(*rtype).FieldByName(0x1151000, 0x114d883, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /usr/local/Cellar/go/1.14.3/libexec/src/reflect/type.go:933 +0x189
gopkg.in/go-playground/validator%2ev9.isUnique(0x11c6360, 0xc00011a900, 0x0)
    /Users/swsp/go/pkg/mod/gopkg.in/go-playground/[email protected]/baked_in.go:242 +0x438

Does #644 fix this issue?

It should yes

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dkostenko picture dkostenko  路  5Comments

alexyans picture alexyans  路  3Comments

jdgordon picture jdgordon  路  4Comments

muhammadkholidb picture muhammadkholidb  路  3Comments

romangithub1024 picture romangithub1024  路  5Comments