sql.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * SQL executor
  5. *
  6. * @todo we must handle the case if sql.php is called directly with a query
  7. * that returns 0 rows - to prevent cyclic redirects or includes
  8. * @package PhpMyAdmin
  9. */
  10. use PhpMyAdmin\Config\PageSettings;
  11. use PhpMyAdmin\ParseAnalyze;
  12. use PhpMyAdmin\Response;
  13. use PhpMyAdmin\Sql;
  14. use PhpMyAdmin\Url;
  15. use PhpMyAdmin\Util;
  16. use PhpMyAdmin\Core;
  17. /**
  18. * Gets some core libraries
  19. */
  20. require_once 'libraries/common.inc.php';
  21. require_once 'libraries/check_user_privileges.inc.php';
  22. PageSettings::showGroup('Browse');
  23. $response = Response::getInstance();
  24. $header = $response->getHeader();
  25. $scripts = $header->getScripts();
  26. $scripts->addFile('vendor/jquery/jquery.uitablefilter.js');
  27. $scripts->addFile('tbl_change.js');
  28. $scripts->addFile('indexes.js');
  29. $scripts->addFile('gis_data_editor.js');
  30. $scripts->addFile('multi_column_sort.js');
  31. $sql = new Sql();
  32. /**
  33. * Set ajax_reload in the response if it was already set
  34. */
  35. if (isset($ajax_reload) && $ajax_reload['reload'] === true) {
  36. $response->addJSON('ajax_reload', $ajax_reload);
  37. }
  38. /**
  39. * Defines the url to return to in case of error in a sql statement
  40. */
  41. $is_gotofile = true;
  42. if (empty($goto)) {
  43. if (empty($table)) {
  44. $goto = Util::getScriptNameForOption(
  45. $GLOBALS['cfg']['DefaultTabDatabase'], 'database'
  46. );
  47. } else {
  48. $goto = Util::getScriptNameForOption(
  49. $GLOBALS['cfg']['DefaultTabTable'], 'table'
  50. );
  51. }
  52. } // end if
  53. if (! isset($err_url)) {
  54. $err_url = (! empty($back) ? $back : $goto)
  55. . '?' . Url::getCommon(array('db' => $GLOBALS['db']))
  56. . ((mb_strpos(' ' . $goto, 'db_') != 1
  57. && strlen($table) > 0)
  58. ? '&amp;table=' . urlencode($table)
  59. : ''
  60. );
  61. } // end if
  62. // Coming from a bookmark dialog
  63. if (isset($_POST['bkm_fields']['bkm_sql_query'])) {
  64. $sql_query = $_POST['bkm_fields']['bkm_sql_query'];
  65. } elseif (isset($_POST['sql_query'])) {
  66. $sql_query = $_POST['sql_query'];
  67. } elseif (isset($_GET['sql_query']) && isset($_GET['sql_signature'])) {
  68. if (Core::checkSqlQuerySignature($_GET['sql_query'], $_GET['sql_signature'])) {
  69. $sql_query = $_GET['sql_query'];
  70. }
  71. }
  72. // This one is just to fill $db
  73. if (isset($_POST['bkm_fields']['bkm_database'])) {
  74. $db = $_POST['bkm_fields']['bkm_database'];
  75. }
  76. // During grid edit, if we have a relational field, show the dropdown for it.
  77. if (isset($_POST['get_relational_values'])
  78. && $_POST['get_relational_values'] == true
  79. ) {
  80. $sql->getRelationalValues($db, $table);
  81. // script has exited at this point
  82. }
  83. // Just like above, find possible values for enum fields during grid edit.
  84. if (isset($_POST['get_enum_values']) && $_POST['get_enum_values'] == true) {
  85. $sql->getEnumOrSetValues($db, $table, "enum");
  86. // script has exited at this point
  87. }
  88. // Find possible values for set fields during grid edit.
  89. if (isset($_POST['get_set_values']) && $_POST['get_set_values'] == true) {
  90. $sql->getEnumOrSetValues($db, $table, "set");
  91. // script has exited at this point
  92. }
  93. if (isset($_GET['get_default_fk_check_value'])
  94. && $_GET['get_default_fk_check_value'] == true
  95. ) {
  96. $response = Response::getInstance();
  97. $response->addJSON(
  98. 'default_fk_check_value', Util::isForeignKeyCheck()
  99. );
  100. exit;
  101. }
  102. /**
  103. * Check ajax request to set the column order and visibility
  104. */
  105. if (isset($_POST['set_col_prefs']) && $_POST['set_col_prefs'] == true) {
  106. $sql->setColumnOrderOrVisibility($table, $db);
  107. // script has exited at this point
  108. }
  109. // Default to browse if no query set and we have table
  110. // (needed for browsing from DefaultTabTable)
  111. if (empty($sql_query) && strlen($table) > 0 && strlen($db) > 0) {
  112. $sql_query = $sql->getDefaultSqlQueryForBrowse($db, $table);
  113. // set $goto to what will be displayed if query returns 0 rows
  114. $goto = '';
  115. } else {
  116. // Now we can check the parameters
  117. Util::checkParameters(array('sql_query'));
  118. }
  119. /**
  120. * Parse and analyze the query
  121. */
  122. list(
  123. $analyzed_sql_results,
  124. $db,
  125. $table_from_sql
  126. ) = ParseAnalyze::sqlQuery($sql_query, $db);
  127. // @todo: possibly refactor
  128. extract($analyzed_sql_results);
  129. if ($table != $table_from_sql && !empty($table_from_sql)) {
  130. $table = $table_from_sql;
  131. }
  132. /**
  133. * Check rights in case of DROP DATABASE
  134. *
  135. * This test may be bypassed if $is_js_confirmed = 1 (already checked with js)
  136. * but since a malicious user may pass this variable by url/form, we don't take
  137. * into account this case.
  138. */
  139. if ($sql->hasNoRightsToDropDatabase(
  140. $analyzed_sql_results, $cfg['AllowUserDropDatabase'], $GLOBALS['dbi']->isSuperuser()
  141. )) {
  142. Util::mysqlDie(
  143. __('"DROP DATABASE" statements are disabled.'),
  144. '',
  145. false,
  146. $err_url
  147. );
  148. } // end if
  149. /**
  150. * Need to find the real end of rows?
  151. */
  152. if (isset($find_real_end) && $find_real_end) {
  153. $unlim_num_rows = $sql->findRealEndOfRows($db, $table);
  154. }
  155. /**
  156. * Bookmark add
  157. */
  158. if (isset($_POST['store_bkm'])) {
  159. $sql->addBookmark($goto);
  160. // script has exited at this point
  161. } // end if
  162. /**
  163. * Sets or modifies the $goto variable if required
  164. */
  165. if ($goto == 'sql.php') {
  166. $is_gotofile = false;
  167. $goto = 'sql.php' . Url::getCommon(
  168. array(
  169. 'db' => $db,
  170. 'table' => $table,
  171. 'sql_query' => $sql_query
  172. )
  173. );
  174. } // end if
  175. $sql->executeQueryAndSendQueryResponse(
  176. $analyzed_sql_results, // analyzed_sql_results
  177. $is_gotofile, // is_gotofile
  178. $db, // db
  179. $table, // table
  180. isset($find_real_end) ? $find_real_end : null, // find_real_end
  181. isset($import_text) ? $import_text : null, // sql_query_for_bookmark
  182. isset($extra_data) ? $extra_data : null, // extra_data
  183. isset($message_to_show) ? $message_to_show : null, // message_to_show
  184. isset($message) ? $message : null, // message
  185. isset($sql_data) ? $sql_data : null, // sql_data
  186. $goto, // goto
  187. $pmaThemeImage, // pmaThemeImage
  188. isset($disp_query) ? $display_query : null, // disp_query
  189. isset($disp_message) ? $disp_message : null, // disp_message
  190. isset($query_type) ? $query_type : null, // query_type
  191. $sql_query, // sql_query
  192. isset($selected) ? $selected : null, // selectedTables
  193. isset($complete_query) ? $complete_query : null // complete_query
  194. );