Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/Collection/Functions/FetchPropertyFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,18 @@ private function processTokens(
foreach ($tokens as $tokenIndex => $token) {
$property = $currentEntityMetadata->getProperty($token);
if ($property->relationship !== null) {
$relType = $property->relationship->type;
$isMainSide = $relType === Relationship::MANY_HAS_ONE
|| ($relType === Relationship::ONE_HAS_ONE && $property->relationship->isMain);
if (
$isMainSide
&& $tokenIndex === count($tokens) - 1
&& in_array($lastToken, $property->relationship->entityMetadata->getPrimaryKey(), strict: true)
) {
$lastToken = $token;
break;
}

[
$currentAlias,
$currentConventions,
Expand Down Expand Up @@ -241,6 +253,36 @@ private function processTokens(
throw new InvalidArgumentException("Property expression '$propertyExpression' does not fetch specific property.");
}

if ($propertyMetadata->relationship !== null) {
$relType = $propertyMetadata->relationship->type;
if (
($relType === Relationship::ONE_HAS_ONE && !$propertyMetadata->relationship->isMain) ||
$relType === Relationship::ONE_HAS_MANY ||
$relType === Relationship::MANY_HAS_MANY
) {
$allTokens = [...$tokens, $lastToken];
[
$currentAlias,
$currentConventions,
$currentEntityMetadata,
] = $this->processRelationship(
$allTokens,
$joins,
$propertyMetadata,
$aggregator,
$currentConventions,
$currentMapper,
$currentAlias,
$lastToken,
count($allTokens) - 1,
$makeDistinct,
);
$primaryKey = $currentEntityMetadata->getPrimaryKey();
$lastToken = $primaryKey[0];
$propertyMetadata = $currentEntityMetadata->getProperty($lastToken);
}
}

$column = $this->toColumnExpr(
$currentEntityMetadata,
$propertyMetadata,
Expand Down
34 changes: 34 additions & 0 deletions tests/cases/integration/Collection/collection.where.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,40 @@ class CollectionWhereTest extends DataTestCase
}


public function testFilterByNonMainSideRelationship(): void
{
// Non-main side of 1:1 relationship (Ean.book is non-main, FK ean_id is in books table)
$ean = new Ean();
$ean->code = '1234';
$ean->book = $this->orm->books->getByIdChecked(1);
$this->orm->eans->persistAndFlush($ean);
$this->orm->clear();

$fetched = $this->orm->eans->findBy(['book' => 1])->fetch();
Assert::notNull($fetched);
Assert::equal('1234', $fetched->code);

Assert::null($this->orm->eans->findBy(['book' => 2])->fetch());
}


public function testFilterByNonMainSideRelationshipNull(): void
{
// Non-main side of 1:1 self-referential relationship (Book.previousPart is non-main side)
// Book 4 has next_part = 3, so Book 3 has a previousPart (= Book 4)
// Books 1, 2, 4 have no previousPart

$booksWithNoPrevious = $this->orm->books->findBy(['previousPart' => null]);
Assert::count(3, $booksWithNoPrevious);

$booksWithPrevious = $this->orm->books->findBy(['previousPart!=' => null]);
Assert::count(1, $booksWithPrevious);
$book = $booksWithPrevious->fetch();
Assert::notNull($book);
Assert::equal(3, $book->id);
}


private function moveToDifferentZone(DateTimeImmutable $dateTime): DateTimeImmutable
{
return $dateTime->setTimezone(new DateTimeZone("UTC"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ FROM
LEFT JOIN "books" AS "books_any" ON (
"authors"."id" = "books_any"."author_id"
)
LEFT JOIN "public"."authors" AS "books_translator_any" ON (
"books_any"."translator_id" = "books_translator_any"."id"
)
WHERE
("books_any"."title" = 'Book 1')
AND (
"books_translator_any"."id" IS NULL
"books_any"."translator_id" IS NULL
)
GROUP BY
"authors"."id";
Expand All @@ -27,13 +24,10 @@ FROM
LEFT JOIN "books" AS "books_any" ON (
"authors"."id" = "books_any"."author_id"
)
LEFT JOIN "public"."authors" AS "books_translator_any" ON (
"books_any"."translator_id" = "books_translator_any"."id"
)
WHERE
("books_any"."title" = 'Book 1')
AND (
"books_translator_any"."id" IS NULL
"books_any"."translator_id" IS NULL
)
GROUP BY
"authors"."id"
Expand All @@ -45,7 +39,10 @@ FROM
"public"."authors" AS "authors"
LEFT JOIN "books" AS "books_count" ON (
(
"authors"."id" = "books_count"."author_id"
(
"authors"."id" = "books_count"."author_id"
)
AND "books_count"."translator_id" IS NOT NULL
)
OR (
(
Expand All @@ -54,18 +51,12 @@ FROM
AND "books_count"."price" < 100
)
)
LEFT JOIN "public"."authors" AS "books_translator_count" ON (
(
"books_count"."translator_id" = "books_translator_count"."id"
)
AND "books_translator_count"."id" IS NOT NULL
)
GROUP BY
"authors"."id"
HAVING
(
COUNT("books_translator_count"."id") >= 1
AND COUNT("books_translator_count"."id") <= 1
COUNT("books_count"."id") >= 1
AND COUNT("books_count"."id") <= 1
)
OR (
COUNT("books_count"."id") >= 1
Expand All @@ -82,7 +73,10 @@ FROM
"public"."authors" AS "authors"
LEFT JOIN "books" AS "books_count" ON (
(
"authors"."id" = "books_count"."author_id"
(
"authors"."id" = "books_count"."author_id"
)
AND "books_count"."translator_id" IS NOT NULL
)
OR (
(
Expand All @@ -91,18 +85,12 @@ FROM
AND "books_count"."price" < 100
)
)
LEFT JOIN "public"."authors" AS "books_translator_count" ON (
(
"books_count"."translator_id" = "books_translator_count"."id"
)
AND "books_translator_count"."id" IS NOT NULL
)
GROUP BY
"authors"."id"
HAVING
(
COUNT("books_translator_count"."id") >= 1
AND COUNT("books_translator_count"."id") <= 1
COUNT("books_count"."id") >= 1
AND COUNT("books_count"."id") <= 1
)
OR (
COUNT("books_count"."id") >= 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,2 @@
SELECT
COUNT(*) AS count
FROM
(
SELECT
"books"."id"
FROM
"books" AS "books"
LEFT JOIN "public"."authors" AS "author" ON (
"books"."author_id" = "author"."id"
)
WHERE
"author"."id" > 0
) temp;

SELECT
"books".*
FROM
"books" AS "books"
LEFT JOIN "public"."authors" AS "author" ON (
"books"."author_id" = "author"."id"
)
WHERE
"author"."id" > 0
ORDER BY
"author"."id" ASC;
SELECT COUNT(*) AS count FROM (SELECT "books"."id" FROM "books" AS "books" WHERE "books"."author_id" > 0) temp;
SELECT "books".* FROM "books" AS "books" WHERE "books"."author_id" > 0 ORDER BY "books"."author_id" ASC;
Original file line number Diff line number Diff line change
@@ -1,21 +1,2 @@
SELECT
"books".*
FROM
"books" AS "books"
LEFT JOIN "public"."authors" AS "author" ON (
"books"."author_id" = "author"."id"
)
ORDER BY
"author"."id" DESC,
"books"."title" ASC;

SELECT
"books".*
FROM
"books" AS "books"
LEFT JOIN "public"."authors" AS "author" ON (
"books"."author_id" = "author"."id"
)
ORDER BY
"author"."id" DESC,
"books"."title" DESC;
SELECT "books".* FROM "books" AS "books" ORDER BY "books"."author_id" DESC, "books"."title" ASC;
SELECT "books".* FROM "books" AS "books" ORDER BY "books"."author_id" DESC, "books"."title" DESC;
Original file line number Diff line number Diff line change
@@ -1,21 +1,2 @@
SELECT
"books".*
FROM
"books" AS "books"
LEFT JOIN "public"."authors" AS "author" ON (
"books"."author_id" = "author"."id"
)
ORDER BY
"author"."id" DESC,
"books"."title" ASC;

SELECT
"books".*
FROM
"books" AS "books"
LEFT JOIN "public"."authors" AS "author" ON (
"books"."author_id" = "author"."id"
)
ORDER BY
"author"."id" DESC,
"books"."title" DESC;
SELECT "books".* FROM "books" AS "books" ORDER BY "books"."author_id" DESC, "books"."title" ASC;
SELECT "books".* FROM "books" AS "books" ORDER BY "books"."author_id" DESC, "books"."title" DESC;
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
SELECT "books".* FROM "books" AS "books" WHERE "books"."id" = 1;
START TRANSACTION;
INSERT INTO "eans" ("code", "type") VALUES ('1234', 2);
SELECT CURRVAL('public.eans_id_seq');
UPDATE "books" SET "ean_id" = 1 WHERE "id" = 1;
COMMIT;
SELECT
"eans".*
FROM
"eans" AS "eans"
LEFT JOIN "books" AS "book" ON ("eans"."id" = "book"."ean_id")
WHERE
"book"."id" = 1;

SELECT
"eans".*
FROM
"eans" AS "eans"
LEFT JOIN "books" AS "book" ON ("eans"."id" = "book"."ean_id")
WHERE
"book"."id" = 2;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
SELECT
"books".*
FROM
"books" AS "books"
LEFT JOIN "books" AS "previousPart" ON (
"books"."id" = "previousPart"."next_part"
)
WHERE
"previousPart"."id" IS NULL;

SELECT
"books".*
FROM
"books" AS "books"
LEFT JOIN "books" AS "previousPart" ON (
"books"."id" = "previousPart"."next_part"
)
WHERE
"previousPart"."id" IS NOT NULL;
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ SELECT
"books_x_tags"."tag_id"
FROM
"books" AS "books"
LEFT JOIN "public"."authors" AS "author" ON (
"books"."author_id" = "author"."id"
)
LEFT JOIN "books_x_tags" AS "books_x_tags" ON (
"books_x_tags"."book_id" = "books"."id"
)
WHERE
("author"."id" = 1)
("books"."author_id" = 1)
AND (
"books_x_tags"."tag_id" IN (1)
);
Expand All @@ -24,14 +21,11 @@ SELECT
) AS "count"
FROM
"books" AS "books"
LEFT JOIN "public"."authors" AS "author" ON (
"books"."author_id" = "author"."id"
)
LEFT JOIN "books_x_tags" AS "books_x_tags" ON (
"books_x_tags"."book_id" = "books"."id"
)
WHERE
("author"."id" = 1)
("books"."author_id" = 1)
AND (
"books_x_tags"."tag_id" IN (1)
)
Expand All @@ -53,15 +47,12 @@ FROM
LEFT JOIN "tag_followers" AS "author_tagFollowers_any" ON (
"author"."id" = "author_tagFollowers_any"."author_id"
)
LEFT JOIN "public"."authors" AS "author_tagFollowers_author_any" ON (
"author_tagFollowers_any"."author_id" = "author_tagFollowers_author_any"."id"
)
LEFT JOIN "books_x_tags" AS "books_x_tags" ON (
"books_x_tags"."book_id" = "books"."id"
)
WHERE
(
"author_tagFollowers_author_any"."id" = 1
"author_tagFollowers_any"."author_id" = 1
)
AND (
"books_x_tags"."tag_id" IN (1)
Expand Down Expand Up @@ -89,15 +80,12 @@ FROM
LEFT JOIN "tag_followers" AS "author_tagFollowers_any" ON (
"author"."id" = "author_tagFollowers_any"."author_id"
)
LEFT JOIN "public"."authors" AS "author_tagFollowers_author_any" ON (
"author_tagFollowers_any"."author_id" = "author_tagFollowers_author_any"."id"
)
LEFT JOIN "books_x_tags" AS "books_x_tags" ON (
"books_x_tags"."book_id" = "books"."id"
)
WHERE
(
"author_tagFollowers_author_any"."id" = 1
"author_tagFollowers_any"."author_id" = 1
)
AND (
"books_x_tags"."tag_id" IN (1)
Expand Down
Loading