/** * Provides the main table to form the LEFT JOIN clause * * @param array $search_tables Tables involved in the search * @param array $search_columns Columns involved in the search * @param array $where_clause_columns Columns having criteria where clause * @param array $where_clause_tables Tables having criteria where clause * * @return string table name */ private function _getMasterTable($search_tables, $search_columns, $where_clause_columns, $where_clause_tables) { if (count($where_clause_tables) == 1) { // If there is exactly one column that has a decent where-clause // we will just use this $master = key($where_clause_tables); return $master; } // Now let's find out which of the tables has an index // (When the control user is the same as the normal user // because he is using one of his databases as pmadb, // the last db selected is not always the one where we need to work) $candidate_columns = $this->_getLeftJoinColumnCandidates($search_tables, $search_columns, $where_clause_columns); // Generally, we need to display all the rows of foreign (referenced) // table, whether they have any matching row in child table or not. // So we select candidate tables which are foreign tables. $foreign_tables = array(); foreach ($candidate_columns as $one_table) { $foreigners = PMA_getForeigners($this->_db, $one_table); foreach ($foreigners as $key => $foreigner) { if ($key != 'foreign_keys_data') { if (in_array($foreigner['foreign_table'], $candidate_columns)) { $foreign_tables[$foreigner['foreign_table']] = $foreigner['foreign_table']; } continue; } foreach ($foreigner as $one_key) { if (in_array($one_key['ref_table_name'], $candidate_columns)) { $foreign_tables[$one_key['ref_table_name']] = $one_key['ref_table_name']; } } } } if (count($foreign_tables)) { $candidate_columns = $foreign_tables; } // If our array of candidates has more than one member we'll just // find the smallest table. // Of course the actual query would be faster if we check for // the Criteria which gives the smallest result set in its table, // but it would take too much time to check this if (!(count($candidate_columns) > 1)) { // Only one single candidate return reset($candidate_columns); } // Of course we only want to check each table once $checked_tables = $candidate_columns; $tsize = array(); $csize = array(); foreach ($candidate_columns as $table) { if ($checked_tables[$table] != 1) { $_table = new Table($table, $this->_db); $tsize[$table] = $_table->countRecords(); $checked_tables[$table] = 1; } $csize[$table] = $tsize[$table]; } // Return largest table return array_search(max($csize), $csize); }