diff --git a/cmd/dataxl/main_test.go b/cmd/dataxl/main_test.go index 7982dbf..54a7c55 100644 --- a/cmd/dataxl/main_test.go +++ b/cmd/dataxl/main_test.go @@ -138,12 +138,24 @@ func TestParseCellConservativeInference(t *testing.T) { } func TestSetPathDoesNotOverwriteConflictingShape(t *testing.T) { - record := map[string]any{} - setPath(record, "user", "Alice") - setPath(record, "user.name", "Bob") - if got := record["user"]; got != "Alice" { - t.Fatalf("user = %#v, want original scalar", got) - } + t.Run("parent scalar before child", func(t *testing.T) { + record := map[string]any{} + setPath(record, "user", "Alice") + setPath(record, "user.name", "Bob") + if got := record["user"]; got != "Alice" { + t.Fatalf("user = %#v, want original scalar", got) + } + }) + + t.Run("child before parent scalar", func(t *testing.T) { + record := map[string]any{} + setPath(record, "user.name", "Bob") + setPath(record, "user", "Alice") + want := map[string]any{"name": "Bob"} + if got := record["user"]; !reflect.DeepEqual(got, want) { + t.Fatalf("user = %#v, want original nested value %#v", got, want) + } + }) } func TestSetPathRestoresNestedArrays(t *testing.T) { diff --git a/cmd/dataxl/path.go b/cmd/dataxl/path.go index ee589f5..94dd700 100644 --- a/cmd/dataxl/path.go +++ b/cmd/dataxl/path.go @@ -93,7 +93,12 @@ func setPath(root map[string]any, path string, value any) { return } if last { - m[token.key] = value + // Preserve the value established by an earlier column. This also + // protects a nested map/slice when a later parent scalar conflicts + // with it (for example, user.name followed by user). + if _, exists := m[token.key]; !exists { + m[token.key] = value + } return } if _, exists := m[token.key]; !exists {