diff --git a/core/metamodel.class.php b/core/metamodel.class.php
index 9ebab4ad0..c18acb527 100644
--- a/core/metamodel.class.php
+++ b/core/metamodel.class.php
@@ -2161,14 +2161,23 @@ abstract class MetaModel
//
$aUpdateValues = array();
+
// 1/a - Get the key and friendly name
//
// We need one pkey to be the key, let's take the one corresponding to the root class
// (used to be based on the leaf, but it may happen that this one has no table defined)
$sRootClass = self::GetRootClass($sTargetClass);
+ $oSelectedIdField = null;
if ($sTableClass == $sRootClass)
{
- $aTranslation[$sTargetAlias]['id'] = new FieldExpressionResolved(self::DBGetKey($sTableClass), $sTableAlias);
+ $oIdField = new FieldExpressionResolved(self::DBGetKey($sTableClass), $sTableAlias);
+ $aTranslation[$sTargetAlias]['id'] = $oIdField;
+
+ if ($bIsOnQueriedClass)
+ {
+ // Add this field to the list of queried fields (required for the COUNT to work fine)
+ $oSelectedIdField = $oIdField;
+ }
}
// 1/b - Get the other attributes
@@ -2227,7 +2236,7 @@ abstract class MetaModel
// 3 - The whole stuff, for this table only
//
- $oSelectBase = new SQLQuery($sTable, $sTableAlias, array(), $aFullText, $bIsOnQueriedClass, $aUpdateValues);
+ $oSelectBase = new SQLQuery($sTable, $sTableAlias, array(), $aFullText, $bIsOnQueriedClass, $aUpdateValues, $oSelectedIdField);
// 4 - The external keys -> joins...
//
diff --git a/core/sqlquery.class.inc.php b/core/sqlquery.class.inc.php
index e34c3120d..22605d711 100644
--- a/core/sqlquery.class.inc.php
+++ b/core/sqlquery.class.inc.php
@@ -44,9 +44,10 @@ class SQLQuery
private $m_aFullTextNeedles = array();
private $m_bToDelete = true; // The current table must be listed for deletion ?
private $m_aValues = array(); // Values to set in case of an update query
+ private $m_oSelectedIdField = null;
private $m_aJoinSelects = array();
- public function __construct($sTable, $sTableAlias, $aFields, $aFullTextNeedles = array(), $bToDelete = true, $aValues = array())
+ public function __construct($sTable, $sTableAlias, $aFields, $aFullTextNeedles = array(), $bToDelete = true, $aValues = array(), $oSelectedIdField = null)
{
// This check is not needed but for developping purposes
//if (!CMDBSource::IsTable($sTable))
@@ -65,6 +66,7 @@ class SQLQuery
$this->m_aFullTextNeedles = $aFullTextNeedles;
$this->m_bToDelete = $bToDelete;
$this->m_aValues = $aValues;
+ $this->m_oSelectedIdField = $oSelectedIdField;
}
public function DisplayHtml()
@@ -113,7 +115,8 @@ class SQLQuery
$oCondition = null;
$aDelTables = array();
$aSetValues = array();
- $this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues);
+ $aSelectedIdFields = array();
+ $this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues, $aSelectedIdFields);
echo "From ...
\n";
echo "
\n";
print_r($aFrom);
@@ -188,7 +191,8 @@ class SQLQuery
$oCondition = null;
$aDelTables = array();
$aSetValues = array();
- $this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues);
+ $aSelectedIdFields = array();
+ $this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues, $aSelectedIdFields);
// Target: DELETE myAlias1, myAlias2 FROM t1 as myAlias1, t2 as myAlias2, t3 as topreserve WHERE ...
@@ -222,7 +226,8 @@ class SQLQuery
$oCondition = null;
$aDelTables = array();
$aSetValues = array();
- $this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues);
+ $aSelectedIdFields = array();
+ $this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues, $aSelectedIdFields);
$sFrom = self::ClauseFrom($aFrom);
$sValues = self::ClauseValues($aSetValues);
@@ -239,13 +244,22 @@ class SQLQuery
$oCondition = null;
$aDelTables = array();
$aSetValues = array();
- $this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues);
+ $aSelectedIdFields = array();
+ $this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues, $aSelectedIdFields);
$sFrom = self::ClauseFrom($aFrom);
$sWhere = self::ClauseWhere($oCondition, $aArgs);
if ($bGetCount)
{
- $sSQL = "SELECT COUNT(*) AS COUNT FROM $sFrom WHERE $sWhere";
+ if (count($aSelectedIdFields) > 0)
+ {
+ $sIDFields = implode(', ', $aSelectedIdFields);
+ $sSQL = "SELECT COUNT(DISTINCT $sIDFields) AS COUNT FROM $sFrom WHERE $sWhere";
+ }
+ else
+ {
+ $sSQL = "SELECT COUNT(*) AS COUNT FROM $sFrom WHERE $sWhere";
+ }
}
else
{
@@ -353,9 +367,9 @@ class SQLQuery
}
// Purpose: prepare the query data, once for all
- private function privRender(&$aFrom, &$aFields, &$oCondition, &$aDelTables, &$aSetValues)
+ private function privRender(&$aFrom, &$aFields, &$oCondition, &$aDelTables, &$aSetValues, &$aSelectedIdFields)
{
- $sTableAlias = $this->privRenderSingleTable($aFrom, $aFields, $aDelTables, $aSetValues);
+ $sTableAlias = $this->privRenderSingleTable($aFrom, $aFields, $aDelTables, $aSetValues, $aSelectedIdFields);
// Add the full text search condition, based on each and every requested field
//
@@ -388,7 +402,7 @@ class SQLQuery
return $sTableAlias;
}
- private function privRenderSingleTable(&$aFrom, &$aFields, &$aDelTables, &$aSetValues, $sJoinType = 'first', $sCallerAlias = '', $sLeftField = '', $sRightField = '', $sRightTableAlias = '')
+ private function privRenderSingleTable(&$aFrom, &$aFields, &$aDelTables, &$aSetValues, &$aSelectedIdFields, $sJoinType = 'first', $sCallerAlias = '', $sLeftField = '', $sRightField = '', $sRightTableAlias = '')
{
$aActualTableFields = CMDBSource::GetTableFieldsList($this->m_sTable);
@@ -429,6 +443,11 @@ class SQLQuery
$aSetValues["`{$this->m_sTableAlias}`.`$sFieldName`"] = $value; // quoted further!
}
+ if (!is_null($this->m_oSelectedIdField))
+ {
+ $aSelectedIdFields[] = $this->m_oSelectedIdField->Render();
+ }
+
// loop on joins, to complete the list of tables/fields/conditions
//
$aTempFrom = array(); // temporary subset of 'from' specs, to be grouped in the final query
@@ -440,7 +459,7 @@ class SQLQuery
$sRightField = $aJoinData["rightfield"];
$sRightTableAlias = $aJoinData["righttablealias"];
- $sJoinTableAlias = $oRightSelect->privRenderSingleTable($aTempFrom, $aFields, $aDelTables, $aSetValues, $sJoinType, $this->m_sTableAlias, $sLeftField, $sRightField, $sRightTableAlias);
+ $sJoinTableAlias = $oRightSelect->privRenderSingleTable($aTempFrom, $aFields, $aDelTables, $aSetValues, $aSelectedIdFields, $sJoinType, $this->m_sTableAlias, $sLeftField, $sRightField, $sRightTableAlias);
}
$aFrom[$this->m_sTableAlias]['subfrom'] = $aTempFrom;