dialect/sqlgraph: fix M2O relation in neighbors-with check

Summary: Pull Request resolved: https://github.com/facebookincubator/ent/pull/198

Reviewed By: alexsn

Differential Revision: D18707741

fbshipit-source-id: 69dd010e27ee07ffe44acc12003b9772220aaa2a
This commit is contained in:
Ariel Mashraki
2019-11-26 12:22:08 -08:00
committed by Facebook Github Bot
parent 56335d6e12
commit 413bbad8d8
2 changed files with 87 additions and 1 deletions

View File

@@ -202,7 +202,7 @@ func HasNeighborsWith(q *Selector, s *Step, pred func(*Selector)) {
matches := builder.Select(to.C(s.To.Column)).
From(to)
pred(matches)
q.Where(In(from.C(s.From.Column), matches))
q.Where(In(from.C(s.Edge.Columns[0]), matches))
case r == O2M || (r == O2O && !s.Edge.Inverse):
from := q.Table()
to := builder.Table(s.Edge.Table)

View File

@@ -443,6 +443,92 @@ func TestHasNeighborsWith(t *testing.T) {
wantQuery string
wantArgs []interface{}
}{
{
name: "O2O",
step: func() *Step {
step := &Step{}
step.From.Table = "users"
step.From.Column = "id"
step.To.Table = "cards"
step.To.Column = "id"
step.Edge.Rel = O2O
step.Edge.Table = "cards"
step.Edge.Columns = []string{"owner_id"}
return step
}(),
selector: Dialect("postgres").Select("*").From(Table("users")),
predicate: func(s *Selector) {
s.Where(EQ("expired", false))
},
wantQuery: `SELECT * FROM "users" WHERE "users"."id" IN (SELECT "cards"."owner_id" FROM "cards" WHERE "expired" = $1)`,
wantArgs: []interface{}{false},
},
{
name: "O2O/inverse",
step: func() *Step {
step := &Step{}
step.From.Table = "cards"
step.From.Column = "id"
step.To.Table = "users"
step.To.Column = "id"
step.Edge.Rel = O2O
step.Edge.Table = "cards"
step.Edge.Inverse = true
step.Edge.Columns = []string{"owner_id"}
return step
}(),
selector: Dialect("postgres").Select("*").From(Table("cards")),
predicate: func(s *Selector) {
s.Where(EQ("name", "a8m"))
},
wantQuery: `SELECT * FROM "cards" WHERE "cards"."owner_id" IN (SELECT "users"."id" FROM "users" WHERE "name" = $1)`,
wantArgs: []interface{}{"a8m"},
},
{
name: "O2M",
step: func() *Step {
step := &Step{}
step.From.Table = "users"
step.From.Column = "id"
step.To.Table = "pets"
step.To.Column = "id"
step.Edge.Rel = O2M
step.Edge.Table = "pets"
step.Edge.Columns = []string{"owner_id"}
return step
}(),
selector: Dialect("postgres").Select("*").
From(Table("users")).
Where(EQ("last_name", "mashraki")),
predicate: func(s *Selector) {
s.Where(EQ("name", "pedro"))
},
wantQuery: `SELECT * FROM "users" WHERE "last_name" = $1 AND "users"."id" IN (SELECT "pets"."owner_id" FROM "pets" WHERE "name" = $2)`,
wantArgs: []interface{}{"mashraki", "pedro"},
},
{
name: "M2O",
step: func() *Step {
step := &Step{}
step.From.Table = "pets"
step.From.Column = "id"
step.To.Table = "users"
step.To.Column = "id"
step.Edge.Rel = M2O
step.Edge.Table = "pets"
step.Edge.Inverse = true
step.Edge.Columns = []string{"owner_id"}
return step
}(),
selector: Dialect("postgres").Select("*").
From(Table("pets")).
Where(EQ("name", "pedro")),
predicate: func(s *Selector) {
s.Where(EQ("last_name", "mashraki"))
},
wantQuery: `SELECT * FROM "pets" WHERE "name" = $1 AND "pets"."owner_id" IN (SELECT "users"."id" FROM "users" WHERE "last_name" = $2)`,
wantArgs: []interface{}{"pedro", "mashraki"},
},
{
name: "M2M",
step: func() *Step {