georgysavva / scany

Library for scanning data from a database into Go structs and more
MIT License
1.27k stars 67 forks source link

getColumnToFieldIndexMap mishandles index paths >= 3 deep #29

Closed PaulForgey closed 3 years ago

PaulForgey commented 3 years ago

The field path index build with

index := append(traversal.IndexPrefix, field.Index...)

Is not creating unique index path copies. It happens to be when the capacity of the slice is 1 or 2 and adding one more, but not once you get to 3, where the capacity doubles again to 4. This means append() will quit making copies at that point, and subsequently assigned fields at this level will all point to the last entry.

You can reproduce this by creating a struct like

type Level1 struct {
    Level2
}

type Level2 struct {
    Level3
}

type Level3 struct {
    Level4
}

type Level4 struct {
    One string
    Two string
    Three string
    Four string
}

The resulting map will have

"one": [0,0,0,3],
"two": [0,0,0,3],
// and so on
georgysavva commented 3 years ago

Thanks for discovering such a nasty bug!

May you be interested in contributing and fixing it? If not I will fix it myself in a few days.

PaulForgey commented 3 years ago

working on a PR right now and associated unit test for it.