diff --git a/src/Query.php b/src/Query.php index d83b101..aecefce 100644 --- a/src/Query.php +++ b/src/Query.php @@ -657,6 +657,10 @@ public function createSubQuery(Model $target, string $targetPath, ?Model $from = foreach ($this->getResolver()->resolveRelations($targetPath, $from) as $relationPath => $relation) { $predecessor = array_slice(explode('.', $relationPath), -2, 1)[0]; foreach ($relation->reverse($subQueryResolver) as $oppositeRelation) { + // Always override the join type, as a sub-query that is unable + // to establish a link to the outer query is useless anyway. + $oppositeRelation->setJoinType('INNER'); + if ( $relation->getReverseName() === null && $predecessor !== $oppositeRelation->getName() diff --git a/tests/Lib/Model/Chair.php b/tests/Lib/Model/Chair.php index f5e6ab2..4a20641 100644 --- a/tests/Lib/Model/Chair.php +++ b/tests/Lib/Model/Chair.php @@ -28,6 +28,7 @@ public function getColumns() public function createRelations(Relations $relations) { - $relations->belongsTo('employee', Employee::class); + $relations->belongsTo('employee', Employee::class) + ->setJoinType('LEFT'); } } diff --git a/tests/QueryTest.php b/tests/QueryTest.php index 0c00961..34e1495 100644 --- a/tests/QueryTest.php +++ b/tests/QueryTest.php @@ -5,8 +5,11 @@ use ipl\Orm\Exception\InvalidRelationException; use ipl\Orm\Query; use ipl\Orm\ResolvedExpression; +use ipl\Sql\Connection; use ipl\Sql\Expression; use ipl\Sql\Test\TestCase; +use ipl\Stdlib\Filter; +use ipl\Tests\Orm\Lib\Model\Employee; class QueryTest extends TestCase { @@ -607,4 +610,26 @@ public function testWithoutColumnsDoesNotWorkWithExpressions() $query->assembleSelect() ); } + + public function testSubQueriesOverrideTheJoinType(): void + { + $query = (new Query()) + ->setDb($this->createStub(Connection::class)) + ->setModel(new Employee()) + ->columns('name') + ->filter(Filter::equal('chair.vendor', 'Icinga')); + + $this->assertSql( + <<<'SQL' +SELECT employee.name FROM employee +WHERE (employee.deleted = ?) AND (employee.id IN ((SELECT sub_chair_employee.id AS sub_chair_employee_id + FROM chair sub_chair + INNER JOIN employee sub_chair_employee + ON (sub_chair_employee.id = sub_chair.employee_id) AND (sub_chair_employee.deleted = ?) + WHERE sub_chair.vendor = ?))) +SQL, + $query->assembleSelect(), + ['n', 'n', 'Icinga'] + ); + } }