From 036d70aa8da7ad07333f11e256ba8911e65b6685 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Thu, 11 Jun 2015 12:45:57 +0530 Subject: [PATCH 01/14] All tables are not defined outside Signed-off-by: Madhura Jayaratne --- libraries/DBQbe.class.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index 3873817920..af83e87ec3 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -1385,13 +1385,14 @@ class PMA_DbQbe . PMA_getRelatives($all_tables, $master); } // end if (count($all_tables) > 0) + + // In case relations are not defined, just generate the FROM clause + // from the list of tables, however we don't generate any JOIN + if (empty($from_clause)) { + $from_clause = implode(', ', $all_tables); + } } // end count($_POST['criteriaColumn']) > 0 - // In case relations are not defined, just generate the FROM clause - // from the list of tables, however we don't generate any JOIN - if (empty($from_clause) && isset($all_tables)) { - $from_clause = implode(', ', $all_tables); - } return $from_clause; } From 27c259c7cba58db5bb5840657201a6c47c3564e4 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Thu, 11 Jun 2015 12:58:11 +0530 Subject: [PATCH 02/14] Allow user to chose whether to use joins or not Signed-off-by: Madhura Jayaratne --- libraries/DBQbe.class.php | 44 ++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index af83e87ec3..0e7f8fedd2 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -1370,26 +1370,32 @@ class PMA_DbQbe } } // end while - // Create LEFT JOINS out of Relations - if (count($all_tables) > 0) { - // Get tables and columns with valid where clauses - $valid_where_clauses = $this->_getWhereClauseTablesAndColumns(); - $where_clause_tables = $valid_where_clauses['where_clause_tables']; - $where_clause_columns = $valid_where_clauses['where_clause_columns']; - // Get master table - $master = $this->_getMasterTable( - $all_tables, $all_columns, - $where_clause_columns, $where_clause_tables - ); - $from_clause = PMA_Util::backquote($master) - . PMA_getRelatives($all_tables, $master); + if (isset($_POST['useJoins'])) { + // Create LEFT JOINS out of Relations + if (count($all_tables) > 0) { + // Get tables and columns with valid where clauses + $valid_where_clauses = $this->_getWhereClauseTablesAndColumns(); + $where_clause_tables = $valid_where_clauses['where_clause_tables']; + $where_clause_columns = $valid_where_clauses['where_clause_columns']; + // Get master table + $master = $this->_getMasterTable( + $all_tables, $all_columns, + $where_clause_columns, $where_clause_tables + ); + $from_clause = PMA_Util::backquote($master) + . PMA_getRelatives($all_tables, $master); - } // end if (count($all_tables) > 0) + } // end if (count($all_tables) > 0) + } // In case relations are not defined, just generate the FROM clause // from the list of tables, however we don't generate any JOIN if (empty($from_clause)) { - $from_clause = implode(', ', $all_tables); + $backQuoted = array(); + foreach ($all_tables as $table) { + $backQuoted[] = PMA_Util::backquote($table); + } + $from_clause = implode(', ', $backQuoted); } } // end count($_POST['criteriaColumn']) > 0 @@ -1432,6 +1438,14 @@ class PMA_DbQbe $html_output .= $this->_getSavedSearchesField(); } + $html_output .= '
'; + $html_output .= ''; + $html_output .= ''; // Get table's elements $html_output .= $this->_getColumnNamesRow(); From bdf51f23cd80a8350502691abb6c149787693416 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Thu, 11 Jun 2015 13:05:23 +0530 Subject: [PATCH 03/14] Interchange show and sort rows Signed-off-by: Madhura Jayaratne --- libraries/DBQbe.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index 0e7f8fedd2..85933ff1d4 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -1449,8 +1449,8 @@ class PMA_DbQbe $html_output .= '
'; // Get table's elements $html_output .= $this->_getColumnNamesRow(); - $html_output .= $this->_getSortRow(); $html_output .= $this->_getShowRow(); + $html_output .= $this->_getSortRow(); $html_output .= $this->_getCriteriaInputboxRow(); $html_output .= $this->_getInsDelAndOrCriteriaRows(); $html_output .= $this->_getModifyColumnsRow(); From 7e69d0ff547169c9541fb8ac8b25d7b9dbbb7337 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Thu, 11 Jun 2015 13:29:57 +0530 Subject: [PATCH 04/14] And and Or checkboxes in last column is redundant Signed-off-by: Madhura Jayaratne --- libraries/DBQbe.class.php | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index 85933ff1d4..cb86503205 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -708,20 +708,24 @@ class PMA_DbQbe * * @param integer $column_number Column Number (0,1,2) or more * @param array $selected Selected criteria column name + * @param bool $last_column Whether this is the last column * * @return string HTML for modification cell */ - private function _getAndOrColCell($column_number, $selected = null) - { + private function _getAndOrColCell( + $column_number, $selected = null, $last_column = false + ) { $html_output = '
'; - $html_output .= '' . __('Or:') . ''; - $html_output .= ''; - $html_output .= '  ' . __('And:') . ''; - $html_output .= ''; + if (! $last_column) { + $html_output .= '' . __('Or:') . ''; + $html_output .= ''; + $html_output .= '  ' . __('And:') . ''; + $html_output .= ''; + } $html_output .= '
' . __('Ins'); $html_output .= ''; @@ -779,7 +783,8 @@ class PMA_DbQbe } $html_output .= $this->_getAndOrColCell( $new_column_count, - $checked_options + $checked_options, + ($column_index + 1 == $this->_criteria_column_count) ); $new_column_count++; } // end for From ce304b315709141e1d8df966ae52b0f6d349af6b Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Thu, 11 Jun 2015 13:53:02 +0530 Subject: [PATCH 05/14] Remove database name for consistency Signed-off-by: Madhura Jayaratne --- libraries/relation.lib.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/relation.lib.php b/libraries/relation.lib.php index e10f4a18ad..0d98862591 100644 --- a/libraries/relation.lib.php +++ b/libraries/relation.lib.php @@ -1411,8 +1411,7 @@ function PMA_getRelatives($all_tables, $master) while ($row = $GLOBALS['dbi']->fetchAssoc($relations)) { $found_table = $row[$to . '_table']; if (isset($remaining_tables[$found_table])) { - $left_join_with = PMA_Util::backquote($GLOBALS['db']) . '.' - . PMA_Util::backquote($row[$to . '_table']); + $left_join_with = PMA_Util::backquote($row[$to . '_table']); $on_condition = PMA_Util::backquote($row[$from . '_table']) . '.' . PMA_Util::backquote($row[$from . '_field']) . ' = ' . PMA_Util::backquote($row[$to . '_table']) . '.' @@ -1446,8 +1445,7 @@ function PMA_getRelatives($all_tables, $master) && ($one_key['ref_table_name'] == $master || $one_key['ref_table_name'] == $one_table) ) { - $left_join_with = PMA_Util::backquote($GLOBALS['db']) . '.' - . PMA_Util::backquote($one_table); + $left_join_with = PMA_Util::backquote($one_table); if (! isset($left_joins[$left_join_with])) { $left_joins[$left_join_with] = array( 'left_join_with' =>$left_join_with, From 357f0be26516ccabbefc85d9a252d71d059d8739 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Thu, 11 Jun 2015 14:00:04 +0530 Subject: [PATCH 06/14] Use negation Signed-off-by: Madhura Jayaratne --- libraries/DBQbe.class.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index cb86503205..45f543948a 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -1375,7 +1375,7 @@ class PMA_DbQbe } } // end while - if (isset($_POST['useJoins'])) { + if (! isset($_POST['doNotUseJoins'])) { // Create LEFT JOINS out of Relations if (count($all_tables) > 0) { // Get tables and columns with valid where clauses @@ -1444,12 +1444,13 @@ class PMA_DbQbe } $html_output .= '
'; - $html_output .= ''; + $html_output .= ''; $html_output .= ''; // Get table's elements From 115607abb222c5da8a33c80266582ebba9e14b56 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Thu, 11 Jun 2015 21:27:06 +0530 Subject: [PATCH 07/14] bug #4510 QBE generates wrong query Signed-off-by: Madhura Jayaratne --- ChangeLog | 1 + libraries/DBQbe.class.php | 146 +++++++++++++++++++++++++++++++------ libraries/relation.lib.php | 122 ------------------------------- 3 files changed, 123 insertions(+), 146 deletions(-) diff --git a/ChangeLog b/ChangeLog index eabd055b9a..70d24b3844 100644 --- a/ChangeLog +++ b/ChangeLog @@ -54,6 +54,7 @@ phpMyAdmin - ChangeLog + rfe #1634 Don't group tables in tree if the result has only one group - bug #4946 When hide table structure actions is false, action should be in a row + rfe #726 Batch changing the collation of each column in a table +- bug #4510 QBE generates wrong query 4.4.10.0 (not yet released) - bug #4950 Issues in database selection for replication diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index 45f543948a..b4cac4fbfb 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -1377,36 +1377,134 @@ class PMA_DbQbe if (! isset($_POST['doNotUseJoins'])) { // Create LEFT JOINS out of Relations - if (count($all_tables) > 0) { - // Get tables and columns with valid where clauses - $valid_where_clauses = $this->_getWhereClauseTablesAndColumns(); - $where_clause_tables = $valid_where_clauses['where_clause_tables']; - $where_clause_columns = $valid_where_clauses['where_clause_columns']; - // Get master table - $master = $this->_getMasterTable( - $all_tables, $all_columns, - $where_clause_columns, $where_clause_tables - ); - $from_clause = PMA_Util::backquote($master) - . PMA_getRelatives($all_tables, $master); - - } // end if (count($all_tables) > 0) - } - - // In case relations are not defined, just generate the FROM clause - // from the list of tables, however we don't generate any JOIN - if (empty($from_clause)) { - $backQuoted = array(); - foreach ($all_tables as $table) { - $backQuoted[] = PMA_Util::backquote($table); - } - $from_clause = implode(', ', $backQuoted); + $from_clause = $this->_getJoinForFromClause($all_tables, $all_columns); + } else { + // Create cartesian product + $from_clause = implode(", ", array_map('PMA_Util::backquote', $all_tables)); } } // end count($_POST['criteriaColumn']) > 0 return $from_clause; } + /** + * Formulates the WHERE clause by JOINing tables + * + * @param array $allTables Tables involved in the search + * @param array $allColumns Columns involved in the search + * + * @return string table name + */ + private function _getJoinForFromClause($allTables, $allColumns) { + + // $relations[master_table][foreign_table] => clause + $relations = array(); + + // Fill $relations with inter table relationship data + foreach ($allTables as $oneTable) { + $relations[$oneTable] = array(); + + $foreigners = PMA_getForeigners($GLOBALS['db'], $oneTable); + foreach ($foreigners as $field => $foreigner) { + // Foreign keys data + if ($field == 'foreign_keys_data') { + foreach ($foreigner as $oneKey) { + $clauses = array(); + // There may be multiple column relations + foreach ($oneKey['index_list'] as $index => $oneField) { + $clauses[] = PMA_Util::backquote($oneTable) . "." + . PMA_Util::backquote($oneField) . " = " + . PMA_Util::backquote($oneKey['ref_table_name']) . "." + . PMA_Util::backquote($oneKey['ref_index_list'][$index]); + } + // Combine multiple column relations with AND + $relations[$oneTable][$oneKey['ref_table_name']] + = implode(" AND ", $clauses); + } + } else { // Internal relations + $relations[$oneTable][$foreigner['foreign_table']] + = PMA_Util::backquote($oneTable) . "." + . PMA_Util::backquote($field) . " = " + . PMA_Util::backquote($foreigner['foreign_table']) . "." + . PMA_Util::backquote($foreigner['foreign_field']); + } + } + } + + // 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( + $allTables, $allColumns, + $whereClauseColumns, $whereClauseTables + ); + + // Will incldue master tables and all tables that can be combined into + // a cluster by their relation + $finalized = array(); + // Add master tables + $finalized[$master] = ''; + + while (true) { + $added = false; + foreach ($relations as $masterTable => $foreignData) { + foreach ($foreignData as $foreignTable => $clause) { + if (! isset($finalized[$masterTable]) + && isset($finalized[$foreignTable]) + ) { + $finalized[$masterTable] = $clause; + $added = true; + + // We are done if all tables are in $finalized + if (count($finalized) == count($allTables)) { + break 3; + } + } else if (! isset($finalized[$foreignTable]) + && isset($finalized[$masterTable]) + && in_array($foreignTable, $allTables) + ) { + $finalized[$foreignTable] = $clause; + $added = true; + + // We are done if all tables are in $finalized + if (count($finalized) == count($allTables)) { + break 3; + } + } + } + } + // If no new tables were added during this iteration, break; + if (! $added) { + break; + } + } + + // Tables that can not be combined with the table cluster + // that includes master table + $unfinalized = array_diff($allTables, array_keys($finalized)); + // Add these tables are cartesian product before joined tables + $join = implode(', ', array_map('PMA_Util::backquote', $unfinalized)); + + $first = true; + // Add joined tables + foreach ($finalized as $table => $clause) { + if ($first) { + if (! empty($join)) { + $join .= ", "; + } + $join .= PMA_Util::backquote($table); + $first = false; + } else { + $join .= "\n LEFT JOIN " . PMA_Util::backquote($table) . " ON " . $clause; + } + } + + return $join; + } + /** * Provides the generated SQL query * diff --git a/libraries/relation.lib.php b/libraries/relation.lib.php index 0d98862591..d160ee1cfe 100644 --- a/libraries/relation.lib.php +++ b/libraries/relation.lib.php @@ -1364,128 +1364,6 @@ function PMA_getForeignData( return $foreignData; } // end of 'PMA_getForeignData()' function -/** - * Finds all related tables - * - * @param array $all_tables All the involved tables - * @param string $master The master table to form the LEFT JOIN clause - * - * @return string LEFT JOIN - * @access private - */ -function PMA_getRelatives($all_tables, $master) -{ - $fromclause = ''; - $left_joins = array(); - $emerg = ''; - $ignore_internal_relations = false; - - // The list of tables that we still couldn't connect - $remaining_tables = $all_tables; - unset($remaining_tables[$master]); - // The list of already connected tables - $known_tables = array(); - $known_tables[$master] = $master; - $run = 0; - while ($GLOBALS['cfgRelation']['relwork'] && count($remaining_tables) > 0) { - // Whether to go from master to foreign or vice versa - if ($run % 2 == 0) { - $from = 'master'; - $to = 'foreign'; - } else { - $from = 'foreign'; - $to = 'master'; - } - $in_know = '(\'' . implode('\', \'', $known_tables) . '\')'; - $in_left = '(\'' . implode('\', \'', $remaining_tables) . '\')'; - $rel_query = 'SELECT *' - . ' FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db']) - . '.' . PMA_Util::backquote($GLOBALS['cfgRelation']['relation']) - . ' WHERE ' . $from . '_db = \'' - . PMA_Util::sqlAddSlashes($GLOBALS['db']) . '\'' - . ' AND ' . $to . '_db = \'' - . PMA_Util::sqlAddSlashes($GLOBALS['db']) . '\'' - . ' AND ' . $from . '_table IN ' . $in_know - . ' AND ' . $to . '_table IN ' . $in_left; - $relations = @$GLOBALS['dbi']->query($rel_query, $GLOBALS['controllink']); - while ($row = $GLOBALS['dbi']->fetchAssoc($relations)) { - $found_table = $row[$to . '_table']; - if (isset($remaining_tables[$found_table])) { - $left_join_with = PMA_Util::backquote($row[$to . '_table']); - $on_condition = PMA_Util::backquote($row[$from . '_table']) . '.' - . PMA_Util::backquote($row[$from . '_field']) . ' = ' - . PMA_Util::backquote($row[$to . '_table']) . '.' - . PMA_Util::backquote($row[$to . '_field']); - - $left_joins[$left_join_with] = array( - 'left_join_with' => $left_join_with, - 'on_condition' => array($on_condition) - ); - - $known_tables[$found_table] = $found_table; - unset($remaining_tables[$found_table]); - } - } // end while - $run++; - if ($run > 5) { - foreach ($remaining_tables as $table) { - $emerg .= ', ' . PMA_Util::backquote($table); - unset($remaining_tables[$table]); - } - } - } // end while - - // Generate 'LEFT JOIN's for InnoDB foreign keys. - $remaining_tables = $all_tables; - foreach ($remaining_tables as $one_table) { - $foreigners = PMA_getForeigners($GLOBALS['db'], $one_table, '', 'foreign'); - foreach ($foreigners['foreign_keys_data'] as $one_key) { - if (in_array($one_key['ref_table_name'], $all_tables) - && ! isset($one_key['ref_db_name']) - && ($one_key['ref_table_name'] == $master - || $one_key['ref_table_name'] == $one_table) - ) { - $left_join_with = PMA_Util::backquote($one_table); - if (! isset($left_joins[$left_join_with])) { - $left_joins[$left_join_with] = array( - 'left_join_with' =>$left_join_with, - 'on_condition' => array() - ); - } - - foreach ($one_key['ref_index_list'] as $key => $one_column) { - $on_condition = PMA_Util::backquote($one_key['ref_table_name']) - . '.' . PMA_Util::backquote($one_column) . ' = ' - . PMA_Util::backquote($one_table) . '.' - . PMA_Util::backquote($one_key['index_list'][$key]); - - if (! in_array($on_condition, $left_joins[$left_join_with]['on_condition'])) { - $left_joins[$left_join_with]['on_condition'][] - = $on_condition; - } - } - $ignore_internal_relations = true; - unset($remaining_tables[$one_table]); - } - } - } - - if ($ignore_internal_relations) { - $emerg = ''; - } - - // Build the 'FROM' clause. - foreach ($left_joins as $one_join) { - $fromclause .= "\n" . ' LEFT JOIN ' - . $one_join['left_join_with'] - . ' ON ' - . implode(' AND ', $one_join['on_condition']); - } - - $fromclause = $emerg . $fromclause; - return $fromclause; -} // end of the "PMA_getRelatives()" function - /** * Rename a field in relation tables * From 4b9ef9db9f3830622657b533e478ab2915d2cd2b Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Fri, 12 Jun 2015 05:39:42 +0530 Subject: [PATCH 08/14] Fix failing tests Signed-off-by: Madhura Jayaratne --- test/classes/PMA_DBQbe_test.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/classes/PMA_DBQbe_test.php b/test/classes/PMA_DBQbe_test.php index c84f337c6e..c93e8fc906 100644 --- a/test/classes/PMA_DBQbe_test.php +++ b/test/classes/PMA_DBQbe_test.php @@ -272,10 +272,7 @@ class PMA_DBQbe_Test extends PHPUnit_Framework_TestCase . '
Ins  Del
', $this->_callProtectedFunction( From 2a0397dd33d0c299d7659d0c4675129307a54e3d Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Fri, 12 Jun 2015 06:23:51 +0530 Subject: [PATCH 09/14] Remove the choice to select whether or not to use joins. Reverts 27c259c and 357f0be Signed-off-by: Madhura Jayaratne --- libraries/DBQbe.class.php | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index b4cac4fbfb..7c52c206c9 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -1375,10 +1375,12 @@ class PMA_DbQbe } } // end while - if (! isset($_POST['doNotUseJoins'])) { - // Create LEFT JOINS out of Relations - $from_clause = $this->_getJoinForFromClause($all_tables, $all_columns); - } else { + // Create LEFT JOINS out of Relations + $from_clause = $this->_getJoinForFromClause($all_tables, $all_columns); + + // In case relations are not defined, just generate the FROM clause + // from the list of tables, however we don't generate any JOIN + if (empty($from_clause)) { // Create cartesian product $from_clause = implode(", ", array_map('PMA_Util::backquote', $all_tables)); } @@ -1541,15 +1543,6 @@ class PMA_DbQbe $html_output .= $this->_getSavedSearchesField(); } - $html_output .= '
'; - $html_output .= ''; - $html_output .= '
Or:' - . '  And:
Ins

Ins  Del' . '
'; // Get table's elements $html_output .= $this->_getColumnNamesRow(); From ab6b617e979f2fbeed5989751dc700bdf3143c2f Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Fri, 12 Jun 2015 07:27:51 +0530 Subject: [PATCH 10/14] Introduce aliases Signed-off-by: Madhura Jayaratne --- libraries/DBQbe.class.php | 65 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index 7c52c206c9..1c8c27d2ec 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -128,6 +128,13 @@ class PMA_DbQbe * @var array */ private $_curField; + /** + * Current alias + * + * @access private + * @var array + */ + private $_curAlias; /** * Current criteria Sort options * @@ -444,6 +451,54 @@ class PMA_DbQbe return $html_output; } + private function _getColumnAliasRow() + { + $html_output = ''; + $html_output .= ''; + $new_column_count = 0; + + for ( + $colInd = 0; + $colInd < $this->_criteria_column_count; + $colInd++ + ) { + if (! empty($this->_criteriaColumnInsert) + && isset($this->_criteriaColumnInsert[$colInd]) + && $this->_criteriaColumnInsert[$colInd] == 'on' + ) { + $html_output .= ''; + $new_column_count++; + } // end if + + if (! empty($this->_criteriaColumnDelete) + && isset($this->_criteriaColumnDelete[$colInd]) + && $this->_criteriaColumnDelete[$colInd] == 'on' + ) { + continue; + } + + $tmp_alias = ''; + if (! empty($_REQUEST['criteriaAlias'][$colInd])) { + $tmp_alias + = $this->_curAlias[$new_column_count] + = $_REQUEST['criteriaAlias'][$colInd]; + }// end if + + $html_output .= ''; + $new_column_count++; + } // end for + $html_output .= ''; + return $html_output; + } + /** * Provides search form's row containing sort(ASC/DESC) select options * @@ -983,7 +1038,12 @@ class PMA_DbQbe && isset($this->_curShow[$column_index]) && $this->_curShow[$column_index] == 'on' ) { - $select_clauses[] = $this->_curField[$column_index]; + $select = $this->_curField[$column_index]; + if (! empty($this->_curAlias[$column_index])) { + $select .= " AS " + . PMA_Util::backquote($this->_curAlias[$column_index]); + } + $select_clauses[] = $select; } } // end for if ($select_clauses) { @@ -1487,7 +1547,7 @@ class PMA_DbQbe // Tables that can not be combined with the table cluster // that includes master table $unfinalized = array_diff($allTables, array_keys($finalized)); - // Add these tables are cartesian product before joined tables + // Add these tables as cartesian product before joined tables $join = implode(', ', array_map('PMA_Util::backquote', $unfinalized)); $first = true; @@ -1546,6 +1606,7 @@ class PMA_DbQbe $html_output .= '
' . __('Alias:') . ''; + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + $html_output .= '
'; // Get table's elements $html_output .= $this->_getColumnNamesRow(); + $html_output .= $this->_getColumnAliasRow(); $html_output .= $this->_getShowRow(); $html_output .= $this->_getSortRow(); $html_output .= $this->_getCriteriaInputboxRow(); From 401dbb1918afb71f2c5b534fbb925887eaec7b32 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Fri, 12 Jun 2015 10:36:16 +0530 Subject: [PATCH 11/14] Allow ordering order by clauses Signed-off-by: Madhura Jayaratne --- libraries/DBQbe.class.php | 148 ++++++++++++++++++++++++++++++++------ 1 file changed, 125 insertions(+), 23 deletions(-) diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index 1c8c27d2ec..a0cccacbd8 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -142,6 +142,13 @@ class PMA_DbQbe * @var array */ private $_curSort; + /** + * Current criteria sort order + * + * @access private + * @var array + */ + private $_curSortOrder; /** * Current criteria Show options * @@ -405,6 +412,40 @@ class PMA_DbQbe return $html_output; } + /** + * Provides select options list containing sort order + * + * @param integer $columnNumber Column Number (0,1,2) or more + * @param integer $sortOrder Sort order + * + * @return string HTML for select options + */ + private function _getSortOrderSelectCell($columnNumber, $sortOrder) + { + $totalColumnCount = $this->_criteria_column_count; + if (! empty($this->_criteriaColumnInsert)) { + $totalColumnCount += count($this->_criteriaColumnInsert); + } + if (! empty($this->_criteriaColumnDelete)) { + $totalColumnCount -= count($this->_criteriaColumnDelete); + } + + $html_output = ''; + return $html_output; + } + /** * Provides search form's row containing column select options * @@ -451,6 +492,11 @@ class PMA_DbQbe return $html_output; } + /** + * Provides search form's row containing column aliases + * + * @return string HTML for search table's row + */ private function _getColumnAliasRow() { $html_output = ''; @@ -537,26 +583,23 @@ class PMA_DbQbe ) { $_REQUEST['criteriaSort'][$colInd] = ''; } //end if - // Set asc_selected - if (isset($_REQUEST['criteriaSort'][$colInd]) - && $_REQUEST['criteriaSort'][$colInd] == 'ASC' - ) { + + $asc_selected = ''; $desc_selected = ''; + if (isset($_REQUEST['criteriaSort'][$colInd])) { $this->_curSort[$new_column_count] = $_REQUEST['criteriaSort'][$colInd]; - $asc_selected = ' selected="selected"'; + // Set asc_selected + if ($_REQUEST['criteriaSort'][$colInd] == 'ASC') { + $asc_selected = ' selected="selected"'; + } // end if + // Set desc selected + if ($_REQUEST['criteriaSort'][$colInd] == 'DESC') { + $desc_selected = ' selected="selected"'; + } // end if } else { - $asc_selected = ''; - } // end if - // Set desc selected - if (isset($_REQUEST['criteriaSort'][$colInd]) - && $_REQUEST['criteriaSort'][$colInd] == 'DESC' - ) { - $this->_curSort[$new_column_count] - = $_REQUEST['criteriaSort'][$colInd]; - $desc_selected = ' selected="selected"'; - } else { - $desc_selected = ''; - } // end if + $this->_curSort[$new_column_count] = ''; + } + $html_output .= $this->_getSortSelectCell( $new_column_count, $asc_selected, $desc_selected ); @@ -566,6 +609,55 @@ class PMA_DbQbe return $html_output; } + /** + * Provides search form's row containing sort order + * + * @return string HTML for search table's row + */ + private function _getSortOrder() + { + $html_output = ''; + $html_output .= ''; + $new_column_count = 0; + + for ( + $colInd = 0; + $colInd < $this->_criteria_column_count; + $colInd++ + ) { + if (! empty($this->_criteriaColumnInsert) + && isset($this->_criteriaColumnInsert[$colInd]) + && $this->_criteriaColumnInsert[$colInd] == 'on' + ) { + $html_output .= $this->_getSortOrderSelectCell( + $new_column_count, null + ); + $new_column_count++; + } // end if + + if (! empty($this->_criteriaColumnDelete) + && isset($this->_criteriaColumnDelete[$colInd]) + && $this->_criteriaColumnDelete[$colInd] == 'on' + ) { + continue; + } + + $sortOrder = null; + if (! empty($_REQUEST['criteriaSortOrder'][$colInd])) { + $sortOrder + = $this->_curSortOrder[$new_column_count] + = $_REQUEST['criteriaSortOrder'][$colInd]; + } + + $html_output .= $this->_getSortOrderSelectCell( + $new_column_count, $sortOrder + ); + $new_column_count++; + } // end for + $html_output .= ''; + return $html_output; + } + /** * Provides search form's row containing SHOW checkboxes * @@ -1157,6 +1249,15 @@ class PMA_DbQbe $orderby_clause = ''; $orderby_clauses = array(); + // Create copy of instance variables + $field = $this->_curField; + $sort = $this->_curSort; + $sortOrder = $this->_curSortOrder; + if (count($field) == count($sort) && count($field) == count($sortOrder)) { + // Sort all three arrays based on sort order + array_multisort($sortOrder, $sort, $field); + } + for ( $column_index = 0; $column_index < $this->_criteria_column_count; @@ -1165,19 +1266,19 @@ class PMA_DbQbe // if all columns are chosen with * selector, // then sorting isn't available // Fix for Bug #570698 - if (empty($this->_curField[$column_index]) - && empty($this->_curSort[$column_index]) + if (empty($field[$column_index]) + && empty($sort[$column_index]) ) { continue; } - if (/*overload*/mb_substr($this->_curField[$column_index], -2) == '.*') { + if (/*overload*/mb_substr($field[$column_index], -2) == '.*') { continue; } - if (! empty($this->_curSort[$column_index])) { - $orderby_clauses[] = $this->_curField[$column_index] . ' ' - . $this->_curSort[$column_index]; + if (! empty($sort[$column_index])) { + $orderby_clauses[] = $field[$column_index] . ' ' + . $sort[$column_index]; } } // end for if ($orderby_clauses) { @@ -1609,6 +1710,7 @@ class PMA_DbQbe $html_output .= $this->_getColumnAliasRow(); $html_output .= $this->_getShowRow(); $html_output .= $this->_getSortRow(); + $html_output .= $this->_getSortOrder(); $html_output .= $this->_getCriteriaInputboxRow(); $html_output .= $this->_getInsDelAndOrCriteriaRows(); $html_output .= $this->_getModifyColumnsRow(); From ab9a8bdd254022841abb228f6e67798c9f2e32b1 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Fri, 12 Jun 2015 11:58:50 +0530 Subject: [PATCH 12/14] Do array multi sort only when sort order is defined Signed-off-by: Madhura Jayaratne --- libraries/DBQbe.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index a0cccacbd8..7befec0503 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -1253,7 +1253,10 @@ class PMA_DbQbe $field = $this->_curField; $sort = $this->_curSort; $sortOrder = $this->_curSortOrder; - if (count($field) == count($sort) && count($field) == count($sortOrder)) { + if ($sortOrder + && count($sortOrder) == count($sort) + && count($sortOrder) == count($field) + ) { // Sort all three arrays based on sort order array_multisort($sortOrder, $sort, $field); } From 8dacdd198e6bf0ec8dcd73b332fb79654d28fac1 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Fri, 12 Jun 2015 18:24:47 +0530 Subject: [PATCH 13/14] Move the column count obtaining logic to a separate method Signed-off-by: Madhura Jayaratne --- libraries/DBQbe.class.php | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/libraries/DBQbe.class.php b/libraries/DBQbe.class.php index 7befec0503..16329f4636 100644 --- a/libraries/DBQbe.class.php +++ b/libraries/DBQbe.class.php @@ -422,14 +422,7 @@ class PMA_DbQbe */ private function _getSortOrderSelectCell($columnNumber, $sortOrder) { - $totalColumnCount = $this->_criteria_column_count; - if (! empty($this->_criteriaColumnInsert)) { - $totalColumnCount += count($this->_criteriaColumnInsert); - } - if (! empty($this->_criteriaColumnDelete)) { - $totalColumnCount -= count($this->_criteriaColumnDelete); - } - + $totalColumnCount = $this->_getNewColumnCount(); $html_output = '
'; + $html_output .= ''; + $html_output .= '
' . __('Sort order:') . '
'; $html_output .= '