From 856a73fb87a1c62d6590dc3c378c38927443c0ed Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Wed, 5 Apr 2017 12:58:33 +0000 Subject: [PATCH] N.689 61 tables limit. INVESTIGATING the issue. Added a test to reproduce the issue on the standard data model, and a test to build statistics on the number of tables used by classes. SVN:trunk[4669] --- core/sqlobjectquery.class.inc.php | 11 ++++ test/testlist.inc.php | 99 +++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/core/sqlobjectquery.class.inc.php b/core/sqlobjectquery.class.inc.php index e9c7d7dfd..6cad9b3f2 100644 --- a/core/sqlobjectquery.class.inc.php +++ b/core/sqlobjectquery.class.inc.php @@ -534,6 +534,17 @@ class SQLObjectQuery extends SQLQuery return (count($this->m_aJoinSelects) == 0); } + public function CountTables() + { + $iRet = 1; + foreach ($this->m_aJoinSelects as $i => $aJoinInfo) + { + $oSQLQuery = $aJoinInfo["select"]; + $iRet += $oSQLQuery->CountTables(); + } + return $iRet; + } + protected function CollectUsedTables(&$aTables) { $this->m_oConditionExpr->CollectUsedParents($aTables); diff --git a/test/testlist.inc.php b/test/testlist.inc.php index d3144e819..c7b551043 100644 --- a/test/testlist.inc.php +++ b/test/testlist.inc.php @@ -5629,3 +5629,102 @@ class TestBug788 extends TestBizModel } } } + +class WhereIsThe61TablesThreat extends TestBizModel +{ + static public function GetName() + { + return '61 tables'; + } + + static public function GetDescription() + { + return 'Evaluate where is the 61 tables limit threat'; + } + + protected function DoExecute() + { + $aClassToCount_Full = array(); + $aDistribution = array(); + $iTotalClasses = 0; + foreach (MetaModel::GetClasses() as $sClass) + { + if (MetaModel::IsAbstract($sClass)) continue; + + $iTotalClasses++; + $oSearch = DBSearch::FromOQL("SELECT $sClass WHERE id = 1"); + $oSql = $oSearch->GetSQLQueryStructure(array(), false, null); + $iCount = $oSql->CountTables(); + $aClassToCount_Full[$sClass] = $iCount; + if (array_key_exists($iCount, $aDistribution)) + { + $aDistribution[$iCount]++; + } + else + { + $aDistribution[$iCount] = 1; + } + } + arsort($aClassToCount_Full); + + $iHighestCount = max($aClassToCount_Full); + for($i = 1; $i < $iHighestCount ; $i++) + { + if (!array_key_exists($i, $aDistribution)) + { + $aDistribution[$i] = 0; + } + } + ksort($aDistribution); + + + $i = 0; + $iLimit = 15; + $iCountThreshold = 10; + echo "
TOP $iLimit offenders (+ those exceeding $iCountThreshold tables)
"; + foreach ($aClassToCount_Full as $sClass => $iCountFull) + { + $i++; + if (($iCountFull <= $iCountThreshold) && ($i >= $iLimit)) break; + + echo "$sClass: $iCountFull tables
"; + } + + echo "
Distribution of table counts
"; + echo "

Over a total of $iTotalClasses instantiable classes.

"; + echo ""; + echo ""; + foreach ($aDistribution as $iTableCount => $iClassCount) + { + echo ""; + } + echo "
Table countClasses
$iTableCount$iClassCount
"; + } +} + +class TestBug689 extends TestBizModel +{ + static public function GetName() + { + return 'An OQL failing to export in XML'; + } + + static public function GetDescription() + { + return '(N.689) Reaching the limit of 61 tables'; + } + + protected function DoExecute() + { + $sOql = 'SELECT child, parent, s1, p, o FROM UserRequest AS child JOIN UserRequest AS parent ON child.parent_request_id = parent.id JOIN lnkFunctionalCIToTicket AS l1 ON l1.ticket_id = child.id JOIN Server AS s1 ON l1.functionalci_id = s1.id JOIN Person AS p ON child.caller_id = p.id JOIN Organization AS o ON p.org_id = o.id'; + $oSearch = DBSearch::FromOQL($sOql); + $oSql = $oSearch->GetSQLQueryStructure(array(), false, null); + //$sSql = $oSql->RenderSelect(); + + echo '

'.$sOql.'

'; + echo '

This query rendered with all columns give a MySQL query having '.$oSql->CountTables().' tables... let\'s try it with the DBObjectSet API:

'; + $oSet = new DBObjectSet($oSearch); + $oObj = $oSet->Fetch(); + echo '

Well done, this is working fine! Some magic happened in the background!

'; + } +}