mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-19 00:28:47 +02:00
N°3618 - Count on union with different conditions fails (Fix multi-column attributes sql generation)
This commit is contained in:
@@ -1672,6 +1672,35 @@ class FieldExpression extends UnaryExpression
|
||||
// Has been resolved into an SQL expression
|
||||
class FieldExpressionResolved extends FieldExpression
|
||||
{
|
||||
protected $m_aAdditionalExpressions;
|
||||
|
||||
public function __construct($mExpression, $sParent = '')
|
||||
{
|
||||
$this->m_aAdditionalExpressions = array();
|
||||
if (is_array($mExpression))
|
||||
{
|
||||
foreach ($mExpression as $sSuffix => $sExpression)
|
||||
{
|
||||
if ($sSuffix == '')
|
||||
{
|
||||
$sName = $sExpression;
|
||||
}
|
||||
$this->m_aAdditionalExpressions[$sSuffix] = new FieldExpressionResolved($sExpression, $sParent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sName = $mExpression;
|
||||
}
|
||||
|
||||
parent::__construct($sName, $sParent);
|
||||
}
|
||||
|
||||
public function AdditionalExpressions()
|
||||
{
|
||||
return $this->m_aAdditionalExpressions;
|
||||
}
|
||||
|
||||
public function GetUnresolvedFields($sAlias, &$aUnresolved)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -178,6 +178,14 @@ class QueryBuilderExpressions
|
||||
foreach ($this->m_aSelectExpr as $sColAlias => $oExpr)
|
||||
{
|
||||
$this->m_aSelectExpr[$sColAlias] = $oExpr->Translate($aTranslationData, $bMatchAll, $bMarkFieldsAsResolved);
|
||||
if ($this->m_aSelectExpr[$sColAlias] instanceof FieldExpressionResolved)
|
||||
{
|
||||
// Split the field with the relevant alias
|
||||
foreach ($this->m_aSelectExpr[$sColAlias]->AdditionalExpressions() as $sSuffix => $oAdditionalExpr)
|
||||
{
|
||||
$this->m_aSelectExpr[$sColAlias.$sSuffix] = $oAdditionalExpr->Translate($aTranslationData, $bMatchAll, $bMarkFieldsAsResolved);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->m_aGroupByExpr)
|
||||
{
|
||||
|
||||
@@ -239,24 +239,16 @@ class SQLObjectQueryBuilder
|
||||
continue;
|
||||
}
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
foreach ($oAttDef->GetSQLExpressions() as $sColId => $sSQLExpr)
|
||||
$oFieldSQLExp = new FieldExpressionResolved($oAttDef->GetSQLExpressions(), $sClassAlias);
|
||||
/**
|
||||
* @var string $sPluginClass
|
||||
* @var iQueryModifier $oQueryModifier
|
||||
*/
|
||||
foreach (MetaModel::EnumPlugins('iQueryModifier') as $sPluginClass => $oQueryModifier)
|
||||
{
|
||||
if (!empty($sColId))
|
||||
{
|
||||
// Multi column attributes
|
||||
$oBuild->m_oQBExpressions->AddSelect($sSelectedClassAlias.$sAttCode.$sColId, new FieldExpression($sAttCode.$sColId, $sClassAlias));
|
||||
}
|
||||
$oFieldSQLExp = new FieldExpressionResolved($sSQLExpr, $sClassAlias);
|
||||
/**
|
||||
* @var string $sPluginClass
|
||||
* @var iQueryModifier $oQueryModifier
|
||||
*/
|
||||
foreach (MetaModel::EnumPlugins('iQueryModifier') as $sPluginClass => $oQueryModifier)
|
||||
{
|
||||
$oFieldSQLExp = $oQueryModifier->GetFieldExpression($oBuild, $sClass, $sAttCode, $sColId, $oFieldSQLExp, $oBaseSQLQuery);
|
||||
}
|
||||
$aTranslation[$sClassAlias][$sAttCode.$sColId] = $oFieldSQLExp;
|
||||
$oFieldSQLExp = $oQueryModifier->GetFieldExpression($oBuild, $sClass, $sAttCode, '', $oFieldSQLExp, $oBaseSQLQuery);
|
||||
}
|
||||
$aTranslation[$sClassAlias][$sAttCode] = $oFieldSQLExp;
|
||||
}
|
||||
|
||||
// Translate the selected columns
|
||||
|
||||
@@ -50,6 +50,7 @@ class OQLTest extends ItopDataTestCase
|
||||
|
||||
/**
|
||||
* @dataProvider NestedQueryProvider
|
||||
* @depends testOQLSetup
|
||||
*
|
||||
* @param $sQuery
|
||||
*
|
||||
@@ -435,9 +436,7 @@ class OQLTest extends ItopDataTestCase
|
||||
{
|
||||
return [
|
||||
'Bug 3660 1' => [
|
||||
"SELECT UserRequest AS U
|
||||
JOIN lnkContactToTicket AS l ON l.ticket_id=U.id
|
||||
JOIN Team AS T ON l.contact_id=T.id",
|
||||
"SELECT UserRequest AS U JOIN lnkContactToTicket AS l ON l.ticket_id=U.id JOIN Team AS T ON l.contact_id=T.id",
|
||||
"SELECT `U` FROM `UserRequest` AS `U`
|
||||
INNER JOIN `lnkContactToTicket` AS `l`
|
||||
ON `U`.`id` = `l`.`ticket_id`
|
||||
@@ -445,13 +444,64 @@ class OQLTest extends ItopDataTestCase
|
||||
ON `l`.`contact_id` = `T`.`id`",
|
||||
],
|
||||
'Bug 3660 2' => [
|
||||
"SELECT UserRequest AS U
|
||||
JOIN lnkContactToTicket AS l ON l.ticket_id=U.id
|
||||
JOIN Contact AS C ON l.contact_id=C.id",
|
||||
"SELECT UserRequest AS U JOIN lnkContactToTicket AS l ON l.ticket_id=U.id JOIN Contact AS C ON l.contact_id=C.id",
|
||||
"SELECT `U` FROM `UserRequest` AS `U`
|
||||
INNER JOIN `lnkContactToTicket` AS `l`
|
||||
ON `U`.`id` = `l`.`ticket_id`",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider MakeSelectQueryForCountProvider
|
||||
*
|
||||
* @param $sOQL
|
||||
* @param $sExpectedSQL
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function testMakeSelectQueryForCount($sOQL, $sExpectedSQL)
|
||||
{
|
||||
$oFilter = DBSearch::FromOQL($sOQL);
|
||||
// Avoid adding all the fields for counts or "group by" requests
|
||||
$aCountAttToLoad = array();
|
||||
$sMainClass = null;
|
||||
foreach ($oFilter->GetSelectedClasses() as $sClassAlias => $sClass) {
|
||||
$aCountAttToLoad[$sClassAlias] = array();
|
||||
if (empty($sMainClass)) {
|
||||
$sMainClass = $sClass;
|
||||
}
|
||||
}
|
||||
$sSQL = $oFilter->MakeSelectQuery([], [], $aCountAttToLoad, null, 0, 0, true);
|
||||
static::assertEquals($sExpectedSQL, $sSQL);
|
||||
}
|
||||
|
||||
public function MakeSelectQueryForCountProvider()
|
||||
{
|
||||
return [
|
||||
'Bug 3618' => [
|
||||
"SELECT UserRequest WHERE private_log LIKE '%Auteur : %' UNION SELECT Problem",
|
||||
"SELECT COUNT(*) AS COUNT FROM (SELECT
|
||||
1
|
||||
FROM (
|
||||
SELECT
|
||||
DISTINCT `UserRequest_Ticket`.`id` AS `UserRequestid`
|
||||
FROM
|
||||
`ticket` AS `UserRequest_Ticket`
|
||||
WHERE ((`UserRequest_Ticket`.`private_log` LIKE '%Auteur : %') AND COALESCE((`UserRequest_Ticket`.`finalclass` IN ('UserRequest')), 1))
|
||||
|
||||
UNION
|
||||
SELECT
|
||||
DISTINCT `Problem`.`id` AS `Problemid`
|
||||
FROM
|
||||
`ticket_problem` AS `Problem`
|
||||
WHERE 1
|
||||
|
||||
) as __selects__
|
||||
) AS _union_alderaan_",
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user