Skip to content

Nested eager-loaded relations fail to populate on duplicate entity instances in many-to-many relationships #1465

@mguentner

Description

@mguentner

Problem

Given the following schema:

CREATE TABLE items (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE tags (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE item_tags (
    item_id TEXT NOT NULL,
    tag_id TEXT NOT NULL,
    PRIMARY KEY (item_id, tag_id),
    FOREIGN KEY (item_id) REFERENCES items(id),
    FOREIGN KEY (tag_id) REFERENCES tags(id)
);

CREATE TABLE lists (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE list_items (
    list_id TEXT NOT NULL,
    item_id TEXT NOT NULL,
    PRIMARY KEY (list_id, item_id),
    FOREIGN KEY (list_id) REFERENCES lists(id),
    FOREIGN KEY (item_id) REFERENCES items(id)
);

A tag can be part of many items.
An item can be part of many lists.

This allows us to construct the following example structure:

   	      tag1
	       |
	      item1
        /     \
	   list1 list2

However, when generating code with sqlboiler, the resulting function will only populate the first item with the respective tag in the first list.
The tags of the item in the second list will be empty.

Generated function

In items.go there is the following code:

	if singular {
		object.R.Tags = resultSlice
		for _, foreign := range resultSlice {
			if foreign.R == nil {
				foreign.R = &tagR{}
			}
			foreign.R.Items = append(foreign.R.Items, object)
		}
		return nil
	}

	for i, foreign := range resultSlice {
		localJoinCol := localJoinCols[i]
		for _, local := range slice {
			if local.ID == localJoinCol {
				local.R.Tags = append(local.R.Tags, foreign)
				if foreign.R == nil {
					foreign.R = &tagR{}
				}
				foreign.R.Items = append(foreign.R.Items, local)
                                // OFFENDING break
				break
			}
		}
	}

	return nil

When the offending break is removed, the bug is no longer present.

I have created a repository to reproduce the issue:
https://github.com/mguentner/sqlboiler_many_to_many_bug

Have a look at the test case https://github.com/mguentner/sqlboiler_many_to_many_bug/blob/master/main_test.go

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions