Skip to content
Snippets Groups Projects
Commit 6be61133 authored by Jared Hancock's avatar Jared Hancock
Browse files

orm: Propagate LEFT joins in join paths

If something like members__staff is considered leaving the Team model,
and the `members` relationship is nullable, and the `staff` relationship is
not, in the context of the compiled SQL statement, the second join should
also be considered nullable (LEFT join), because otherwise inconsistent
results would be returned from the query.

In other words, if a count is considered as an annotation to the Team model
instances, Teams with zero members should still be considered as valid teams
and should be selected with such an annotation. Before this patch, however,
the join between TeamMember and Staff would have been an inner join instead
of a LEFT join, which could skew the database results.
parent 5acdf568
No related branches found
No related tags found
No related merge requests found
......@@ -2115,13 +2115,20 @@ class SqlCompiler {
// Call pushJoin for each segment in the join path. A new JOIN
// fragment will need to be emitted and/or cached
$joins = array();
$push = function($p, $model) use (&$joins, &$path) {
$null = false;
$push = function($p, $model) use (&$joins, &$path, &$null) {
$J = $model::getMeta('joins');
if (!($info = $J[$p])) {
throw new OrmException(sprintf(
'Model `%s` does not have a relation called `%s`',
$model, $p));
}
// Propogate LEFT joins through other joins. That is, if a
// multi-join expression is used, the first LEFT join should
// result in further joins also being LEFT
if (isset($info['null']))
$null = $null || $info['null'];
$info['null'] = $null;
$crumb = $path;
$path = ($path) ? "{$path}__{$p}" : $p;
$joins[] = array($crumb, $path, $model, $info);
......
......@@ -1143,10 +1143,6 @@ class StaffDeptAccess extends VerySimpleModel {
'joins' => array(
'dept' => array(
'constraint' => array('dept_id' => 'Dept.id'),
// FIXME: The ORM needs a way to support
// staff__dept_access__dept performing a LEFT join b/c
// staff__dept_access is LEFT
'null' => true,
),
'staff' => array(
'constraint' => array('staff_id' => 'Staff.staff_id'),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment