added japanese language
[openemr.git] / phpmyadmin / libraries / sql.lib.php
blobd42555ce4e6f5b8f0f238c3b70ee995681640bc2
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * set of functions for the sql executor
6 * @package PhpMyAdmin
7 */
8 if (!defined('PHPMYADMIN')) {
9 exit;
12 /**
13 * Get the database name inside a query
15 * @param string $sql SQL query
16 * @param array $databases array with all databases
18 * @return string $db new database name
20 function PMA_getNewDatabase($sql, $databases)
22 $db = '';
23 // loop through all the databases
24 foreach ($databases as $database) {
25 if (strpos($sql, $database['SCHEMA_NAME']) !== false) {
26 $db = $database['SCHEMA_NAME'];
27 break;
30 return $db;
33 /**
34 * Get the table name in a sql query
35 * If there are several tables in the SQL query,
36 * first table wil lreturn
38 * @param string $sql SQL query
39 * @param array $tables array of names in current database
41 * @return string $table table name
43 function PMA_getTableNameBySQL($sql, $tables)
45 $table = '';
47 // loop through all the tables in the database
48 foreach ($tables as $tbl) {
49 if (strpos($sql, $tbl)) {
50 $table .= ' ' . $tbl;
54 if (count(explode(' ', trim($table))) > 1) {
55 $tmp_array = explode(' ', trim($table));
56 return $tmp_array[0];
59 return trim($table);
63 /**
64 * Generate table html when SQL statement have multiple queries
65 * which return displayable results
67 * @param object $displayResultsObject PMA_DisplayResults object
68 * @param string $db database name
69 * @param array $sql_data information about SQL statement
70 * @param string $goto URL to go back in case of errors
71 * @param string $pmaThemeImage path for theme images directory
72 * @param string $printview whether printview is enabled
73 * @param string $url_query URL query
74 * @param array $disp_mode the display mode
75 * @param string $sql_limit_to_append limit clause
76 * @param bool $editable whether editable or not
78 * @return string $table_html html content
80 function PMA_getTableHtmlForMultipleQueries(
81 $displayResultsObject, $db, $sql_data, $goto, $pmaThemeImage,
82 $printview, $url_query, $disp_mode, $sql_limit_to_append,
83 $editable
84 ) {
85 $table_html = '';
87 $tables_array = $GLOBALS['dbi']->getTables($db);
88 $databases_array = $GLOBALS['dbi']->getDatabasesFull();
89 $multi_sql = implode(";", $sql_data['valid_sql']);
90 $querytime_before = array_sum(explode(' ', microtime()));
92 // Assignment for variable is not needed since the results are
93 // looping using the connection
94 @$GLOBALS['dbi']->tryMultiQuery($multi_sql);
96 $querytime_after = array_sum(explode(' ', microtime()));
97 $querytime = $querytime_after - $querytime_before;
98 $sql_no = 0;
100 do {
101 $analyzed_sql = array();
102 $is_affected = false;
104 $result = $GLOBALS['dbi']->storeResult();
105 $fields_meta = ($result !== false)
106 ? $GLOBALS['dbi']->getFieldsMeta($result)
107 : array();
108 $fields_cnt = count($fields_meta);
110 // Initialize needed params related to each query in multiquery statement
111 if (isset($sql_data['valid_sql'][$sql_no])) {
112 // 'Use' query can change the database
113 if (stripos($sql_data['valid_sql'][$sql_no], "use ")) {
114 $db = PMA_getNewDatabase(
115 $sql_data['valid_sql'][$sql_no],
116 $databases_array
120 $table = PMA_getTableNameBySQL(
121 $sql_data['valid_sql'][$sql_no],
122 $tables_array
125 // for the use of the parse_analyze.inc.php
126 $sql_query = $sql_data['valid_sql'][$sql_no];
128 // Parse and analyze the query
129 include 'libraries/parse_analyze.inc.php';
131 $unlim_num_rows = PMA_Table::countRecords($db, $table, true);
132 $showtable = PMA_Table::sGetStatusInfo($db, $table, null, true);
133 $url_query = PMA_URL_getCommon($db, $table);
135 // Handle remembered sorting order, only for single table query
136 if ($GLOBALS['cfg']['RememberSorting']
137 && ! ($is_count || $is_export || $is_func || $is_analyse)
138 && isset($analyzed_sql[0]['select_expr'])
139 && (count($analyzed_sql[0]['select_expr']) == 0)
140 && isset($analyzed_sql[0]['queryflags']['select_from'])
141 && count($analyzed_sql[0]['table_ref']) == 1
143 PMA_handleSortOrder(
144 $db,
145 $table,
146 $analyzed_sql,
147 $sql_data['valid_sql'][$sql_no]
151 // Do append a "LIMIT" clause?
152 if (($_SESSION['tmpval']['max_rows'] != 'all')
153 && ! ($is_count || $is_export || $is_func || $is_analyse)
154 && isset($analyzed_sql[0]['queryflags']['select_from'])
155 && ! isset($analyzed_sql[0]['queryflags']['offset'])
156 && empty($analyzed_sql[0]['limit_clause'])
158 $sql_limit_to_append = ' LIMIT '
159 . $_SESSION['tmpval']['pos']
160 . ', ' . $_SESSION['tmpval']['max_rows'] . " ";
161 $sql_data['valid_sql'][$sql_no] = PMA_getSqlWithLimitClause(
162 $sql_data['valid_sql'][$sql_no],
163 $analyzed_sql,
164 $sql_limit_to_append
168 // Set the needed properties related to executing sql query
169 $displayResultsObject->__set('db', $db);
170 $displayResultsObject->__set('table', $table);
171 $displayResultsObject->__set('goto', $goto);
174 if (! $is_affected) {
175 $num_rows = ($result) ? @$GLOBALS['dbi']->numRows($result) : 0;
176 } elseif (! isset($num_rows)) {
177 $num_rows = @$GLOBALS['dbi']->affectedRows();
180 if (isset($sql_data['valid_sql'][$sql_no])) {
182 $displayResultsObject->__set(
183 'sql_query',
184 $sql_data['valid_sql'][$sql_no]
186 $displayResultsObject->setProperties(
187 $unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
188 $is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage,
189 $GLOBALS['text_dir'], $is_maint, $is_explain, $is_show,
190 $showtable, $printview, $url_query, $editable
194 if ($num_rows == 0) {
195 continue;
198 // With multiple results, operations are limied
199 $disp_mode = 'nnnn000000';
200 $is_limited_display = true;
202 // Collect the tables
203 $table_html .= $displayResultsObject->getTable(
204 $result, $disp_mode, $analyzed_sql, $is_limited_display
207 // Free the result to save the memory
208 $GLOBALS['dbi']->freeResult($result);
210 $sql_no++;
212 } while ($GLOBALS['dbi']->moreResults() && $GLOBALS['dbi']->nextResult());
214 return $table_html;
218 * Handle remembered sorting order, only for single table query
220 * @param string $db database name
221 * @param string $table table name
222 * @param array &$analyzed_sql_results the analyzed query results
223 * @param string &$full_sql_query SQL query
225 * @return void
227 function PMA_handleSortOrder(
228 $db, $table, &$analyzed_sql_results, &$full_sql_query
230 $pmatable = new PMA_Table($table, $db);
231 if (empty($analyzed_sql_results['analyzed_sql'][0]['order_by_clause'])) {
232 $sorted_col = $pmatable->getUiProp(PMA_Table::PROP_SORTED_COLUMN);
233 if ($sorted_col) {
234 //remove the tablename from retrieved preference
235 //to get just the column name and the sort order
236 $sorted_col = str_replace(
237 PMA_Util::backquote($table) . '.', '', $sorted_col
239 // retrieve the remembered sorting order for current table
240 $sql_order_to_append = ' ORDER BY ' . $sorted_col . ' ';
241 $full_sql_query
242 = $analyzed_sql_results['analyzed_sql'][0]['section_before_limit']
243 . $sql_order_to_append
244 . $analyzed_sql_results['analyzed_sql'][0]['limit_clause']
245 . ' '
246 . $analyzed_sql_results['analyzed_sql'][0]['section_after_limit'];
248 // update the $analyzed_sql
249 $analyzed_sql_results['analyzed_sql'][0]['section_before_limit']
250 .= $sql_order_to_append;
251 $analyzed_sql_results['analyzed_sql'][0]['order_by_clause']
252 = $sorted_col;
254 } else {
255 // store the remembered table into session
256 $pmatable->setUiProp(
257 PMA_Table::PROP_SORTED_COLUMN,
258 $analyzed_sql_results['analyzed_sql'][0]['order_by_clause']
264 * Append limit clause to SQL query
266 * @param string $full_sql_query SQL query
267 * @param array $analyzed_sql the analyzed query
268 * @param string $sql_limit_to_append clause to append
270 * @return string limit clause appended SQL query
272 function PMA_getSqlWithLimitClause($full_sql_query, $analyzed_sql,
273 $sql_limit_to_append
275 return $analyzed_sql[0]['section_before_limit'] . "\n"
276 . $sql_limit_to_append . $analyzed_sql[0]['section_after_limit'];
281 * Get column name from a drop SQL statement
283 * @param string $sql SQL query
285 * @return string $drop_column Name of the column
287 function PMA_getColumnNameInColumnDropSql($sql)
289 $tmpArray1 = explode('DROP', $sql);
290 $str_to_check = trim($tmpArray1[1]);
292 if (stripos($str_to_check, 'COLUMN') !== false) {
293 $tmpArray2 = explode('COLUMN', $str_to_check);
294 $str_to_check = trim($tmpArray2[1]);
297 $tmpArray3 = explode(' ', $str_to_check);
298 $str_to_check = trim($tmpArray3[0]);
300 $drop_column = str_replace(';', '', trim($str_to_check));
301 $drop_column = str_replace('`', '', $drop_column);
303 return $drop_column;
307 * Verify whether the result set has columns from just one table
309 * @param array $fields_meta meta fields
311 * @return boolean whether the result set has columns from just one table
313 function PMA_resultSetHasJustOneTable($fields_meta)
315 $just_one_table = true;
316 $prev_table = $fields_meta[0]->table;
317 foreach ($fields_meta as $one_field_meta) {
318 if (! empty($one_field_meta->table)
319 && $one_field_meta->table != $prev_table
321 $just_one_table = false;
322 break;
325 return $just_one_table;
329 * Verify whether the result set contains all the columns
330 * of at least one unique key
332 * @param string $db database name
333 * @param string $table table name
334 * @param array $fields_meta meta fields
336 * @return boolean whether the result set contains a unique key
338 function PMA_resultSetContainsUniqueKey($db, $table, $fields_meta)
340 $resultSetColumnNames = array();
341 foreach ($fields_meta as $oneMeta) {
342 $resultSetColumnNames[] = $oneMeta->name;
344 foreach (PMA_Index::getFromTable($table, $db) as $index) {
345 if ($index->isUnique()) {
346 $indexColumns = $index->getColumns();
347 $numberFound = 0;
348 foreach ($indexColumns as $indexColumnName => $dummy) {
349 if (in_array($indexColumnName, $resultSetColumnNames)) {
350 $numberFound++;
353 if ($numberFound == count($indexColumns)) {
354 return true;
358 return false;
362 * Get the HTML for relational column dropdown
363 * During grid edit, if we have a relational field, returns the html for the
364 * dropdown
366 * @param string $db current database
367 * @param string $table current table
368 * @param string $column current column
369 * @param string $curr_value current selected value
371 * @return string $dropdown html for the dropdown
373 function PMA_getHtmlForRelationalColumnDropdown($db, $table, $column, $curr_value)
375 $foreigners = PMA_getForeigners($db, $table, $column);
377 $foreignData = PMA_getForeignData($foreigners, $column, false, '', '');
379 if ($foreignData['disp_row'] == null) {
380 //Handle the case when number of values
381 //is more than $cfg['ForeignKeyMaxLimit']
382 $_url_params = array(
383 'db' => $db,
384 'table' => $table,
385 'field' => $column
388 $dropdown = '<span class="curr_value">'
389 . htmlspecialchars($_REQUEST['curr_value'])
390 . '</span>'
391 . '<a href="browse_foreigners.php'
392 . PMA_URL_getCommon($_url_params) . '"'
393 . ' target="_blank" class="browse_foreign" ' . '>'
394 . __('Browse foreign values')
395 . '</a>';
396 } else {
397 $dropdown = PMA_foreignDropdown(
398 $foreignData['disp_row'],
399 $foreignData['foreign_field'],
400 $foreignData['foreign_display'],
401 $curr_value,
402 $GLOBALS['cfg']['ForeignKeyMaxLimit']
404 $dropdown = '<select>' . $dropdown . '</select>';
407 return $dropdown;
411 * Get the HTML for the header of the page in print view if print view is selected.
412 * Otherwise returns null.
414 * @param string $db current database
415 * @param string $sql_query current sql query
416 * @param int $num_rows the number of rows in result
418 * @return string $header html for the header
420 function PMA_getHtmlForPrintViewHeader($db, $sql_query, $num_rows)
422 $response = PMA_Response::getInstance();
423 $header = $response->getHeader();
424 if (isset($_REQUEST['printview']) && $_REQUEST['printview'] == '1') {
425 PMA_Util::checkParameters(array('db', 'sql_query'));
426 $header->enablePrintView();
427 $hostname = '';
428 if ( $GLOBALS['cfg']['Server']['verbose']) {
429 $hostname = $GLOBALS['cfg']['Server']['verbose'];
430 } else {
431 $hostname = $GLOBALS['cfg']['Server']['host'];
432 if (! empty( $GLOBALS['cfg']['Server']['port'])) {
433 $hostname .= $GLOBALS['cfg']['Server']['port'];
437 $versions = "phpMyAdmin&nbsp;" . PMA_VERSION;
438 $versions .= "&nbsp;/&nbsp;";
439 $versions .= "MySQL&nbsp;" . PMA_MYSQL_STR_VERSION;
441 $print_view_header = '';
442 $print_view_header .= "<h1>" . __('SQL result') . "</h1>";
443 $print_view_header .= "<p>";
444 $print_view_header .= "<strong>" . __('Host:')
445 . "</strong> $hostname<br />";
446 $print_view_header .= "<strong>" . __('Database:') . "</strong> "
447 . htmlspecialchars($db) . "<br />";
448 $print_view_header .= "<strong>" . __('Generation Time:') . "</strong> "
449 . PMA_Util::localisedDate() . "<br />";
450 $print_view_header .= "<strong>" . __('Generated by:')
451 . "</strong> $versions<br />";
452 $print_view_header .= "<strong>" . __('SQL query:') . "</strong> "
453 . htmlspecialchars($sql_query) . ";";
454 if (isset($num_rows)) {
455 $print_view_header .= "<br />";
456 $print_view_header .= "<strong>" . __('Rows:') . "</strong> $num_rows";
458 $print_view_header .= "</p>";
459 } else {
460 $print_view_header = null;
463 return $print_view_header;
467 * Get the HTML for the profiling table and accompanying chart if profiling is set.
468 * Otherwise returns null
470 * @param string $url_query url query
471 * @param string $db current database
472 * @param array $profiling_results array containing the profiling info
474 * @return string $profiling_table html for the profiling table and chart
476 function PMA_getHtmlForProfilingChart($url_query, $db, $profiling_results)
478 if (isset($profiling_results)) {
479 $pma_token = $_SESSION[' PMA_token '];
480 $url_query = (isset($url_query) ? $url_query : PMA_URL_getCommon($db));
482 $profiling_table = '';
483 $profiling_table .= '<fieldset><legend>' . __('Profiling')
484 . '</legend>' . "\n";
485 $profiling_table .= '<div style="float: left;">';
486 $profiling_table .= '<h3>' . __('Detailed profile') . '</h3>';
487 $profiling_table .= '<table id="profiletable"><thead>' . "\n";
488 $profiling_table .= ' <tr>' . "\n";
489 $profiling_table .= ' <th>' . __('Order')
490 . '<div class="sorticon"></div></th>' . "\n";
491 $profiling_table .= ' <th>' . __('State')
492 . PMA_Util::showMySQLDocu('general-thread-states')
493 . '<div class="sorticon"></div></th>' . "\n";
494 $profiling_table .= ' <th>' . __('Time')
495 . '<div class="sorticon"></div></th>' . "\n";
496 $profiling_table .= ' </tr></thead><tbody>' . "\n";
497 list($detailed_table, $chart_json, $profiling_stats)
498 = PMA_analyzeAndGetTableHtmlForProfilingResults($profiling_results);
499 $profiling_table .= $detailed_table;
500 $profiling_table .= '</tbody></table>' . "\n";
501 $profiling_table .= '</div>';
503 $profiling_table .= '<div style="float: left; margin-left:10px;">';
504 $profiling_table .= '<h3>' . __('Summary by state') . '</h3>';
505 $profiling_table .= '<table id="profilesummarytable"><thead>' . "\n";
506 $profiling_table .= ' <tr>' . "\n";
507 $profiling_table .= ' <th>' . __('State')
508 . PMA_Util::showMySQLDocu('general-thread-states')
509 . '<div class="sorticon"></div></th>' . "\n";
510 $profiling_table .= ' <th>' . __('Total Time')
511 . '<div class="sorticon"></div></th>' . "\n";
512 $profiling_table .= ' <th>' . __('% Time')
513 . '<div class="sorticon"></div></th>' . "\n";
514 $profiling_table .= ' <th>' . __('Calls')
515 . '<div class="sorticon"></div></th>' . "\n";
516 $profiling_table .= ' <th>' . __('ø Time')
517 . '<div class="sorticon"></div></th>' . "\n";
518 $profiling_table .= ' </tr></thead><tbody>' . "\n";
519 $profiling_table .= PMA_getTableHtmlForProfilingSummaryByState(
520 $profiling_stats
522 $profiling_table .= '</tbody></table>' . "\n";
524 $profiling_table .= <<<EOT
525 <script type="text/javascript">
526 pma_token = '$pma_token';
527 url_query = '$url_query';
528 </script>
529 EOT;
530 $profiling_table .= "</div>";
531 $profiling_table .= "<div class='clearfloat'></div>";
533 //require_once 'libraries/chart.lib.php';
534 $profiling_table .= '<div id="profilingChartData" style="display:none;">';
535 $profiling_table .= json_encode($chart_json);
536 $profiling_table .= '</div>';
537 $profiling_table .= '<div id="profilingchart" style="display:none;">';
538 $profiling_table .= '</div>';
539 $profiling_table .= '<script type="text/javascript">';
540 $profiling_table .= "AJAX.registerOnload('sql.js', function () {";
541 $profiling_table .= 'makeProfilingChart();';
542 $profiling_table .= 'initProfilingTables();';
543 $profiling_table .= '});';
544 $profiling_table .= '</script>';
545 $profiling_table .= '</fieldset>' . "\n";
546 } else {
547 $profiling_table = null;
549 return $profiling_table;
553 * Function to get HTML for detailed profiling results table, profiling stats, and
554 * $chart_json for displaying the chart.
556 * @param array $profiling_results profiling results
558 * @return mixed
560 function PMA_analyzeAndGetTableHtmlForProfilingResults(
561 $profiling_results
563 $profiling_stats = array(
564 'total_time' => 0,
565 'states' => array(),
567 $chart_json = Array();
568 $i = 1;
569 $table = '';
570 foreach ($profiling_results as $one_result) {
571 if (isset($profiling_stats['states'][ucwords($one_result['Status'])])) {
572 $states = $profiling_stats['states'];
573 $states[ucwords($one_result['Status'])]['time']
574 += $one_result['Duration'];
575 $states[ucwords($one_result['Status'])]['calls']++;
576 } else {
577 $profiling_stats['states'][ucwords($one_result['Status'])] = array(
578 'total_time' => $one_result['Duration'],
579 'calls' => 1,
582 $profiling_stats['total_time'] += $one_result['Duration'];
584 $table .= ' <tr>' . "\n";
585 $table .= '<td>' . $i++ . '</td>' . "\n";
586 $table .= '<td>' . ucwords($one_result['Status'])
587 . '</td>' . "\n";
588 $table .= '<td class="right">'
589 . (PMA_Util::formatNumber($one_result['Duration'], 3, 1))
590 . 's<span style="display:none;" class="rawvalue">'
591 . $one_result['Duration'] . '</span></td>' . "\n";
592 if (isset($chart_json[ucwords($one_result['Status'])])) {
593 $chart_json[ucwords($one_result['Status'])]
594 += $one_result['Duration'];
595 } else {
596 $chart_json[ucwords($one_result['Status'])]
597 = $one_result['Duration'];
600 return array($table, $chart_json, $profiling_stats);
604 * Function to get HTML for summary by state table
606 * @param array $profiling_stats profiling stats
608 * @return string $table html for the table
610 function PMA_getTableHtmlForProfilingSummaryByState($profiling_stats)
612 $table = '';
613 foreach ($profiling_stats['states'] as $name => $stats) {
614 $table .= ' <tr>' . "\n";
615 $table .= '<td>' . $name . '</td>' . "\n";
616 $table .= '<td align="right">'
617 . PMA_Util::formatNumber($stats['total_time'], 3, 1)
618 . 's<span style="display:none;" class="rawvalue">'
619 . $stats['total_time'] . '</span></td>' . "\n";
620 $table .= '<td align="right">'
621 . PMA_Util::formatNumber(
622 100 * ($stats['total_time'] / $profiling_stats['total_time']),
623 0, 2
625 . '%</td>' . "\n";
626 $table .= '<td align="right">' . $stats['calls'] . '</td>'
627 . "\n";
628 $table .= '<td align="right">'
629 . PMA_Util::formatNumber(
630 $stats['total_time'] / $stats['calls'], 3, 1
632 . 's<span style="display:none;" class="rawvalue">'
633 . number_format($stats['total_time'] / $stats['calls'], 8, '.', '')
634 . '</span></td>' . "\n";
635 $table .= ' </tr>' . "\n";
637 return $table;
641 * Get the HTML for the enum column dropdown
642 * During grid edit, if we have a enum field, returns the html for the
643 * dropdown
645 * @param string $db current database
646 * @param string $table current table
647 * @param string $column current column
648 * @param string $curr_value currently selected value
650 * @return string $dropdown html for the dropdown
652 function PMA_getHtmlForEnumColumnDropdown($db, $table, $column, $curr_value)
654 $values = PMA_getValuesForColumn($db, $table, $column);
655 $dropdown = '<option value="">&nbsp;</option>';
656 $dropdown .= PMA_getHtmlForOptionsList($values, array($curr_value));
657 $dropdown = '<select>' . $dropdown . '</select>';
658 return $dropdown;
662 * Get the HTML for the set column dropdown
663 * During grid edit, if we have a set field, returns the html for the
664 * dropdown
666 * @param string $db current database
667 * @param string $table current table
668 * @param string $column current column
669 * @param string $curr_value currently selected value
671 * @return string $dropdown html for the set column
673 function PMA_getHtmlForSetColumn($db, $table, $column, $curr_value)
675 $values = PMA_getValuesForColumn($db, $table, $column);
676 $dropdown = '';
678 //converts characters of $curr_value to HTML entities
679 $converted_curr_value = htmlentities(
680 $curr_value, ENT_COMPAT, "UTF-8"
683 $selected_values = explode(',', $converted_curr_value);
684 $dropdown .= PMA_getHtmlForOptionsList($values, $selected_values);
686 $select_size = (sizeof($values) > 10) ? 10 : sizeof($values);
687 $dropdown = '<select multiple="multiple" size="' . $select_size . '">'
688 . $dropdown . '</select>';
690 return $dropdown;
694 * Get all the values for a enum column or set column in a table
696 * @param string $db current database
697 * @param string $table current table
698 * @param string $column current column
700 * @return array $values array containing the value list for the column
702 function PMA_getValuesForColumn($db, $table, $column)
704 $field_info_query = $GLOBALS['dbi']->getColumnsSql($db, $table, $column);
706 $field_info_result = $GLOBALS['dbi']->fetchResult(
707 $field_info_query, null, null, null, PMA_DatabaseInterface::QUERY_STORE
710 $values = PMA_Util::parseEnumSetValues($field_info_result[0]['Type']);
712 return $values;
716 * Get HTML for options list
718 * @param array $values set of values
719 * @param array $selected_values currently selected values
721 * @return string $options HTML for options list
723 function PMA_getHtmlForOptionsList($values, $selected_values)
725 $options = '';
726 foreach ($values as $value) {
727 $options .= '<option value="' . $value . '"';
728 if (in_array($value, $selected_values, true)) {
729 $options .= ' selected="selected" ';
731 $options .= '>' . $value . '</option>';
733 return $options;
737 * Function to get html for bookmark support if bookmarks are enabled. Else will
738 * return null
740 * @param string $disp_mode display mode
741 * @param bool $cfgBookmark configuration setting for bookmarking
742 * @param string $sql_query sql query
743 * @param string $db current database
744 * @param string $table current table
745 * @param string $complete_query complete query
746 * @param string $bkm_user bookmarking user
748 * @return string $html
750 function PMA_getHtmlForBookmark($disp_mode, $cfgBookmark, $sql_query, $db, $table,
751 $complete_query, $bkm_user
753 if ($disp_mode[7] == '1'
754 && (! empty($cfgBookmark) && empty($_GET['id_bookmark']))
755 && ! empty($sql_query)
757 $html = "\n";
758 $goto = 'sql.php'
759 . PMA_URL_getCommon(
760 array(
761 'db' => $db,
762 'table' => $table,
763 'sql_query' => $sql_query,
764 'id_bookmark'=> 1,
767 $bkm_sql_query = urlencode(
768 isset($complete_query) ? $complete_query : $sql_query
770 $html = '<form action="sql.php" method="post"'
771 . ' onsubmit="return ! emptyFormElements(this,'
772 . '\'bkm_fields[bkm_label]\');"'
773 . ' id="bookmarkQueryForm">';
774 $html .= PMA_URL_getHiddenInputs();
775 $html .= '<input type="hidden" name="goto" value="' . $goto . '" />';
776 $html .= '<input type="hidden" name="bkm_fields[bkm_database]"'
777 . ' value="' . htmlspecialchars($db) . '" />';
778 $html .= '<input type="hidden" name="bkm_fields[bkm_user]"'
779 . ' value="' . $bkm_user . '" />';
780 $html .= '<input type="hidden" name="bkm_fields[bkm_sql_query]"'
781 . ' value="'
782 . $bkm_sql_query
783 . '" />';
784 $html .= '<fieldset>';
785 $html .= '<legend>';
786 $html .= PMA_Util::getIcon(
787 'b_bookmark.png', __('Bookmark this SQL query'), true
789 $html .= '</legend>';
790 $html .= '<div class="formelement">';
791 $html .= '<label for="fields_label_">' . __('Label:') . '</label>';
792 $html .= '<input type="text" id="fields_label_"'
793 . ' name="bkm_fields[bkm_label]" value="" />';
794 $html .= '</div>';
795 $html .= '<div class="formelement">';
796 $html .= '<input type="checkbox" name="bkm_all_users"'
797 . ' id="bkm_all_users" value="true" />';
798 $html .= '<label for="bkm_all_users">'
799 . __('Let every user access this bookmark')
800 . '</label>';
801 $html .= '</div>';
802 $html .= '<div class="clearfloat"></div>';
803 $html .= '</fieldset>';
804 $html .= '<fieldset class="tblFooters">';
805 $html .= '<input type="hidden" name="store_bkm" value="1" />';
806 $html .= '<input type="submit"'
807 . ' value="' . __('Bookmark this SQL query') . '" />';
808 $html .= '</fieldset>';
809 $html .= '</form>';
811 } else {
812 $html = null;
815 return $html;
819 * Function to check whether to remember the sorting order or not
821 * @param array $analyzed_sql_results the analyzed query and other variables set
822 * after analyzing the query
824 * @return boolean
826 function PMA_isRememberSortingOrder($analyzed_sql_results)
828 $select_from = isset(
829 $analyzed_sql_results['analyzed_sql'][0]['queryflags']['select_from']
831 if ($GLOBALS['cfg']['RememberSorting']
832 && ! ($analyzed_sql_results['is_count']
833 || $analyzed_sql_results['is_export']
834 || $analyzed_sql_results['is_func']
835 || $analyzed_sql_results['is_analyse'])
836 && isset($analyzed_sql_results['analyzed_sql'][0]['select_expr'])
837 && (count($analyzed_sql_results['analyzed_sql'][0]['select_expr']) == 0)
838 && $select_from
839 && count($analyzed_sql_results['analyzed_sql'][0]['table_ref']) == 1
841 return true;
842 } else {
843 return false;
848 * Function to check whether the LIMIT clause should be appended or not
850 * @param array $analyzed_sql_results the analyzed query and other variables set
851 * after analyzing the query
853 * @return boolean
855 function PMA_isAppendLimitClause($analyzed_sql_results)
857 $select_from = isset(
858 $analyzed_sql_results['analyzed_sql'][0]['queryflags']['select_from']
860 if (($_SESSION['tmpval']['max_rows'] != 'all')
861 && ! ($analyzed_sql_results['is_export']
862 || $analyzed_sql_results['is_analyse'])
863 && ($select_from || $analyzed_sql_results['is_subquery'])
864 && ! isset($analyzed_sql_results['analyzed_sql'][0]['queryflags']['offset'])
865 && empty($analyzed_sql_results['analyzed_sql'][0]['limit_clause'])
867 return true;
868 } else {
869 return false;
874 * Function to check whether this query is for just browsing
876 * @param array $analyzed_sql_results the analyzed query and other variables set
877 * after analyzing the query
878 * @param boolean $find_real_end whether the real end should be found
880 * @return boolean
882 function PMA_isJustBrowsing($analyzed_sql_results, $find_real_end)
884 $distinct = isset(
885 $analyzed_sql_results['analyzed_sql'][0]['queryflags']['distinct']
888 $table_name = isset(
889 $analyzed_sql_results['analyzed_sql'][0]['table_ref'][1]['table_name']
891 if (! $analyzed_sql_results['is_group']
892 && ! isset($analyzed_sql_results['analyzed_sql'][0]['queryflags']['union'])
893 && ! $distinct
894 && ! $table_name
895 && (empty($analyzed_sql_results['analyzed_sql'][0]['where_clause'])
896 || $analyzed_sql_results['analyzed_sql'][0]['where_clause'] == '1 ')
897 && empty($analyzed_sql_results['analyzed_sql'][0]['group_by_clause'])
898 && ! isset($find_real_end)
899 && !$analyzed_sql_results['is_subquery']
900 && empty($analyzed_sql_results['analyzed_sql'][0]['having_clause'])
902 return true;
903 } else {
904 return false;
909 * Function to check whether the reated transformation information shoul be deleted
911 * @param array $analyzed_sql_results the analyzed query and other variables set
912 * after analyzing the query
914 * @return boolean
916 function PMA_isDeleteTransformationInfo($analyzed_sql_results)
918 if (!empty($analyzed_sql_results['analyzed_sql'][0]['querytype'])
919 && (($analyzed_sql_results['analyzed_sql'][0]['querytype'] == 'ALTER')
920 || ($analyzed_sql_results['analyzed_sql'][0]['querytype'] == 'DROP'))
922 return true;
923 } else {
924 return false;
929 * Function to check whether the user has rights to drop the database
931 * @param array $analyzed_sql_results the analyzed query and other variables set
932 * after analyzing the query
933 * @param boolean $allowUserDropDatabase whether the user is allowed to drop db
934 * @param boolean $is_superuser whether this user is a superuser
936 * @return boolean
938 function PMA_hasNoRightsToDropDatabase($analyzed_sql_results,
939 $allowUserDropDatabase, $is_superuser
941 if (! defined('PMA_CHK_DROP')
942 && ! $allowUserDropDatabase
943 && isset ($analyzed_sql_results['drop_database'])
944 && $analyzed_sql_results['drop_database'] == 1
945 && ! $is_superuser
947 return true;
948 } else {
949 return false;
954 * Function to set the column order
956 * @param PMA_Table $pmatable PMA_Table instance
958 * @return boolean $retval
960 function PMA_setColumnOrder($pmatable)
962 $col_order = explode(',', $_REQUEST['col_order']);
963 $retval = $pmatable->setUiProp(
964 PMA_Table::PROP_COLUMN_ORDER,
965 $col_order,
966 $_REQUEST['table_create_time']
968 if (gettype($retval) != 'boolean') {
969 $response = PMA_Response::getInstance();
970 $response->isSuccess(false);
971 $response->addJSON('message', $retval->getString());
972 exit;
975 return $retval;
979 * Function to set the column visibility
981 * @param PMA_Table $pmatable PMA_Table instance
983 * @return boolean $retval
985 function PMA_setColumnVisibility($pmatable)
987 $col_visib = explode(',', $_REQUEST['col_visib']);
988 $retval = $pmatable->setUiProp(
989 PMA_Table::PROP_COLUMN_VISIB, $col_visib,
990 $_REQUEST['table_create_time']
992 if (gettype($retval) != 'boolean') {
993 $response = PMA_Response::getInstance();
994 $response->isSuccess(false);
995 $response->addJSON('message', $retval->getString());
996 exit;
998 return $retval;
1002 * Function to check the request for setting the column order or visibility
1004 * @param String $table the current table
1005 * @param String $db the current database
1007 * @return void
1009 function PMA_setColumnOrderOrVisibility($table, $db)
1011 $pmatable = new PMA_Table($table, $db);
1012 $retval = false;
1014 // set column order
1015 if (isset($_REQUEST['col_order'])) {
1016 $retval = PMA_setColumnOrder($pmatable);
1019 // set column visibility
1020 if ($retval === true && isset($_REQUEST['col_visib'])) {
1021 $retval = PMA_setColumnVisibility($pmatable);
1024 $response = PMA_Response::getInstance();
1025 $response->isSuccess($retval == true);
1026 exit;
1030 * Function to add a bookmark
1032 * @param String $pmaAbsoluteUri absolute URI
1033 * @param String $goto goto page URL
1035 * @return void
1037 function PMA_addBookmark($pmaAbsoluteUri, $goto)
1039 $result = PMA_Bookmark_save(
1040 $_POST['bkm_fields'],
1041 (isset($_POST['bkm_all_users'])
1042 && $_POST['bkm_all_users'] == 'true' ? true : false
1045 $response = PMA_Response::getInstance();
1046 if ($response->isAjax()) {
1047 if ($result) {
1048 $msg = PMA_message::success(__('Bookmark %s has been created.'));
1049 $msg->addParam($_POST['bkm_fields']['bkm_label']);
1050 $response->addJSON('message', $msg);
1051 } else {
1052 $msg = PMA_message::error(__('Bookmark not created!'));
1053 $response->isSuccess(false);
1054 $response->addJSON('message', $msg);
1056 exit;
1057 } else {
1058 // go back to sql.php to redisplay query; do not use &amp; in this case:
1060 * @todo In which scenario does this happen?
1062 PMA_sendHeaderLocation(
1063 $pmaAbsoluteUri . $goto
1064 . '&label=' . $_POST['bkm_fields']['bkm_label']
1070 * Function to find the real end of rows
1072 * @param String $db the current database
1073 * @param String $table the current table
1075 * @return mixed the number of rows if "retain" param is true, otherwise true
1077 function PMA_findRealEndOfRows($db, $table)
1079 $unlim_num_rows = PMA_Table::countRecords($db, $table, true);
1080 $_SESSION['tmpval']['pos'] = PMA_getStartPosToDisplayRow($unlim_num_rows);
1082 return $unlim_num_rows;
1086 * Function to get values for the relational columns
1088 * @param String $db the current database
1089 * @param String $table the current table
1090 * @param String $display_field display field
1092 * @return void
1094 function PMA_getRelationalValues($db, $table, $display_field)
1096 $column = $_REQUEST['column'];
1097 if ($_SESSION['tmpval']['relational_display'] == 'D'
1098 && isset($display_field)
1099 && strlen($display_field)
1100 && isset($_REQUEST['relation_key_or_display_column'])
1101 && $_REQUEST['relation_key_or_display_column']
1103 $curr_value = $_REQUEST['relation_key_or_display_column'];
1104 } else {
1105 $curr_value = $_REQUEST['curr_value'];
1107 $dropdown = PMA_getHtmlForRelationalColumnDropdown(
1108 $db, $table, $column, $curr_value
1110 $response = PMA_Response::getInstance();
1111 $response->addJSON('dropdown', $dropdown);
1112 exit;
1116 * Function to get values for Enum or Set Columns
1118 * @param String $db the current database
1119 * @param String $table the current table
1120 * @param String $columnType whether enum or set
1122 * @return void
1124 function PMA_getEnumOrSetValues($db, $table, $columnType)
1126 $column = $_REQUEST['column'];
1127 $curr_value = $_REQUEST['curr_value'];
1128 $response = PMA_Response::getInstance();
1129 if ($columnType == "enum") {
1130 $dropdown = PMA_getHtmlForEnumColumnDropdown(
1131 $db, $table, $column, $curr_value
1133 $response->addJSON('dropdown', $dropdown);
1134 } else {
1135 $select = PMA_getHtmlForSetColumn($db, $table, $column, $curr_value);
1136 $response->addJSON('select', $select);
1138 exit;
1142 * Function to append the limit clause
1144 * @param String $full_sql_query full sql query
1145 * @param array $analyzed_sql analyzed sql query
1146 * @param String $display_query display query
1148 * @return array
1150 function PMA_appendLimitClause($full_sql_query, $analyzed_sql, $display_query)
1152 $sql_limit_to_append = ' LIMIT ' . $_SESSION['tmpval']['pos']
1153 . ', ' . $_SESSION['tmpval']['max_rows'] . " ";
1154 $full_sql_query = PMA_getSqlWithLimitClause(
1155 $full_sql_query,
1156 $analyzed_sql,
1157 $sql_limit_to_append
1161 * @todo pretty printing of this modified query
1163 if ($display_query) {
1164 // if the analysis of the original query revealed that we found
1165 // a section_after_limit, we now have to analyze $display_query
1166 // to display it correctly
1168 if (! empty($analyzed_sql[0]['section_after_limit'])
1169 && trim($analyzed_sql[0]['section_after_limit']) != ';'
1171 $analyzed_display_query = PMA_SQP_analyze(
1172 PMA_SQP_parse($display_query)
1174 $display_query = $analyzed_display_query[0]['section_before_limit']
1175 . "\n" . $sql_limit_to_append
1176 . $analyzed_display_query[0]['section_after_limit'];
1180 return array($sql_limit_to_append, $full_sql_query, isset(
1181 $analyzed_display_query)
1182 ? $analyzed_display_query : null,
1183 isset($display_query) ? $display_query : null
1188 * Function to get the default sql query for browsing page
1190 * @param String $db the current database
1191 * @param String $table the current table
1193 * @return String $sql_query the default $sql_query for browse page
1195 function PMA_getDefaultSqlQueryForBrowse($db, $table)
1197 include_once 'libraries/bookmark.lib.php';
1198 $book_sql_query = PMA_Bookmark_get(
1199 $db,
1200 '\'' . PMA_Util::sqlAddSlashes($table) . '\'',
1201 'label',
1202 false,
1203 true
1206 if (! empty($book_sql_query)) {
1207 $GLOBALS['using_bookmark_message'] = PMA_message::notice(
1208 __('Using bookmark "%s" as default browse query.')
1210 $GLOBALS['using_bookmark_message']->addParam($table);
1211 $GLOBALS['using_bookmark_message']->addMessage(
1212 PMA_Util::showDocu('faq', 'faq6-22')
1214 $sql_query = $book_sql_query;
1215 } else {
1216 $sql_query = 'SELECT * FROM ' . PMA_Util::backquote($table);
1218 unset($book_sql_query);
1220 return $sql_query;
1224 * Responds an error when an error happens when executing the query
1226 * @param boolean $is_gotofile whether goto file or not
1227 * @param String $error error after executing the query
1228 * @param String $full_sql_query full sql query
1230 * @return void
1232 function PMA_handleQueryExecuteError($is_gotofile, $error, $full_sql_query)
1234 if ($is_gotofile) {
1235 $message = PMA_Message::rawError($error);
1236 $response = PMA_Response::getInstance();
1237 $response->isSuccess(false);
1238 $response->addJSON('message', $message);
1239 } else {
1240 PMA_Util::mysqlDie($error, $full_sql_query, '', '');
1242 exit;
1246 * Function to store the query as a bookmark
1248 * @param String $db the current database
1249 * @param String $bkm_user the bookmarking user
1250 * @param String $sql_query_for_bookmark the query to be stored in bookmark
1251 * @param String $bkm_label bookmark label
1252 * @param boolean $bkm_replace whether to replace existing bookmarks
1254 * @return void
1256 function PMA_storeTheQueryAsBookmark($db, $bkm_user, $sql_query_for_bookmark,
1257 $bkm_label, $bkm_replace
1259 include_once 'libraries/bookmark.lib.php';
1260 $bfields = array(
1261 'bkm_database' => $db,
1262 'bkm_user' => $bkm_user,
1263 'bkm_sql_query' => urlencode($sql_query_for_bookmark),
1264 'bkm_label' => $bkm_label
1267 // Should we replace bookmark?
1268 if (isset($bkm_replace)) {
1269 $bookmarks = PMA_Bookmark_getList($db);
1270 foreach ($bookmarks as $key => $val) {
1271 if ($val == $bkm_label) {
1272 PMA_Bookmark_delete($key);
1277 PMA_Bookmark_save($bfields, isset($_POST['bkm_all_users']));
1282 * Function to execute the SQL query and set the execution time
1284 * @param String $full_sql_query the full sql query
1286 * @return mixed $result the results after running the query
1288 function PMA_executeQueryAndStoreResults($full_sql_query)
1290 // Measure query time.
1291 $querytime_before = array_sum(explode(' ', microtime()));
1293 $result = @$GLOBALS['dbi']->tryQuery(
1294 $full_sql_query, null, PMA_DatabaseInterface::QUERY_STORE
1296 $querytime_after = array_sum(explode(' ', microtime()));
1298 $GLOBALS['querytime'] = $querytime_after - $querytime_before;
1300 // If a stored procedure was called, there may be more results that are
1301 // queued up and waiting to be flushed from the buffer. So let's do that.
1302 do {
1303 $GLOBALS['dbi']->storeResult();
1304 if (! $GLOBALS['dbi']->moreResults()) {
1305 break;
1307 } while ($GLOBALS['dbi']->nextResult());
1309 return $result;
1313 * Function to get the affected or changed number of rows after executing a query
1315 * @param boolean $is_affected whether the query affected a table
1316 * @param mixed $result results of executing the query
1317 * @param int $num_rows number of rows affected or changed
1319 * @return int $num_rows number of rows affected or changed
1321 function PMA_getNumberOfRowsAffectedOrChanged($is_affected, $result, $num_rows)
1323 if (! $is_affected) {
1324 $num_rows = ($result) ? @$GLOBALS['dbi']->numRows($result) : 0;
1325 } elseif (! isset($num_rows)) {
1326 $num_rows = @$GLOBALS['dbi']->affectedRows();
1329 return $num_rows;
1333 * Checks if the current database has changed
1334 * This could happen if the user sends a query like "USE `database`;"
1336 * @param String $db the database in the query
1338 * @return int $reload whether to reload the navigation(1) or not(0)
1340 function PMA_hasCurrentDbChanged($db)
1342 // Checks if the current database has changed
1343 // This could happen if the user sends a query like "USE `database`;"
1344 $reload = 0;
1345 if (strlen($db)) {
1346 $current_db = $GLOBALS['dbi']->fetchValue('SELECT DATABASE()');
1347 // $current_db is false, except when a USE statement was sent
1348 if ($current_db != false && $db !== $current_db) {
1349 $reload = 1;
1353 return $reload;
1357 * If a table, database or column gets dropped, clean comments.
1359 * @param String $db current database
1360 * @param String $table current table
1361 * @param String $dropped_column dropped column if any
1362 * @param bool $purge whether purge set or not
1363 * @param array $extra_data extra data
1365 * @return array $extra_data
1367 function PMA_cleanupRelations($db, $table, $dropped_column, $purge, $extra_data)
1369 include_once 'libraries/relation_cleanup.lib.php';
1371 if (isset($purge) && $purge == 1) {
1372 if (strlen($table) && strlen($db)) {
1373 PMA_relationsCleanupTable($db, $table);
1374 } elseif (strlen($db)) {
1375 PMA_relationsCleanupDatabase($db);
1379 if (isset($dropped_column)
1380 && !empty($dropped_column)
1381 && strlen($db)
1382 && strlen($table)
1384 PMA_relationsCleanupColumn($db, $table, $dropped_column);
1385 // to refresh the list of indexes (Ajax mode)
1386 $extra_data['indexes_list'] = PMA_Index::getView($table, $db);
1389 return $extra_data;
1393 * Function to count the total number of rows for the same 'SELECT' query without
1394 * the 'LIMIT' clause that may have been programatically added
1396 * @param int $num_rows number of rows affected/changed by the query
1397 * @param bool $is_select whether the query is SELECT or not
1398 * @param bool $justBrowsing whether just browsing or not
1399 * @param string $db the current database
1400 * @param string $table the current table
1401 * @param array $parsed_sql parsed sql
1402 * @param array $analyzed_sql_results the analyzed query and other variables set
1403 * after analyzing the query
1405 * @return int $unlim_num_rows unlimited number of rows
1407 function PMA_countQueryResults(
1408 $num_rows, $is_select, $justBrowsing,
1409 $db, $table, $parsed_sql, $analyzed_sql_results
1411 if (!PMA_isAppendLimitClause($analyzed_sql_results)) {
1412 // if we did not append a limit, set this to get a correct
1413 // "Showing rows..." message
1414 // $_SESSION['tmpval']['max_rows'] = 'all';
1415 $unlim_num_rows = $num_rows;
1416 } elseif ($is_select || $analyzed_sql_results['is_subquery']) {
1417 // c o u n t q u e r y
1419 // If we are "just browsing", there is only one table,
1420 // and no WHERE clause (or just 'WHERE 1 '),
1421 // we do a quick count (which uses MaxExactCount) because
1422 // SQL_CALC_FOUND_ROWS is not quick on large InnoDB tables
1424 // However, do not count again if we did it previously
1425 // due to $find_real_end == true
1426 if ($justBrowsing) {
1427 $unlim_num_rows = PMA_Table::countRecords(
1428 $db,
1429 $table,
1430 true
1433 } else {
1434 // add select expression after the SQL_CALC_FOUND_ROWS
1436 // for UNION, just adding SQL_CALC_FOUND_ROWS
1437 // after the first SELECT works.
1439 // take the left part, could be:
1440 // SELECT
1441 // (SELECT
1443 $analyzed_sql = $analyzed_sql_results['analyzed_sql'];
1445 $count_query = PMA_SQP_format(
1446 $parsed_sql,
1447 'query_only',
1449 $analyzed_sql[0]['position_of_first_select'] + 1
1451 $count_query .= ' SQL_CALC_FOUND_ROWS ';
1452 // add everything that was after the first SELECT
1453 $count_query .= PMA_SQP_format(
1454 $parsed_sql,
1455 'query_only',
1456 $analyzed_sql[0]['position_of_first_select'] + 1
1458 // ensure there is no semicolon at the end of the
1459 // count query because we'll probably add
1460 // a LIMIT 1 clause after it
1461 $count_query = rtrim($count_query);
1462 $count_query = rtrim($count_query, ';');
1464 // if using SQL_CALC_FOUND_ROWS, add a LIMIT to avoid
1465 // long delays. Returned count will be complete anyway.
1466 // (but a LIMIT would disrupt results in an UNION)
1468 if (! isset($analyzed_sql[0]['queryflags']['union'])) {
1469 $count_query .= ' LIMIT 1';
1472 // run the count query
1474 $GLOBALS['dbi']->tryQuery($count_query);
1475 // if (mysql_error()) {
1476 // void.
1477 // I tried the case
1478 // (SELECT `User`, `Host`, `Db`, `Select_priv` FROM `db`)
1479 // UNION (SELECT `User`, `Host`, "%" AS "Db",
1480 // `Select_priv`
1481 // FROM `user`) ORDER BY `User`, `Host`, `Db`;
1482 // and although the generated count_query is wrong
1483 // the SELECT FOUND_ROWS() work! (maybe it gets the
1484 // count from the latest query that worked)
1486 // another case where the count_query is wrong:
1487 // SELECT COUNT(*), f1 from t1 group by f1
1488 // and you click to sort on count(*)
1489 // }
1490 $unlim_num_rows = $GLOBALS['dbi']->fetchValue('SELECT FOUND_ROWS()');
1491 } // end else "just browsing"
1492 } else {// not $is_select
1493 $unlim_num_rows = 0;
1496 return $unlim_num_rows;
1500 * Function to handle all aspects relating to executing the query
1502 * @param array $analyzed_sql_results analyzed sql results
1503 * @param String $full_sql_query full sql query
1504 * @param boolean $is_gotofile whether to go to a file
1505 * @param String $db current database
1506 * @param String $table current table
1507 * @param boolean $find_real_end whether to find the real end
1508 * @param String $sql_query_for_bookmark sql query to be stored as bookmark
1509 * @param array $extra_data extra data
1511 * @return mixed
1513 function PMA_executeTheQuery($analyzed_sql_results, $full_sql_query, $is_gotofile,
1514 $db, $table, $find_real_end, $sql_query_for_bookmark, $extra_data
1516 // Only if we ask to see the php code
1517 if (isset($GLOBALS['show_as_php'])) {
1518 $result = null;
1519 $num_rows = 0;
1520 $unlim_num_rows = 0;
1521 } else { // If we don't ask to see the php code
1522 if (isset($_SESSION['profiling']) && PMA_Util::profilingSupported()) {
1523 $GLOBALS['dbi']->query('SET PROFILING=1;');
1526 $result = PMA_executeQueryAndStoreResults($full_sql_query);
1528 // Displays an error message if required and stop parsing the script
1529 $error = $GLOBALS['dbi']->getError();
1530 if ($error) {
1531 PMA_handleQueryExecuteError($is_gotofile, $error, $full_sql_query);
1534 // If there are no errors and bookmarklabel was given,
1535 // store the query as a bookmark
1536 if (! empty($_POST['bkm_label']) && ! empty($sql_query_for_bookmark)) {
1537 PMA_storeTheQueryAsBookmark(
1538 $db, $GLOBALS['cfg']['Bookmark']['user'],
1539 $sql_query_for_bookmark, $_POST['bkm_label'],
1540 isset($_POST['bkm_replace']) ? $_POST['bkm_replace'] : null
1542 } // end store bookmarks
1544 // Gets the number of rows affected/returned
1545 // (This must be done immediately after the query because
1546 // mysql_affected_rows() reports about the last query done)
1547 $num_rows = PMA_getNumberOfRowsAffectedOrChanged(
1548 $analyzed_sql_results['is_affected'], $result,
1549 isset($num_rows) ? $num_rows : null
1552 // Grabs the profiling results
1553 if (isset($_SESSION['profiling']) && PMA_Util::profilingSupported()) {
1554 $profiling_results = $GLOBALS['dbi']->fetchResult('SHOW PROFILE;');
1557 $justBrowsing = PMA_isJustBrowsing(
1558 $analyzed_sql_results, isset($find_real_end) ? $find_real_end : null
1561 $unlim_num_rows = PMA_countQueryResults(
1562 $num_rows, $analyzed_sql_results['is_select'], $justBrowsing, $db,
1563 $table, $analyzed_sql_results['parsed_sql'], $analyzed_sql_results
1566 $extra_data = PMA_cleanupRelations(
1567 isset($db) ? $db : '', isset($table) ? $table : '',
1568 isset($_REQUEST['dropped_column']) ? $_REQUEST['dropped_column'] : null,
1569 isset($_REQUEST['purge']) ? $_REQUEST['purge'] : null,
1570 isset($extra_data) ? $extra_data : null
1573 // Update Indexes list.
1574 if (isset($_REQUEST['index_change'])) {
1575 $extra_data['indexes_list'] = PMA_Index::getView($table, $db);
1579 return array($result, $num_rows, $unlim_num_rows,
1580 isset($profiling_results) ? $profiling_results : null,
1581 isset($justBrowsing) ? $justBrowsing : null, $extra_data
1585 * Delete related tranformatioinformationn information
1587 * @param String $db current database
1588 * @param String $table current table
1589 * @param array $analyzed_sql analyzed sql query
1591 * @return void
1593 function PMA_deleteTransformationInfo($db, $table, $analyzed_sql)
1595 include_once 'libraries/transformations.lib.php';
1596 if ($analyzed_sql[0]['querytype'] == 'ALTER') {
1597 if (stripos($analyzed_sql[0]['unsorted_query'], 'DROP') !== false) {
1598 $drop_column = PMA_getColumnNameInColumnDropSql(
1599 $analyzed_sql[0]['unsorted_query']
1602 if ($drop_column != '') {
1603 PMA_clearTransformations($db, $table, $drop_column);
1607 } else if (($analyzed_sql[0]['querytype'] == 'DROP') && ($table != '')) {
1608 PMA_clearTransformations($db, $table);
1613 * Function to get the message for the no rows returned case
1615 * @param string $message_to_show message to show
1616 * @param array $analyzed_sql_results analyzed sql results
1617 * @param int $num_rows number of rows
1619 * @return string $message
1621 function PMA_getMessageForNoRowsReturned($message_to_show, $analyzed_sql_results,
1622 $num_rows
1624 if ($analyzed_sql_results['is_delete']) {
1625 $message = PMA_Message::getMessageForDeletedRows($num_rows);
1626 } elseif ($analyzed_sql_results['is_insert']) {
1627 if ($analyzed_sql_results['is_replace']) {
1628 // For replace we get DELETED + INSERTED row count,
1629 // so we have to call it affected
1630 $message = PMA_Message::getMessageForAffectedRows($num_rows);
1631 } else {
1632 $message = PMA_Message::getMessageForInsertedRows($num_rows);
1634 $insert_id = $GLOBALS['dbi']->insertId();
1635 if ($insert_id != 0) {
1636 // insert_id is id of FIRST record inserted in one insert,
1637 // so if we inserted multiple rows, we had to increment this
1638 $message->addMessage('[br]');
1639 // need to use a temporary because the Message class
1640 // currently supports adding parameters only to the first
1641 // message
1642 $_inserted = PMA_Message::notice(__('Inserted row id: %1$d'));
1643 $_inserted->addParam($insert_id + $num_rows - 1);
1644 $message->addMessage($_inserted);
1646 } elseif ($analyzed_sql_results['is_affected']) {
1647 $message = PMA_Message::getMessageForAffectedRows($num_rows);
1649 // Ok, here is an explanation for the !$is_select.
1650 // The form generated by sql_query_form.lib.php
1651 // and db_sql.php has many submit buttons
1652 // on the same form, and some confusion arises from the
1653 // fact that $message_to_show is sent for every case.
1654 // The $message_to_show containing a success message and sent with
1655 // the form should not have priority over errors
1656 } elseif (! empty($message_to_show) && ! $analyzed_sql_results['is_select']) {
1657 $message = PMA_Message::rawSuccess(htmlspecialchars($message_to_show));
1658 } elseif (! empty($GLOBALS['show_as_php'])) {
1659 $message = PMA_Message::success(__('Showing as PHP code'));
1660 } elseif (isset($GLOBALS['show_as_php'])) {
1661 /* User disable showing as PHP, query is only displayed */
1662 $message = PMA_Message::notice(__('Showing SQL query'));
1663 } else {
1664 $message = PMA_Message::success(
1665 __('MySQL returned an empty result set (i.e. zero rows).')
1669 if (isset($GLOBALS['querytime'])) {
1670 $_querytime = PMA_Message::notice(
1671 '(' . __('Query took %01.4f seconds.') . ')'
1673 $_querytime->addParam($GLOBALS['querytime']);
1674 $message->addMessage($_querytime);
1677 return $message;
1681 * Function to send the Ajax response when no rows returned
1683 * @param string $message message to be send
1684 * @param array $analyzed_sql analyzed sql
1685 * @param object $displayResultsObject DisplayResult instance
1686 * @param array $extra_data extra data
1688 * @return void
1690 function PMA_sendAjaxResponseForNoResultsReturned($message, $analyzed_sql,
1691 $displayResultsObject, $extra_data
1694 * @todo find a better way to make getMessage() in Header.class.php
1695 * output the intended message
1697 $GLOBALS['message'] = $message;
1699 if ($GLOBALS['cfg']['ShowSQL']) {
1700 $extra_data['sql_query'] = PMA_Util::getMessage(
1701 $message, $GLOBALS['sql_query'], 'success'
1704 if (isset($GLOBALS['reload']) && $GLOBALS['reload'] == 1) {
1705 $extra_data['reload'] = 1;
1706 $extra_data['db'] = $GLOBALS['db'];
1708 $response = PMA_Response::getInstance();
1709 $response->isSuccess($message->isSuccess());
1710 // No need to manually send the message
1711 // The Response class will handle that automatically
1712 $query__type = PMA_DisplayResults::QUERY_TYPE_SELECT;
1713 if ($analyzed_sql[0]['querytype'] == $query__type) {
1714 $createViewHTML = $displayResultsObject->getCreateViewQueryResultOp(
1715 $analyzed_sql
1717 $response->addHTML($createViewHTML . '<br />');
1720 $response->addJSON(isset($extra_data) ? $extra_data : array());
1721 if (empty($_REQUEST['ajax_page_request'])) {
1722 $response->addJSON('message', $message);
1723 exit;
1728 * Function to respond back when the query returns zero rows
1729 * This method is called
1730 * 1-> When browsing an empty table
1731 * 2-> When executing a query on a non empty table which returns zero results
1732 * 3-> When executing a query on an empty table
1733 * 4-> When executing an INSERT, UPDATE, DEDETE query from the SQL tab
1734 * 5-> When deleting a row from BROWSE tab
1735 * 6-> When searching using the SEARCH tab which returns zero results
1736 * 7-> When changing the structure of the table except change operation
1738 * @param array $analyzed_sql_results analyzed sql results
1739 * @param string $db current database
1740 * @param string $table current table
1741 * @param string $message_to_show message to show
1742 * @param int $num_rows number of rows
1743 * @param object $displayResultsObject DisplayResult instance
1744 * @param array $extra_data extra data
1746 * @return void
1748 function PMA_sendQueryResponseForNoResultsReturned($analyzed_sql_results, $db,
1749 $table, $message_to_show, $num_rows, $displayResultsObject, $extra_data
1751 if (PMA_isDeleteTransformationInfo($analyzed_sql_results)) {
1752 PMA_deleteTransformationInfo(
1753 $db, $table, $analyzed_sql_results['analyzed_sql']
1757 $message = PMA_getMessageForNoRowsReturned(
1758 isset($message_to_show) ? $message_to_show : null, $analyzed_sql_results,
1759 $num_rows
1761 if (!isset($GLOBALS['show_as_php'])) {
1762 PMA_sendAjaxResponseForNoResultsReturned(
1763 $message, $analyzed_sql_results['analyzed_sql'],
1764 $displayResultsObject,
1765 isset($extra_data) ? $extra_data : null
1768 exit();
1772 * Function to send response for ajax grid edit
1774 * @param object $result result of the executed query
1776 * @return void
1778 function PMA_sendResponseForGridEdit($result)
1780 $row = $GLOBALS['dbi']->fetchRow($result);
1781 $response = PMA_Response::getInstance();
1782 $response->addJSON('value', $row[0]);
1783 exit;
1787 * Function to get html for the sql query results div
1789 * @param string $previous_update_query_html html for the previously executed query
1790 * @param string $profiling_chart_html html for profiling
1791 * @param object $missing_unique_column_msg message for the missing unique column
1792 * @param object $bookmark_created_msg message for bookmark creation
1793 * @param string $table_html html for the table for displaying sql
1794 * results
1795 * @param string $indexes_problems_html html for displaying errors in indexes
1796 * @param string $bookmark_support_html html for displaying bookmark form
1797 * @param string $print_button_html html for the print button in printview
1799 * @return string $html_output
1801 function PMA_getHtmlForSqlQueryResults($previous_update_query_html,
1802 $profiling_chart_html, $missing_unique_column_msg, $bookmark_created_msg,
1803 $table_html, $indexes_problems_html, $bookmark_support_html, $print_button_html
1805 //begin the sqlqueryresults div here. container div
1806 $html_output = '<div id="sqlqueryresults" class="ajax">';
1807 $html_output .= isset($previous_update_query_html)
1808 ? $previous_update_query_html : '';
1809 $html_output .= isset($profiling_chart_html) ? $profiling_chart_html : '';
1810 $html_output .= isset($missing_unique_column_msg)
1811 ? $missing_unique_column_msg->getDisplay() : '';
1812 $html_output .= isset($bookmark_created_msg)
1813 ? $bookmark_created_msg->getDisplay() : '';
1814 $html_output .= $table_html;
1815 $html_output .= isset($indexes_problems_html) ? $indexes_problems_html : '';
1816 $html_output .= isset($bookmark_support_html) ? $bookmark_support_html : '';
1817 $html_output .= isset($print_button_html) ? $print_button_html : '';
1818 $html_output .= '</div>'; // end sqlqueryresults div
1820 return $html_output;
1824 * Returns a message for successful creation of a bookmark or null if a bookmark
1825 * was not created
1827 * @return PMA_message $bookmark_created_msg
1829 function PMA_getBookmarkCreatedMessage()
1831 if (isset($_GET['label'])) {
1832 $bookmark_created_msg = PMA_message::success(__('Bookmark %s has been created.'));
1833 $bookmark_created_msg->addParam($_GET['label']);
1834 } else {
1835 $bookmark_created_msg = null;
1838 return $bookmark_created_msg;
1842 * Function to get html for the sql query results table
1844 * @param array $sql_data sql data
1845 * @param object $displayResultsObject instance of DisplayResult.class
1846 * @param string $db current database
1847 * @param string $goto goto page url
1848 * @param string $pmaThemeImage theme image uri
1849 * @param string $url_query url query
1850 * @param string $disp_mode display mode
1851 * @param string $sql_limit_to_append sql limit to append
1852 * @param bool $editable whether the result table is editable or not
1853 * @param int $unlim_num_rows unlimited number of rows
1854 * @param int $num_rows number of rows
1855 * @param bool $showtable whether to show table or not
1856 * @param object $result result of the executed query
1857 * @param array $analyzed_sql_results analyzed sql results
1859 * @return String
1861 function PMA_getHtmlForSqlQueryResultsTable($sql_data, $displayResultsObject, $db,
1862 $goto, $pmaThemeImage, $url_query, $disp_mode, $sql_limit_to_append,
1863 $editable, $unlim_num_rows, $num_rows, $showtable, $result,
1864 $analyzed_sql_results
1866 $printview = isset($_REQUEST['printview']) ? $_REQUEST['printview'] : null;
1867 if (! empty($sql_data) && ($sql_data['valid_queries'] > 1)
1868 || $analyzed_sql_results['is_procedure']
1870 $_SESSION['is_multi_query'] = true;
1871 $table_html = PMA_getTableHtmlForMultipleQueries(
1872 $displayResultsObject, $db, $sql_data, $goto,
1873 $pmaThemeImage, $printview, $url_query,
1874 $disp_mode, $sql_limit_to_append, $editable
1876 } else {
1877 if (isset($result) && $result) {
1878 $fields_meta = $GLOBALS['dbi']->getFieldsMeta($result);
1879 $fields_cnt = count($fields_meta);
1881 $_SESSION['is_multi_query'] = false;
1882 $displayResultsObject->setProperties(
1883 $unlim_num_rows, $fields_meta, $analyzed_sql_results['is_count'],
1884 $analyzed_sql_results['is_export'], $analyzed_sql_results['is_func'],
1885 $analyzed_sql_results['is_analyse'], $num_rows,
1886 $fields_cnt, $GLOBALS['querytime'], $pmaThemeImage, $GLOBALS['text_dir'],
1887 $analyzed_sql_results['is_maint'], $analyzed_sql_results['is_explain'],
1888 $analyzed_sql_results['is_show'], $showtable, $printview, $url_query,
1889 $editable
1892 $table_html = $displayResultsObject->getTable(
1893 $result, $disp_mode, $analyzed_sql_results['analyzed_sql']
1895 $GLOBALS['dbi']->freeResult($result);
1898 return $table_html;
1902 * Function to get html for the previous query if there is such. If not will return
1903 * null
1905 * @param string $disp_query display query
1906 * @param bool $showSql whether to show sql
1907 * @param array $sql_data sql data
1908 * @param string $disp_message display message
1910 * @return string $previous_update_query_html
1912 function PMA_getHtmlForPreviousUpdateQuery($disp_query, $showSql, $sql_data,
1913 $disp_message
1915 // previous update query (from tbl_replace)
1916 if (isset($disp_query) && ($showSql == true) && empty($sql_data)) {
1917 $previous_update_query_html = PMA_Util::getMessage(
1918 $disp_message, $disp_query, 'success'
1920 } else {
1921 $previous_update_query_html = null;
1924 return $previous_update_query_html;
1928 * To get the message if a column index is missing. If not will return null
1930 * @param string $table current table
1931 * @param string $db current database
1932 * @param boolean $editable whether the results table can be editable or not
1933 * @param string $disp_mode display mode
1935 * @return PMA_message $message
1937 function PMA_getMessageIfMissingColumnIndex($table, $db, $editable, $disp_mode)
1939 if (!empty($table) && ($GLOBALS['dbi']->isSystemSchema($db) || !$editable)) {
1940 $missing_unique_column_msg = PMA_message::notice(
1942 'Current selection does not contain a unique column.'
1943 . ' Grid edit, checkbox, Edit, Copy and Delete features'
1944 . ' are not available.'
1947 } else {
1948 $missing_unique_column_msg = null;
1951 return $missing_unique_column_msg;
1955 * Function to get html to display problems in indexes
1957 * @param string $query_type query type
1958 * @param bool $selected whether check table, optimize table, analyze
1959 * table or repair table has been selected with
1960 * respect to the selected tables from the
1961 * database structure page.
1962 * @param string $db current database
1964 * @return string
1966 function PMA_getHtmlForIndexesProblems($query_type, $selected, $db)
1968 // BEGIN INDEX CHECK See if indexes should be checked.
1969 if (isset($query_type)
1970 && $query_type == 'check_tbl'
1971 && isset($selected)
1972 && is_array($selected)
1974 $indexes_problems_html = '';
1975 foreach ($selected as $tbl_name) {
1976 $check = PMA_Index::findDuplicates($tbl_name, $db);
1977 if (! empty($check)) {
1978 $indexes_problems_html .= sprintf(
1979 __('Problems with indexes of table `%s`'), $tbl_name
1981 $indexes_problems_html .= $check;
1984 } else {
1985 $indexes_problems_html = null;
1988 return $indexes_problems_html;
1992 * Function to get the html for the print button in printview
1994 * @return string $print_button_html html for the print button
1996 function PMA_getHtmlForPrintButton()
1998 // Do print the page if required
1999 if (isset($_REQUEST['printview']) && $_REQUEST['printview'] == '1') {
2000 $print_button_html = PMA_Util::getButton();
2001 } else {
2002 $print_button_html = null;
2005 return $print_button_html;
2009 * Function to display results when the executed query returns non empty results
2011 * @param array $result executed query results
2012 * @param bool $justBrowsing whether just browsing or not
2013 * @param array $analyzed_sql_results analysed sql results
2014 * @param string $db current database
2015 * @param string $table current table
2016 * @param string $disp_mode display mode
2017 * @param string $message message to show
2018 * @param array $sql_data sql data
2019 * @param object $displayResultsObject Instance of DisplyResults.class
2020 * @param string $goto goto page url
2021 * @param string $pmaThemeImage uri of the theme image
2022 * @param string $sql_limit_to_append sql limit to append
2023 * @param int $unlim_num_rows unlimited number of rows
2024 * @param int $num_rows number of rows
2025 * @param string $full_sql_query full sql query
2026 * @param string $disp_query display query
2027 * @param string $disp_message display message
2028 * @param array $profiling_results profiling results
2029 * @param string $query_type query type
2030 * @param bool $selected whether check table, optimize table, analyze
2031 * table or repair table has been selected with
2032 * respect to the selected tables from the
2033 * database structure page.
2034 * @param string $sql_query sql query
2035 * @param string $complete_query complete sql query
2037 * @return void
2039 function PMA_sendQueryResponseForResultsReturned($result, $justBrowsing,
2040 $analyzed_sql_results, $db, $table, $disp_mode, $message, $sql_data,
2041 $displayResultsObject, $goto, $pmaThemeImage, $sql_limit_to_append,
2042 $unlim_num_rows, $num_rows, $full_sql_query, $disp_query,
2043 $disp_message, $profiling_results, $query_type, $selected, $sql_query,
2044 $complete_query
2046 // If we are retrieving the full value of a truncated field or the original
2047 // value of a transformed field, show it here
2048 if (isset($_REQUEST['grid_edit']) && $_REQUEST['grid_edit'] == true) {
2049 PMA_sendResponseForGridEdit($result);
2050 // script has exited at this point
2053 // Gets the list of fields properties
2054 if (isset($result) && $result) {
2055 $fields_meta = $GLOBALS['dbi']->getFieldsMeta($result);
2058 // Should be initialized these parameters before parsing
2059 $showtable = isset($showtable) ? $showtable : null;
2060 $url_query = isset($url_query) ? $url_query : null;
2062 $response = PMA_Response::getInstance();
2063 $header = $response->getHeader();
2064 $scripts = $header->getScripts();
2066 // hide edit and delete links:
2067 // - for information_schema
2068 // - if the result set does not contain all the columns of a unique key
2069 // (unless this is an updatable view)
2071 $sele_exp_cls = $analyzed_sql_results['analyzed_sql'][0]['select_expr_clause'];
2072 $updatableView
2073 = trim($sele_exp_cls) == '*'
2074 && PMA_Table::isUpdatableView($db, $table);
2076 $has_unique = PMA_resultSetContainsUniqueKey(
2077 $db, $table, $fields_meta
2080 $just_one_table = PMA_resultSetHasJustOneTable($fields_meta);
2082 $editable = ($has_unique || $updatableView) && $just_one_table;
2084 // Displays the results in a table
2085 if (empty($disp_mode)) {
2086 // see the "PMA_setDisplayMode()" function in
2087 // libraries/DisplayResults.class.php
2088 $disp_mode = 'urdr111101';
2090 if (!empty($table) && ($GLOBALS['dbi']->isSystemSchema($db) || !$editable)) {
2091 $disp_mode = 'nnnn110111';
2093 if ( isset($_REQUEST['printview']) && $_REQUEST['printview'] == '1') {
2094 $disp_mode = 'nnnn000000';
2097 if (isset($_REQUEST['table_maintenance'])) {
2098 $scripts->addFile('makegrid.js');
2099 $scripts->addFile('sql.js');
2100 $table_maintenance_html = '';
2101 if (isset($message)) {
2102 $message = PMA_Message::success($message);
2103 $table_maintenance_html = PMA_Util::getMessage(
2104 $message, $GLOBALS['sql_query'], 'success'
2107 $table_maintenance_html .= PMA_getHtmlForSqlQueryResultsTable(
2108 isset($sql_data) ? $sql_data : null, $displayResultsObject, $db, $goto,
2109 $pmaThemeImage, $url_query, $disp_mode, $sql_limit_to_append,
2110 false, $unlim_num_rows, $num_rows, $showtable, $result,
2111 $analyzed_sql_results
2113 if (empty($sql_data) || ($sql_data['valid_queries'] = 1)) {
2114 $response->addHTML($table_maintenance_html);
2115 exit();
2119 if (!isset($_REQUEST['printview']) || $_REQUEST['printview'] != '1') {
2120 $scripts->addFile('makegrid.js');
2121 $scripts->addFile('sql.js');
2122 unset($GLOBALS['message']);
2123 //we don't need to buffer the output in getMessage here.
2124 //set a global variable and check against it in the function
2125 $GLOBALS['buffer_message'] = false;
2128 $print_view_header_html = PMA_getHtmlForPrintViewHeader(
2129 $db, $full_sql_query, $num_rows
2132 $previous_update_query_html = PMA_getHtmlForPreviousUpdateQuery(
2133 isset($disp_query) ? $disp_query : null,
2134 $GLOBALS['cfg']['ShowSQL'], isset($sql_data) ? $sql_data : null,
2135 isset($disp_message) ? $disp_message : null
2138 $profiling_chart_html = PMA_getHtmlForProfilingChart(
2139 $disp_mode, $db, isset($profiling_results) ? $profiling_results : null
2142 $missing_unique_column_msg = PMA_getMessageIfMissingColumnIndex(
2143 $table, $db, $editable, $disp_mode
2146 $bookmark_created_msg = PMA_getBookmarkCreatedMessage();
2148 $table_html = PMA_getHtmlForSqlQueryResultsTable(
2149 isset($sql_data) ? $sql_data : null, $displayResultsObject, $db, $goto,
2150 $pmaThemeImage, $url_query, $disp_mode, $sql_limit_to_append,
2151 $editable, $unlim_num_rows, $num_rows, $showtable, $result,
2152 $analyzed_sql_results
2155 $indexes_problems_html = PMA_getHtmlForIndexesProblems(
2156 isset($query_type) ? $query_type : null,
2157 isset($selected) ? $selected : null, $db
2160 if (isset($GLOBALS['cfg']['Bookmark'])) {
2161 $bookmark_support_html = PMA_getHtmlForBookmark(
2162 $disp_mode,
2163 $GLOBALS['cfg']['Bookmark'],
2164 $sql_query, $db, $table,
2165 isset($complete_query) ? $complete_query : $sql_query,
2166 $GLOBALS['cfg']['Bookmark']['user']
2168 } else {
2169 $bookmark_support_html = '';
2172 $print_button_html = PMA_getHtmlForPrintButton();
2174 $html_output = isset($table_maintenance_html) ? $table_maintenance_html : '';
2176 $html_output .= isset($print_view_header_html) ? $print_view_header_html : '';
2178 $html_output .= PMA_getHtmlForSqlQueryResults(
2179 $previous_update_query_html, $profiling_chart_html,
2180 $missing_unique_column_msg, $bookmark_created_msg,
2181 $table_html, $indexes_problems_html, $bookmark_support_html,
2182 $print_button_html
2185 $response->addHTML($html_output);
2187 exit();
2191 * Function to send response for both empty results and non empty results
2193 * @param int $num_rows number of rows returned by the executed query
2194 * @param int $unlim_num_rows unlimited number of rows
2195 * @param bool $is_affected is affected
2196 * @param string $db current database
2197 * @param string $table current table
2198 * @param string $message_to_show message to show
2199 * @param array $analyzed_sql_results analyzed Sql Results
2200 * @param object $displayResultsObject Instance of DisplayResult class
2201 * @param array $extra_data extra data
2202 * @param array $result executed query results
2203 * @param bool $justBrowsing whether just browsing or not
2204 * @param string $disp_mode disply mode
2205 * @param object $message message
2206 * @param array $sql_data sql data
2207 * @param string $goto goto page url
2208 * @param string $pmaThemeImage uri of the PMA theme image
2209 * @param string $sql_limit_to_append sql limit to append
2210 * @param string $full_sql_query full sql query
2211 * @param string $disp_query display query
2212 * @param string $disp_message display message
2213 * @param array $profiling_results profiling results
2214 * @param string $query_type query type
2215 * @param bool $selected whether check table, optimize table, analyze
2216 * table or repair table has been selected with
2217 * respect to the selected tables from the
2218 * database structure page.
2219 * @param string $sql_query sql query
2220 * @param string $complete_query complete query
2222 * @return void
2224 function PMA_sendQueryResponse($num_rows, $unlim_num_rows, $is_affected,
2225 $db, $table, $message_to_show, $analyzed_sql_results, $displayResultsObject,
2226 $extra_data, $result, $justBrowsing, $disp_mode,$message, $sql_data,
2227 $goto, $pmaThemeImage, $sql_limit_to_append, $full_sql_query,
2228 $disp_query, $disp_message, $profiling_results, $query_type, $selected,
2229 $sql_query, $complete_query
2231 // No rows returned -> move back to the calling page
2232 if ((0 == $num_rows && 0 == $unlim_num_rows) || $is_affected) {
2233 PMA_sendQueryResponseForNoResultsReturned(
2234 $analyzed_sql_results, $db, $table,
2235 isset($message_to_show) ? $message_to_show : null,
2236 $num_rows, $displayResultsObject, $extra_data
2239 } else {
2240 // At least one row is returned -> displays a table with results
2241 PMA_sendQueryResponseForResultsReturned(
2242 isset($result) ? $result : null, $justBrowsing, $analyzed_sql_results,
2243 $db, $table, isset($disp_mode) ? $disp_mode : null,
2244 isset($message) ? $message : null, isset($sql_data) ? $sql_data : null,
2245 $displayResultsObject, $goto, $pmaThemeImage,
2246 $sql_limit_to_append, $unlim_num_rows,
2247 $num_rows, $full_sql_query,
2248 isset($disp_query) ? $disp_query : null,
2249 isset($disp_message) ? $disp_message : null, $profiling_results,
2250 isset($query_type) ? $query_type : null,
2251 isset($selected) ? $selected : null, $sql_query,
2252 isset($complete_query) ? $complete_query : null
2254 } // end rows returned
2258 * Function to execute the query and send the response
2260 * @param array $analyzed_sql_results analysed sql results
2261 * @param bool $is_gotofile whether goto file or not
2262 * @param string $db current database
2263 * @param string $table current table
2264 * @param bool|null $find_real_end whether to find real end or not
2265 * @param string $sql_query_for_bookmark the sql query to be stored as bookmark
2266 * @param array|null $extra_data extra data
2267 * @param bool $is_affected whether affected or not
2268 * @param string $message_to_show message to show
2269 * @param string $disp_mode display mode
2270 * @param string $message message
2271 * @param array|null $sql_data sql data
2272 * @param string $goto goto page url
2273 * @param string $pmaThemeImage uri of the PMA theme image
2274 * @param string $disp_query display query
2275 * @param string $disp_message display message
2276 * @param string $query_type query type
2277 * @param string $sql_query sql query
2278 * @param bool|null $selected whether check table, optimize table,
2279 * analyze table or repair table has been
2280 * selected with respect to the selected
2281 * tables from the database structure page
2282 * @param string $complete_query complete query
2284 * @return void
2286 function PMA_executeQueryAndSendQueryResponse($analyzed_sql_results,
2287 $is_gotofile, $db, $table, $find_real_end, $sql_query_for_bookmark,
2288 $extra_data, $is_affected, $message_to_show, $disp_mode, $message,
2289 $sql_data, $goto, $pmaThemeImage, $disp_query, $disp_message,
2290 $query_type, $sql_query, $selected, $complete_query
2292 // Include PMA_Index class for use in PMA_DisplayResults class
2293 include_once './libraries/Index.class.php';
2295 include 'libraries/DisplayResults.class.php';
2297 // Handle remembered sorting order, only for single table query
2298 // Handling is not required when it's a union query
2299 // (the parser never sets the 'union' key to 0)
2300 if (PMA_isRememberSortingOrder($analyzed_sql_results)
2301 && ! isset($analyzed_sql_results['analyzed_sql'][0]['queryflags']['union'])
2303 PMA_handleSortOrder($db, $table, $analyzed_sql_results, $sql_query);
2306 $displayResultsObject = new PMA_DisplayResults(
2307 $GLOBALS['db'], $GLOBALS['table'], $GLOBALS['goto'], $sql_query
2309 $displayResultsObject->setConfigParamsForDisplayTable();
2311 // assign default full_sql_query
2312 $full_sql_query = $sql_query;
2314 // Do append a "LIMIT" clause?
2315 if (PMA_isAppendLimitClause($analyzed_sql_results)) {
2316 list($sql_limit_to_append,
2317 $full_sql_query, $analyzed_display_query, $display_query
2318 ) = PMA_appendLimitClause(
2319 $full_sql_query, $analyzed_sql_results['analyzed_sql'],
2320 isset($display_query)
2322 } else {
2323 $sql_limit_to_append = '';
2326 $GLOBALS['reload'] = PMA_hasCurrentDbChanged($db);
2327 $GLOBALS['dbi']->selectDb($db);
2329 // Execute the query
2330 list($result, $num_rows, $unlim_num_rows, $profiling_results,
2331 $justBrowsing, $extra_data
2332 ) = PMA_executeTheQuery(
2333 $analyzed_sql_results,
2334 $full_sql_query,
2335 $is_gotofile,
2336 $db,
2337 $table,
2338 isset($find_real_end) ? $find_real_end : null,
2339 isset($sql_query_for_bookmark) ? $sql_query_for_bookmark : null,
2340 isset($extra_data) ? $extra_data : null
2343 PMA_sendQueryResponse(
2344 $num_rows,
2345 $unlim_num_rows,
2346 $is_affected,
2347 $db,
2348 $table,
2349 isset($message_to_show) ? $message_to_show : null,
2350 $analyzed_sql_results,
2351 $displayResultsObject,
2352 $extra_data,
2353 isset($result) ? $result : null,
2354 $justBrowsing,
2355 isset($disp_mode) ? $disp_mode : null,
2356 isset($message) ? $message : null,
2357 isset($sql_data) ? $sql_data : null,
2358 $goto,
2359 $pmaThemeImage,
2360 $sql_limit_to_append,
2361 $full_sql_query,
2362 isset($disp_query) ? $disp_query : null,
2363 isset($disp_message) ? $disp_message : null,
2364 $profiling_results,
2365 isset($query_type) ? $query_type : null,
2366 isset($selected) ? $selected : null,
2367 $sql_query,
2368 isset($complete_query) ? $complete_query : null
2373 * Function to define pos to display a row
2375 * @param Int $number_of_line Number of the line to display
2376 * @param Int $max_rows Number of rows by page
2378 * @return Int Start position to display the line
2380 function PMA_getStartPosToDisplayRow($number_of_line, $max_rows = null)
2382 if (null === $max_rows) {
2383 $max_rows = $_SESSION['tmpval']['max_rows'];
2386 return @((ceil($number_of_line / $max_rows) - 1) * $max_rows);
2390 * Function to calculate new pos if pos is higher than number of rows
2391 * of displayed table
2393 * @param String $db Database name
2394 * @param String $table Table name
2395 * @param Int $pos Initial position
2397 * @return Int Number of pos to display last page
2399 function PMA_calculatePosForLastPage($db, $table, $pos)
2401 if (null === $pos) {
2402 $pos = $_SESSION['tmpval']['pos'];
2405 $unlim_num_rows = PMA_Table::countRecords($db, $table, true);
2406 //If position is higher than number of rows
2407 if ($unlim_num_rows <= $pos && 0 != $pos) {
2408 $pos = PMA_getStartPosToDisplayRow($unlim_num_rows);
2411 return $pos;