Skip to content

Fix relationship record retrieval #249

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

Merged
merged 1 commit into from
Dec 26, 2017
Merged

Conversation

ligustah
Copy link
Contributor

If a custom filter condition is supplied to any of the With{Type} methods the foreign key condition is not actually added to the query. While this doesn't break the retrieval it does pull a lot of unnecessary data into memory.

For a type A that has a 1:N relationship to type B the queries look like these:

SELECT __a.id, __a.c_id FROM a __a LIMIT 1 OFFSET 0;

SELECT __b_Other.id, __b_Other.attribute, __b_Other.a_id FROM b __b_Other WHERE __b_Other.attribute = $1;  -- current
SELECT __b_Other.id, __b_Other.attribute, __b_Other.a_id FROM b __b_Other WHERE (__b_Other.attribute = $1 AND __b_Other.a_id IN ($2)); --fixed
type A struct {
	kallax.Model
	ID    int64 `pk:"autoincr"`
	Other []B
}

type B struct {
	kallax.Model
	ID        int64 `pk:"autoincr"`
	Attribute int64
}

If a custom filter condition is supplied to any of the With{Type} methods the foreign key condition is not actually added to the query. While this doesn't break the retrieval it does pull a lot of unnecessary data into memory.

For a type A that has a 1:N relationship to type B the queries look like these:
```sql
SELECT __a.id, __a.c_id FROM a __a LIMIT 1 OFFSET 0;

SELECT __b_Other.id, __b_Other.attribute, __b_Other.a_id FROM b __b_Other WHERE __b_Other.attribute = $1;  -- current
SELECT __b_Other.id, __b_Other.attribute, __b_Other.a_id FROM b __b_Other WHERE (__b_Other.attribute = $1 AND __b_Other.a_id IN ($2)); --fixed
```

```golang
type A struct {
	kallax.Model
	ID    int64 `pk:"autoincr"`
	Other []B
}

type B struct {
	kallax.Model
	ID        int64 `pk:"autoincr"`
	Attribute int64
}
```
@nadiamoe
Copy link
Contributor

Hello, thanks for the patch and PR. Could you post the go code which generates those queries? Just to make the issue clearer to me.

@ligustah
Copy link
Contributor Author

Sure thing:

package main

import (
	"database/sql"
	"log"

	kallax "gopkg.in/src-d/go-kallax.v1"
)

type A struct {
	kallax.Model
	ID    int64 `pk:"autoincr"`
	Other []B
	C     *C `fk:",inverse"`
}

type B struct {
	kallax.Model
	ID        int64 `pk:"autoincr"`
	Attribute int64
}

type C struct {
	kallax.Model
	ID       int64 `pk:"autoincr"`
	Property int64
}

func main() {
	db, err := sql.Open("postgres", "postgres://postgres:postgres@localhost/postgres?sslmode=disable")
	if err != nil {
		log.Fatal(err)
	}

	err = NewAStore(db).Transaction(func(aStore *AStore) error {
		var bStore BStore
		var cStore CStore
		kallax.StoreFrom(&bStore, aStore)
		kallax.StoreFrom(&cStore, aStore)

		c := &C{
			Property: 5,
		}

		err = cStore.Debug().Insert(c)
		if err != nil {
			return err
		}

		bs := []B{
			{Attribute: 0},
			{Attribute: 0},
			{Attribute: 1},
			{Attribute: 1},
			{Attribute: 2},
			{Attribute: 3},
		}

		return aStore.Debug().Insert(&A{
			Other: bs,
			C:     c,
		})
	})

	if err != nil {
		log.Fatal(err)
	}

	aStore := NewAStore(db).Debug()
	a, err := aStore.FindOne(
		NewAQuery().
			WithC().
			Where(kallax.Eq(Schema.C.Property, 5)),
	)
	if err != nil {
		log.Println(err)
	}

	log.Printf("%+v", a)

	a, err = aStore.FindOne(
		NewAQuery().
			WithOther(kallax.Eq(Schema.B.Attribute, 1)),
	)
	if err != nil {
		log.Println(err)
	}

	log.Printf("%+v", a)
}

That should be it. I used it to test this one as well as #250

@nadiamoe
Copy link
Contributor

Understood. Given the definition of And, it seems that someone slipped and forgot to reassign the result to the actual filter.

Looks good to me, thank you!

@nadiamoe nadiamoe merged commit 2a16129 into src-d:master Dec 26, 2017
@ligustah ligustah deleted the patch-1 branch January 27, 2018 14:02
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

Successfully merging this pull request may close these issues.

2 participants