} $header_cells = PMA_getHeaderCells($is_backup, isset($fields_meta) ? $fields_meta : null, $cfgRelation['mimework'], $db, $table); // workaround for field_fulltext, because its submitted indices contain // the index as a value, not a key. Inserted here for easier maintenance // and less code to change in existing files. if (isset($field_fulltext) && is_array($field_fulltext)) { foreach ($field_fulltext as $fulltext_nr => $fulltext_indexkey) { $submit_fulltext[$fulltext_indexkey] = $fulltext_indexkey; } } if (isset($_REQUEST['submit_num_fields'])) { //if adding new fields, set regenerate to keep the original values $regenerate = 1; } $foreigners = PMA_getForeigners($db, $table, '', 'foreign'); $child_references = PMA_getChildReferences($db, $table); for ($columnNumber = 0; $columnNumber < $num_fields; $columnNumber++) { if (!empty($regenerate)) { list($columnMeta, $submit_length, $submit_attribute, $submit_default_current_timestamp, $comments_map, $mime_map) = PMA_handleRegeneration($columnNumber, isset($available_mime) ? $mime_map : null, $comments_map, $mime_map); } elseif (isset($fields_meta[$columnNumber])) { $columnMeta = PMA_getColumnMetaForDefault($fields_meta[$columnNumber], isset($analyzed_sql[0]['create_table_fields'][$fields_meta[$columnNumber]['Field']]['default_value'])); } if (isset($columnMeta['Type'])) { $extracted_columnspec = PMA_Util::extractColumnSpec($columnMeta['Type']); if ($extracted_columnspec['type'] == 'bit') { $columnMeta['Default'] = PMA_Util::convertBitDefaultValue($columnMeta['Default']); } $type = $extracted_columnspec['type']; $length = $extracted_columnspec['spec_in_brackets']; } else { // creating a column
/** * Formulates the WHERE clause by JOINing tables * * @param array $searchTables Tables involved in the search * @param array $searchColumns Columns involved in the search * * @return string table name */ private function _getJoinForFromClause($searchTables, $searchColumns) { // $relations[master_table][foreign_table] => clause $relations = array(); // Fill $relations with inter table relationship data foreach ($searchTables as $oneTable) { $this->_loadRelationsForTable($relations, $oneTable); } // Get tables and columns with valid where clauses $validWhereClauses = $this->_getWhereClauseTablesAndColumns(); $whereClauseTables = $validWhereClauses['where_clause_tables']; $whereClauseColumns = $validWhereClauses['where_clause_columns']; // Get master table $master = $this->_getMasterTable($searchTables, $searchColumns, $whereClauseColumns, $whereClauseTables); // Will include master tables and all tables that can be combined into // a cluster by their relation $finalized = array(); if (mb_strlen($master) > 0) { // Add master tables $finalized[$master] = ''; } // Fill the $finalized array with JOIN clauses for each table $this->_fillJoinClauses($finalized, $relations, $searchTables); // JOIN clause $join = ''; // Tables that can not be combined with the table cluster // which includes master table $unfinalized = array_diff($searchTables, array_keys($finalized)); if (count($unfinalized) > 0) { // We need to look for intermediary tables to JOIN unfinalized tables // Heuristic to chose intermediary tables is to look for tables // having relationships with unfinalized tables foreach ($unfinalized as $oneTable) { $references = PMA_getChildReferences($this->_db, $oneTable); foreach ($references as $column => $columnReferences) { foreach ($columnReferences as $reference) { // Only from this schema if ($reference['table_schema'] != $this->_db) { continue; } $table = $reference['table_name']; $this->_loadRelationsForTable($relations, $table); // Make copies $tempFinalized = $finalized; $tempSearchTables = $searchTables; $tempSearchTables[] = $table; // Try joining with the added table $this->_fillJoinClauses($tempFinalized, $relations, $tempSearchTables); $tempUnfinalized = array_diff($tempSearchTables, array_keys($tempFinalized)); // Take greedy approach. // If the unfinalized count drops we keep the new table // and switch temporary varibles with the original ones if (count($tempUnfinalized) < count($unfinalized)) { $finalized = $tempFinalized; $searchTables = $tempSearchTables; } // We are done if no unfinalized tables anymore if (count($tempUnfinalized) == 0) { break 3; } } } } $unfinalized = array_diff($searchTables, array_keys($finalized)); // If there are still unfinalized tables if (count($unfinalized) > 0) { // Add these tables as cartesian product before joined tables $join .= implode(', ', array_map('Util::backquote', $unfinalized)); } } $first = true; // Add joined tables foreach ($finalized as $table => $clause) { if ($first) { if (!empty($join)) { $join .= ", "; } $join .= Util::backquote($table); $first = false; } else { $join .= "\n LEFT JOIN " . Util::backquote($table) . " ON " . $clause; } } return $join; }
/** * Check child table references and foreign key for a table column. * * @param string $db name of master table db. * @param string $table name of master table. * @param string $column name of master table column. * @param array $foreigners_full foreiners array for the whole table. * @param array $child_references_full child references for the whole table. * * @return array $column_status telling about references if foreign key. */ function PMA_checkChildForeignReferences($db, $table, $column, $foreigners_full = null, $child_references_full = null) { $column_status = array(); $column_status['isEditable'] = false; $column_status['isReferenced'] = false; $column_status['isForeignKey'] = false; $column_status['references'] = array(); $foreigners = array(); if ($foreigners_full !== null) { if (isset($foreigners_full[$column])) { $foreigners[$column] = $foreigners_full[$column]; } if (isset($foreigners_full['foreign_keys_data'])) { $foreigners['foreign_keys_data'] = $foreigners_full['foreign_keys_data']; } } else { $foreigners = PMA_getForeigners($db, $table, $column, 'foreign'); } $foreigner = PMA_searchColumnInForeigners($foreigners, $column); $child_references = array(); if ($child_references_full !== null) { if (isset($child_references_full[$column])) { $child_references = $child_references_full[$column]; } } else { $child_references = PMA_getChildReferences($db, $table, $column); } if (sizeof($child_references, 0) > 0 || $foreigner) { if (sizeof($child_references, 0) > 0) { $column_status['isReferenced'] = true; foreach ($child_references as $row => $columns) { array_push($column_status['references'], PMA_Util::backquote($columns['table_schema']) . '.' . PMA_Util::backquote($columns['table_name'])); } } if ($foreigner) { $column_status['isForeignKey'] = true; } } else { $column_status['isEditable'] = true; } return $column_status; }
/** * Check child table references and foreign key for a table column. * * @param string $db name of master table db. * @param string $table name of master table. * @param string $column name of master table column. * * @return array $column_status telling about references if foreign key. */ function PMA_checkChildForeignReferences($db, $table, $column) { $column_status = array(); $column_status['isEditable'] = false; $column_status['isReferenced'] = false; $column_status['isForeignKey'] = false; $column_status['references'] = array(); $foreigners = PMA_getForeigners($db, $table, $column); $child_references = PMA_getChildReferences($db, $table, $column); if (sizeof($child_references, 0) > 0 || sizeof($foreigners[$column], 0) > 0) { if (sizeof($child_references, 0) > 0) { $column_status['isReferenced'] = true; foreach ($child_references as $row => $columns) { array_push($column_status['references'], PMA_Util::backquote($columns['table_schema']) . '.' . PMA_Util::backquote($columns['table_name'])); } } if (sizeof($foreigners[$column], 0) > 0) { $column_status['isForeignKey'] = true; } } else { $column_status['isEditable'] = true; } return $column_status; }