From 6be6113355881e4f320d0260d6a6528ced3e7d11 Mon Sep 17 00:00:00 2001 From: Jared Hancock <jared@osticket.com> Date: Mon, 18 Apr 2016 21:15:16 -0500 Subject: [PATCH] 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. --- include/class.orm.php | 9 ++++++++- include/class.staff.php | 4 ---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/class.orm.php b/include/class.orm.php index c71f0e1e6..e919e8f86 100644 --- a/include/class.orm.php +++ b/include/class.orm.php @@ -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); diff --git a/include/class.staff.php b/include/class.staff.php index 8cc30b7db..6709bac0d 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -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'), -- GitLab