From: CiviCRM Date: Wed, 6 Jan 2016 22:13:30 +0000 (-0800) Subject: CRM_Utils_SQL_Select - Fix dedupe behavior for `select`, `groupBy`, `having`, `orderBy`. X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=6e6685dcd15788683848a2aec52534edb1e279e0;p=civicrm-core.git CRM_Utils_SQL_Select - Fix dedupe behavior for `select`, `groupBy`, `having`, `orderBy`. The selected columns should not be deduped at all -- when using `insertInto()`, the selected columns need to line up with the insertion columns, and it's perfectly reasonably to re-use the same value in multipl columns. For th others, it's semantically OK to dedupe, but we should dedupe based on the evaluated query expression rather than the general formula. --- diff --git a/CRM/Utils/SQL/Select.php b/CRM/Utils/SQL/Select.php index f7e1777e64..a45bfa5729 100644 --- a/CRM/Utils/SQL/Select.php +++ b/CRM/Utils/SQL/Select.php @@ -223,7 +223,7 @@ class CRM_Utils_SQL_Select implements ArrayAccess { public function select($exprs, $args = NULL) { $exprs = (array) $exprs; foreach ($exprs as $expr) { - $this->selects[$expr] = $this->interpolate($expr, $args); + $this->selects[] = $this->interpolate($expr, $args); } return $this; } @@ -254,7 +254,8 @@ class CRM_Utils_SQL_Select implements ArrayAccess { public function groupBy($exprs, $args = NULL) { $exprs = (array) $exprs; foreach ($exprs as $expr) { - $this->groupBys[$expr] = $this->interpolate($expr, $args); + $evaluatedExpr = $this->interpolate($expr, $args); + $this->groupBys[$evaluatedExpr] = $evaluatedExpr; } return $this; } @@ -269,7 +270,8 @@ class CRM_Utils_SQL_Select implements ArrayAccess { public function having($exprs, $args = NULL) { $exprs = (array) $exprs; foreach ($exprs as $expr) { - $this->havings[$expr] = $this->interpolate($expr, $args); + $evaluatedExpr = $this->interpolate($expr, $args); + $this->havings[$evaluatedExpr] = $evaluatedExpr; } return $this; } @@ -284,7 +286,8 @@ class CRM_Utils_SQL_Select implements ArrayAccess { public function orderBy($exprs, $args = NULL) { $exprs = (array) $exprs; foreach ($exprs as $expr) { - $this->orderBys[$expr] = $this->interpolate($expr, $args); + $evaluatedExpr = $this->interpolate($expr, $args); + $this->orderBys[$evaluatedExpr] = $evaluatedExpr; } return $this; } diff --git a/tests/phpunit/CRM/Utils/SQL/SelectTest.php b/tests/phpunit/CRM/Utils/SQL/SelectTest.php index d241508e68..ecdc6abf9f 100644 --- a/tests/phpunit/CRM/Utils/SQL/SelectTest.php +++ b/tests/phpunit/CRM/Utils/SQL/SelectTest.php @@ -259,6 +259,22 @@ class CRM_Utils_SQL_SelectTest extends CiviUnitTestCase { $this->assertEquals('world', $select['hello']); } + public function testInsertInto_WithDupes() { + $select = CRM_Utils_SQL_Select::from('foo') + ->insertInto('bar', array('first', 'second', 'third', 'fourth')) + ->select('fid') + ->select('1') + ->select('fid') + ->select('1') + ->where('!field = #value', array('field' => 'zoo', 'value' => 3)) + ->where('!field = #value', array('field' => 'aviary', 'value' => 3)) + ->where('!field = #value', array('field' => 'zoo', 'value' => 3)) + ->groupBy('!colName', array('colName' => 'noodle')) + ->groupBy('!colName', array('colName' => 'sauce')) + ->groupBy('!colName', array('colName' => 'noodle')); + $this->assertLike('INSERT INTO bar (first, second, third, fourth) SELECT fid, 1, fid, 1 FROM foo WHERE (zoo = 3) AND (aviary = 3) GROUP BY noodle, sauce', $select->toSQL()); + } + /** * @param $expected * @param $actual