CRM-21362: Mailing summary report group by MySQL 5.7 error
authordeb.monish <monish.deb@jmaconsulting.biz>
Fri, 27 Oct 2017 08:23:24 +0000 (13:53 +0530)
committerdeb.monish <monish.deb@jmaconsulting.biz>
Fri, 27 Oct 2017 17:52:09 +0000 (23:22 +0530)
CRM/Contact/BAO/Query.php
CRM/Report/Form/Mailing/Summary.php
CRM/Utils/SQL.php

index 55c28556fe78369952dab0db06d3f49e001485ba..4fc9bd6f213cd503116ce804cb96e572bf872f43 100644 (file)
@@ -4678,16 +4678,7 @@ civicrm_relationship.is_permission_a_b = 0
    * @return string
    */
   public static function appendAnyValueToSelect($selectClauses, $groupBy) {
-    $mysqlVersion = CRM_Core_DAO::singleValueQuery('SELECT VERSION()');
-    $sqlMode = explode(',', CRM_Core_DAO::singleValueQuery('SELECT @@sql_mode'));
-
-    // Disable only_full_group_by mode for lower sql versions.
-    if (version_compare($mysqlVersion, '5.7', '<') || (!empty($sqlMode) && !in_array('ONLY_FULL_GROUP_BY', $sqlMode))) {
-      $key = array_search('ONLY_FULL_GROUP_BY', $sqlMode);
-      unset($sqlMode[$key]);
-      CRM_Core_DAO::executeQuery("SET SESSION sql_mode = '" . implode(',', $sqlMode) . "'");
-    }
-    else {
+    if (!CRM_Utils_SQL::disableFullGroupByMode()) {
       $groupBy = array_map('trim', (array) $groupBy);
       $aggregateFunctions = '/(ROUND|AVG|COUNT|GROUP_CONCAT|SUM|MAX|MIN)\(/i';
       foreach ($selectClauses as $key => &$val) {
@@ -4702,6 +4693,27 @@ civicrm_relationship.is_permission_a_b = 0
     return "SELECT " . implode(', ', $selectClauses) . " ";
   }
 
+  /**
+   * For some special cases, where if non-aggregate ORDER BY columns are not present in GROUP BY
+   *  on full_group_by mode, then append the those missing columns to GROUP BY clause
+   * keyword to select fields not present in groupBy
+   *
+   * @param string $groupBy - GROUP BY clause where missing ORDER BY columns will be appended
+   * @param array $orderBys - ORDER BY sub-clauses
+   *
+   */
+  public static function getGroupByFromOrderBy(&$groupBy, $orderBys) {
+    if (!CRM_Utils_SQL::disableFullGroupByMode()) {
+      foreach ($orderBys as $orderBy) {
+        $orderBy = str_replace(array(' DESC', ' ASC'), '', $orderBy); // remove sort syntax from ORDER BY clauses if present
+        // if ORDER BY column is not present in GROUP BY then append it to end
+        if (!strstr($groupBy, $orderBy)) {
+          $groupBy .= ", {$orderBy}";
+        }
+      }
+    }
+  }
+
   /**
    * Include Select columns in groupBy clause.
    *
index c5373ed425bb5b4de5910874cfa43c61d3ec1a17..75f2b961747842271799018032e790fc1d512dfc 100644 (file)
@@ -500,10 +500,6 @@ class CRM_Report_Form_Mailing_Summary extends CRM_Report_Form {
     else {
       $this->_where = "WHERE " . implode(' AND ', $clauses);
     }
-
-    // if ( $this->_aclWhere ) {
-    // $this->_where .= " AND {$this->_aclWhere} ";
-    // }
   }
 
   public function groupBy() {
@@ -513,6 +509,11 @@ class CRM_Report_Form_Mailing_Summary extends CRM_Report_Form {
     $this->_groupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($this->_selectClauses, $groupBy);
   }
 
+  public function orderBy() {
+    parent::orderBy();
+    CRM_Contact_BAO_Query::getGroupByFromOrderBy($this->_groupBy, $this->_orderByArray);
+  }
+
   public function postProcess() {
 
     $this->beginPostProcess();
index 98f437e09a3e6bf35d27cc4fe2ce7af0956040cb..1e8897f802fe720772b935a2a6ceb0ccf8766ca7 100644 (file)
@@ -76,4 +76,24 @@ class CRM_Utils_SQL {
     return version_compare(CRM_Core_DAO::singleValueQuery('SELECT VERSION()'), '5.7', '>=');
   }
 
+  /**
+   * Disable ONLY_FULL_GROUP_BY for MySQL versions lower then 5.7
+   *
+   * @return bool
+   */
+  public static function disableFullGroupByMode() {
+    $sqlModes = self::getSqlModes();
+
+    // Disable only_full_group_by mode for lower sql versions.
+    if (!self::supportsFullGroupBy() || (!empty($sqlModes) && !in_array('ONLY_FULL_GROUP_BY', $sqlModes))) {
+      if ($key = array_search('ONLY_FULL_GROUP_BY', $sqlModes)) {
+        unset($sqlModes[$key]);
+        CRM_Core_DAO::executeQuery("SET SESSION sql_mode = '" . implode(',', $sqlModes) . "'");
+      }
+      return TRUE;
+    }
+
+    return FALSE;
+  }
+
 }