sql.lib.php 84 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * set of functions for the sql executor
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (!defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * Get the database name inside a query
  13. *
  14. * @param string $sql SQL query
  15. * @param array $databases array with all databases
  16. *
  17. * @return string $db new database name
  18. */
  19. function PMA_getNewDatabase($sql, $databases)
  20. {
  21. $db = '';
  22. // loop through all the databases
  23. foreach ($databases as $database) {
  24. if (strpos($sql, $database['SCHEMA_NAME']) !== false) {
  25. $db = $database['SCHEMA_NAME'];
  26. break;
  27. }
  28. }
  29. return $db;
  30. }
  31. /**
  32. * Get the table name in a sql query
  33. * If there are several tables in the SQL query,
  34. * first table wil lreturn
  35. *
  36. * @param string $sql SQL query
  37. * @param array $tables array of names in current database
  38. *
  39. * @return string $table table name
  40. */
  41. function PMA_getTableNameBySQL($sql, $tables)
  42. {
  43. $table = '';
  44. // loop through all the tables in the database
  45. foreach ($tables as $tbl) {
  46. if (strpos($sql, $tbl)) {
  47. $table .= ' ' . $tbl;
  48. }
  49. }
  50. if (count(explode(' ', trim($table))) > 1) {
  51. $tmp_array = explode(' ', trim($table));
  52. return $tmp_array[0];
  53. }
  54. return trim($table);
  55. }
  56. /**
  57. * Generate table html when SQL statement have multiple queries
  58. * which return displayable results
  59. *
  60. * @param object $displayResultsObject PMA_DisplayResults object
  61. * @param string $db database name
  62. * @param array $sql_data information about SQL statement
  63. * @param string $goto URL to go back in case of errors
  64. * @param string $pmaThemeImage path for theme images directory
  65. * @param string $printview whether printview is enabled
  66. * @param string $url_query URL query
  67. * @param array $disp_mode the display mode
  68. * @param string $sql_limit_to_append limit clause
  69. * @param bool $editable whether editable or not
  70. *
  71. * @return string $table_html html content
  72. */
  73. function PMA_getTableHtmlForMultipleQueries(
  74. $displayResultsObject, $db, $sql_data, $goto, $pmaThemeImage,
  75. $printview, $url_query, $disp_mode, $sql_limit_to_append,
  76. $editable
  77. ) {
  78. $table_html = '';
  79. $tables_array = $GLOBALS['dbi']->getTables($db);
  80. $databases_array = $GLOBALS['dbi']->getDatabasesFull();
  81. $multi_sql = implode(";", $sql_data['valid_sql']);
  82. $querytime_before = array_sum(explode(' ', microtime()));
  83. // Assignment for variable is not needed since the results are
  84. // looping using the connection
  85. @$GLOBALS['dbi']->tryMultiQuery($multi_sql);
  86. $querytime_after = array_sum(explode(' ', microtime()));
  87. $querytime = $querytime_after - $querytime_before;
  88. $sql_no = 0;
  89. do {
  90. $analyzed_sql = array();
  91. $is_affected = false;
  92. $result = $GLOBALS['dbi']->storeResult();
  93. $fields_meta = ($result !== false)
  94. ? $GLOBALS['dbi']->getFieldsMeta($result)
  95. : array();
  96. $fields_cnt = count($fields_meta);
  97. // Initialize needed params related to each query in multiquery statement
  98. if (isset($sql_data['valid_sql'][$sql_no])) {
  99. // 'Use' query can change the database
  100. if (stripos($sql_data['valid_sql'][$sql_no], "use ")) {
  101. $db = PMA_getNewDatabase(
  102. $sql_data['valid_sql'][$sql_no],
  103. $databases_array
  104. );
  105. }
  106. $table = PMA_getTableNameBySQL(
  107. $sql_data['valid_sql'][$sql_no],
  108. $tables_array
  109. );
  110. // for the use of the parse_analyze.inc.php
  111. $sql_query = $sql_data['valid_sql'][$sql_no];
  112. // Parse and analyze the query
  113. include 'libraries/parse_analyze.inc.php';
  114. $unlim_num_rows = PMA_Table::countRecords($db, $table, true);
  115. $showtable = PMA_Table::sGetStatusInfo($db, $table, null, true);
  116. $url_query = PMA_URL_getCommon($db, $table);
  117. // Handle remembered sorting order, only for single table query
  118. if ($GLOBALS['cfg']['RememberSorting']
  119. && ! ($is_count || $is_export || $is_func || $is_analyse)
  120. && isset($analyzed_sql[0]['select_expr'])
  121. && (count($analyzed_sql[0]['select_expr']) == 0)
  122. && isset($analyzed_sql[0]['queryflags']['select_from'])
  123. && count($analyzed_sql[0]['table_ref']) == 1
  124. ) {
  125. PMA_handleSortOrder(
  126. $db,
  127. $table,
  128. $analyzed_sql,
  129. $sql_data['valid_sql'][$sql_no]
  130. );
  131. }
  132. // Do append a "LIMIT" clause?
  133. if (($_SESSION['tmpval']['max_rows'] != 'all')
  134. && ! ($is_count || $is_export || $is_func || $is_analyse)
  135. && isset($analyzed_sql[0]['queryflags']['select_from'])
  136. && ! isset($analyzed_sql[0]['queryflags']['offset'])
  137. && empty($analyzed_sql[0]['limit_clause'])
  138. ) {
  139. $sql_limit_to_append = ' LIMIT '
  140. . $_SESSION['tmpval']['pos']
  141. . ', ' . $_SESSION['tmpval']['max_rows'] . " ";
  142. $sql_data['valid_sql'][$sql_no] = PMA_getSqlWithLimitClause(
  143. $sql_data['valid_sql'][$sql_no],
  144. $analyzed_sql,
  145. $sql_limit_to_append
  146. );
  147. }
  148. // Set the needed properties related to executing sql query
  149. $displayResultsObject->__set('db', $db);
  150. $displayResultsObject->__set('table', $table);
  151. $displayResultsObject->__set('goto', $goto);
  152. }
  153. if (! $is_affected) {
  154. $num_rows = ($result) ? @$GLOBALS['dbi']->numRows($result) : 0;
  155. } elseif (! isset($num_rows)) {
  156. $num_rows = @$GLOBALS['dbi']->affectedRows();
  157. }
  158. if (isset($sql_data['valid_sql'][$sql_no])) {
  159. $displayResultsObject->__set(
  160. 'sql_query',
  161. $sql_data['valid_sql'][$sql_no]
  162. );
  163. $displayResultsObject->setProperties(
  164. $unlim_num_rows, $fields_meta, $is_count, $is_export, $is_func,
  165. $is_analyse, $num_rows, $fields_cnt, $querytime, $pmaThemeImage,
  166. $GLOBALS['text_dir'], $is_maint, $is_explain, $is_show,
  167. $showtable, $printview, $url_query, $editable
  168. );
  169. }
  170. if ($num_rows == 0) {
  171. continue;
  172. }
  173. // With multiple results, operations are limied
  174. $disp_mode = 'nnnn000000';
  175. $is_limited_display = true;
  176. // Collect the tables
  177. $table_html .= $displayResultsObject->getTable(
  178. $result, $disp_mode, $analyzed_sql, $is_limited_display
  179. );
  180. // Free the result to save the memory
  181. $GLOBALS['dbi']->freeResult($result);
  182. $sql_no++;
  183. } while ($GLOBALS['dbi']->moreResults() && $GLOBALS['dbi']->nextResult());
  184. return $table_html;
  185. }
  186. /**
  187. * Handle remembered sorting order, only for single table query
  188. *
  189. * @param string $db database name
  190. * @param string $table table name
  191. * @param array &$analyzed_sql_results the analyzed query results
  192. * @param string &$full_sql_query SQL query
  193. *
  194. * @return void
  195. */
  196. function PMA_handleSortOrder(
  197. $db, $table, &$analyzed_sql_results, &$full_sql_query
  198. ) {
  199. $pmatable = new PMA_Table($table, $db);
  200. if (empty($analyzed_sql_results['analyzed_sql'][0]['order_by_clause'])) {
  201. $sorted_col = $pmatable->getUiProp(PMA_Table::PROP_SORTED_COLUMN);
  202. if ($sorted_col) {
  203. //remove the tablename from retrieved preference
  204. //to get just the column name and the sort order
  205. $sorted_col = str_replace(
  206. PMA_Util::backquote($table) . '.', '', $sorted_col
  207. );
  208. // retrieve the remembered sorting order for current table
  209. $sql_order_to_append = ' ORDER BY ' . $sorted_col . ' ';
  210. $full_sql_query
  211. = $analyzed_sql_results['analyzed_sql'][0]['section_before_limit']
  212. . $sql_order_to_append
  213. . $analyzed_sql_results['analyzed_sql'][0]['limit_clause']
  214. . ' '
  215. . $analyzed_sql_results['analyzed_sql'][0]['section_after_limit'];
  216. // update the $analyzed_sql
  217. $analyzed_sql_results['analyzed_sql'][0]['section_before_limit']
  218. .= $sql_order_to_append;
  219. $analyzed_sql_results['analyzed_sql'][0]['order_by_clause']
  220. = $sorted_col;
  221. }
  222. } else {
  223. // store the remembered table into session
  224. $pmatable->setUiProp(
  225. PMA_Table::PROP_SORTED_COLUMN,
  226. $analyzed_sql_results['analyzed_sql'][0]['order_by_clause']
  227. );
  228. }
  229. }
  230. /**
  231. * Append limit clause to SQL query
  232. *
  233. * @param string $full_sql_query SQL query
  234. * @param array $analyzed_sql the analyzed query
  235. * @param string $sql_limit_to_append clause to append
  236. *
  237. * @return string limit clause appended SQL query
  238. */
  239. function PMA_getSqlWithLimitClause($full_sql_query, $analyzed_sql,
  240. $sql_limit_to_append
  241. ) {
  242. return $analyzed_sql[0]['section_before_limit'] . "\n"
  243. . $sql_limit_to_append . $analyzed_sql[0]['section_after_limit'];
  244. }
  245. /**
  246. * Get column name from a drop SQL statement
  247. *
  248. * @param string $sql SQL query
  249. *
  250. * @return string $drop_column Name of the column
  251. */
  252. function PMA_getColumnNameInColumnDropSql($sql)
  253. {
  254. $tmpArray1 = explode('DROP', $sql);
  255. $str_to_check = trim($tmpArray1[1]);
  256. if (stripos($str_to_check, 'COLUMN') !== false) {
  257. $tmpArray2 = explode('COLUMN', $str_to_check);
  258. $str_to_check = trim($tmpArray2[1]);
  259. }
  260. $tmpArray3 = explode(' ', $str_to_check);
  261. $str_to_check = trim($tmpArray3[0]);
  262. $drop_column = str_replace(';', '', trim($str_to_check));
  263. $drop_column = str_replace('`', '', $drop_column);
  264. return $drop_column;
  265. }
  266. /**
  267. * Verify whether the result set has columns from just one table
  268. *
  269. * @param array $fields_meta meta fields
  270. *
  271. * @return boolean whether the result set has columns from just one table
  272. */
  273. function PMA_resultSetHasJustOneTable($fields_meta)
  274. {
  275. $just_one_table = true;
  276. $prev_table = $fields_meta[0]->table;
  277. foreach ($fields_meta as $one_field_meta) {
  278. if (! empty($one_field_meta->table)
  279. && $one_field_meta->table != $prev_table
  280. ) {
  281. $just_one_table = false;
  282. break;
  283. }
  284. }
  285. return $just_one_table;
  286. }
  287. /**
  288. * Verify whether the result set contains all the columns
  289. * of at least one unique key
  290. *
  291. * @param string $db database name
  292. * @param string $table table name
  293. * @param array $fields_meta meta fields
  294. *
  295. * @return boolean whether the result set contains a unique key
  296. */
  297. function PMA_resultSetContainsUniqueKey($db, $table, $fields_meta)
  298. {
  299. $resultSetColumnNames = array();
  300. foreach ($fields_meta as $oneMeta) {
  301. $resultSetColumnNames[] = $oneMeta->name;
  302. }
  303. foreach (PMA_Index::getFromTable($table, $db) as $index) {
  304. if ($index->isUnique()) {
  305. $indexColumns = $index->getColumns();
  306. $numberFound = 0;
  307. foreach ($indexColumns as $indexColumnName => $dummy) {
  308. if (in_array($indexColumnName, $resultSetColumnNames)) {
  309. $numberFound++;
  310. }
  311. }
  312. if ($numberFound == count($indexColumns)) {
  313. return true;
  314. }
  315. }
  316. }
  317. return false;
  318. }
  319. /**
  320. * Get the HTML for relational column dropdown
  321. * During grid edit, if we have a relational field, returns the html for the
  322. * dropdown
  323. *
  324. * @param string $db current database
  325. * @param string $table current table
  326. * @param string $column current column
  327. * @param string $curr_value current selected value
  328. *
  329. * @return string $dropdown html for the dropdown
  330. */
  331. function PMA_getHtmlForRelationalColumnDropdown($db, $table, $column, $curr_value)
  332. {
  333. $foreigners = PMA_getForeigners($db, $table, $column);
  334. $foreignData = PMA_getForeignData($foreigners, $column, false, '', '');
  335. if ($foreignData['disp_row'] == null) {
  336. //Handle the case when number of values
  337. //is more than $cfg['ForeignKeyMaxLimit']
  338. $_url_params = array(
  339. 'db' => $db,
  340. 'table' => $table,
  341. 'field' => $column
  342. );
  343. $dropdown = '<span class="curr_value">'
  344. . htmlspecialchars($_REQUEST['curr_value'])
  345. . '</span>'
  346. . '<a href="browse_foreigners.php'
  347. . PMA_URL_getCommon($_url_params) . '"'
  348. . ' target="_blank" class="browse_foreign" ' . '>'
  349. . __('Browse foreign values')
  350. . '</a>';
  351. } else {
  352. $dropdown = PMA_foreignDropdown(
  353. $foreignData['disp_row'],
  354. $foreignData['foreign_field'],
  355. $foreignData['foreign_display'],
  356. $curr_value,
  357. $GLOBALS['cfg']['ForeignKeyMaxLimit']
  358. );
  359. $dropdown = '<select>' . $dropdown . '</select>';
  360. }
  361. return $dropdown;
  362. }
  363. /**
  364. * Get the HTML for the header of the page in print view if print view is selected.
  365. * Otherwise returns null.
  366. *
  367. * @param string $db current database
  368. * @param string $sql_query current sql query
  369. * @param int $num_rows the number of rows in result
  370. *
  371. * @return string $header html for the header
  372. */
  373. function PMA_getHtmlForPrintViewHeader($db, $sql_query, $num_rows)
  374. {
  375. $response = PMA_Response::getInstance();
  376. $header = $response->getHeader();
  377. if (isset($_REQUEST['printview']) && $_REQUEST['printview'] == '1') {
  378. PMA_Util::checkParameters(array('db', 'sql_query'));
  379. $header->enablePrintView();
  380. $hostname = '';
  381. if ( $GLOBALS['cfg']['Server']['verbose']) {
  382. $hostname = $GLOBALS['cfg']['Server']['verbose'];
  383. } else {
  384. $hostname = $GLOBALS['cfg']['Server']['host'];
  385. if (! empty( $GLOBALS['cfg']['Server']['port'])) {
  386. $hostname .= $GLOBALS['cfg']['Server']['port'];
  387. }
  388. }
  389. $versions = "phpMyAdmin&nbsp;" . PMA_VERSION;
  390. $versions .= "&nbsp;/&nbsp;";
  391. $versions .= "MySQL&nbsp;" . PMA_MYSQL_STR_VERSION;
  392. $print_view_header = '';
  393. $print_view_header .= "<h1>" . __('SQL result') . "</h1>";
  394. $print_view_header .= "<p>";
  395. $print_view_header .= "<strong>" . __('Host:')
  396. . "</strong> $hostname<br />";
  397. $print_view_header .= "<strong>" . __('Database:') . "</strong> "
  398. . htmlspecialchars($db) . "<br />";
  399. $print_view_header .= "<strong>" . __('Generation Time:') . "</strong> "
  400. . PMA_Util::localisedDate() . "<br />";
  401. $print_view_header .= "<strong>" . __('Generated by:')
  402. . "</strong> $versions<br />";
  403. $print_view_header .= "<strong>" . __('SQL query:') . "</strong> "
  404. . htmlspecialchars($sql_query) . ";";
  405. if (isset($num_rows)) {
  406. $print_view_header .= "<br />";
  407. $print_view_header .= "<strong>" . __('Rows:') . "</strong> $num_rows";
  408. }
  409. $print_view_header .= "</p>";
  410. } else {
  411. $print_view_header = null;
  412. }
  413. return $print_view_header;
  414. }
  415. /**
  416. * Get the HTML for the profiling table and accompanying chart if profiling is set.
  417. * Otherwise returns null
  418. *
  419. * @param string $url_query url query
  420. * @param string $db current database
  421. * @param array $profiling_results array containing the profiling info
  422. *
  423. * @return string $profiling_table html for the profiling table and chart
  424. */
  425. function PMA_getHtmlForProfilingChart($url_query, $db, $profiling_results)
  426. {
  427. if (isset($profiling_results)) {
  428. $pma_token = $_SESSION[' PMA_token '];
  429. $url_query = (isset($url_query) ? $url_query : PMA_URL_getCommon($db));
  430. $profiling_table = '';
  431. $profiling_table .= '<fieldset><legend>' . __('Profiling')
  432. . '</legend>' . "\n";
  433. $profiling_table .= '<div style="float: left;">';
  434. $profiling_table .= '<h3>' . __('Detailed profile') . '</h3>';
  435. $profiling_table .= '<table id="profiletable"><thead>' . "\n";
  436. $profiling_table .= ' <tr>' . "\n";
  437. $profiling_table .= ' <th>' . __('Order')
  438. . '<div class="sorticon"></div></th>' . "\n";
  439. $profiling_table .= ' <th>' . __('State')
  440. . PMA_Util::showMySQLDocu('general-thread-states')
  441. . '<div class="sorticon"></div></th>' . "\n";
  442. $profiling_table .= ' <th>' . __('Time')
  443. . '<div class="sorticon"></div></th>' . "\n";
  444. $profiling_table .= ' </tr></thead><tbody>' . "\n";
  445. list($detailed_table, $chart_json, $profiling_stats)
  446. = PMA_analyzeAndGetTableHtmlForProfilingResults($profiling_results);
  447. $profiling_table .= $detailed_table;
  448. $profiling_table .= '</tbody></table>' . "\n";
  449. $profiling_table .= '</div>';
  450. $profiling_table .= '<div style="float: left; margin-left:10px;">';
  451. $profiling_table .= '<h3>' . __('Summary by state') . '</h3>';
  452. $profiling_table .= '<table id="profilesummarytable"><thead>' . "\n";
  453. $profiling_table .= ' <tr>' . "\n";
  454. $profiling_table .= ' <th>' . __('State')
  455. . PMA_Util::showMySQLDocu('general-thread-states')
  456. . '<div class="sorticon"></div></th>' . "\n";
  457. $profiling_table .= ' <th>' . __('Total Time')
  458. . '<div class="sorticon"></div></th>' . "\n";
  459. $profiling_table .= ' <th>' . __('% Time')
  460. . '<div class="sorticon"></div></th>' . "\n";
  461. $profiling_table .= ' <th>' . __('Calls')
  462. . '<div class="sorticon"></div></th>' . "\n";
  463. $profiling_table .= ' <th>' . __('ø Time')
  464. . '<div class="sorticon"></div></th>' . "\n";
  465. $profiling_table .= ' </tr></thead><tbody>' . "\n";
  466. $profiling_table .= PMA_getTableHtmlForProfilingSummaryByState(
  467. $profiling_stats
  468. );
  469. $profiling_table .= '</tbody></table>' . "\n";
  470. $profiling_table .= <<<EOT
  471. <script type="text/javascript">
  472. pma_token = '$pma_token';
  473. url_query = '$url_query';
  474. </script>
  475. EOT;
  476. $profiling_table .= "</div>";
  477. $profiling_table .= "<div class='clearfloat'></div>";
  478. //require_once 'libraries/chart.lib.php';
  479. $profiling_table .= '<div id="profilingChartData" style="display:none;">';
  480. $profiling_table .= json_encode($chart_json);
  481. $profiling_table .= '</div>';
  482. $profiling_table .= '<div id="profilingchart" style="display:none;">';
  483. $profiling_table .= '</div>';
  484. $profiling_table .= '<script type="text/javascript">';
  485. $profiling_table .= "AJAX.registerOnload('sql.js', function () {";
  486. $profiling_table .= 'makeProfilingChart();';
  487. $profiling_table .= 'initProfilingTables();';
  488. $profiling_table .= '});';
  489. $profiling_table .= '</script>';
  490. $profiling_table .= '</fieldset>' . "\n";
  491. } else {
  492. $profiling_table = null;
  493. }
  494. return $profiling_table;
  495. }
  496. /**
  497. * Function to get HTML for detailed profiling results table, profiling stats, and
  498. * $chart_json for displaying the chart.
  499. *
  500. * @param array $profiling_results profiling results
  501. *
  502. * @return mixed
  503. */
  504. function PMA_analyzeAndGetTableHtmlForProfilingResults(
  505. $profiling_results
  506. ) {
  507. $profiling_stats = array(
  508. 'total_time' => 0,
  509. 'states' => array(),
  510. );
  511. $chart_json = Array();
  512. $i = 1;
  513. $table = '';
  514. foreach ($profiling_results as $one_result) {
  515. if (isset($profiling_stats['states'][ucwords($one_result['Status'])])) {
  516. $states = $profiling_stats['states'];
  517. $states[ucwords($one_result['Status'])]['time']
  518. += $one_result['Duration'];
  519. $states[ucwords($one_result['Status'])]['calls']++;
  520. } else {
  521. $profiling_stats['states'][ucwords($one_result['Status'])] = array(
  522. 'total_time' => $one_result['Duration'],
  523. 'calls' => 1,
  524. );
  525. }
  526. $profiling_stats['total_time'] += $one_result['Duration'];
  527. $table .= ' <tr>' . "\n";
  528. $table .= '<td>' . $i++ . '</td>' . "\n";
  529. $table .= '<td>' . ucwords($one_result['Status'])
  530. . '</td>' . "\n";
  531. $table .= '<td class="right">'
  532. . (PMA_Util::formatNumber($one_result['Duration'], 3, 1))
  533. . 's<span style="display:none;" class="rawvalue">'
  534. . $one_result['Duration'] . '</span></td>' . "\n";
  535. if (isset($chart_json[ucwords($one_result['Status'])])) {
  536. $chart_json[ucwords($one_result['Status'])]
  537. += $one_result['Duration'];
  538. } else {
  539. $chart_json[ucwords($one_result['Status'])]
  540. = $one_result['Duration'];
  541. }
  542. }
  543. return array($table, $chart_json, $profiling_stats);
  544. }
  545. /**
  546. * Function to get HTML for summary by state table
  547. *
  548. * @param array $profiling_stats profiling stats
  549. *
  550. * @return string $table html for the table
  551. */
  552. function PMA_getTableHtmlForProfilingSummaryByState($profiling_stats)
  553. {
  554. $table = '';
  555. foreach ($profiling_stats['states'] as $name => $stats) {
  556. $table .= ' <tr>' . "\n";
  557. $table .= '<td>' . $name . '</td>' . "\n";
  558. $table .= '<td align="right">'
  559. . PMA_Util::formatNumber($stats['total_time'], 3, 1)
  560. . 's<span style="display:none;" class="rawvalue">'
  561. . $stats['total_time'] . '</span></td>' . "\n";
  562. $table .= '<td align="right">'
  563. . PMA_Util::formatNumber(
  564. 100 * ($stats['total_time'] / $profiling_stats['total_time']),
  565. 0, 2
  566. )
  567. . '%</td>' . "\n";
  568. $table .= '<td align="right">' . $stats['calls'] . '</td>'
  569. . "\n";
  570. $table .= '<td align="right">'
  571. . PMA_Util::formatNumber(
  572. $stats['total_time'] / $stats['calls'], 3, 1
  573. )
  574. . 's<span style="display:none;" class="rawvalue">'
  575. . number_format($stats['total_time'] / $stats['calls'], 8, '.', '')
  576. . '</span></td>' . "\n";
  577. $table .= ' </tr>' . "\n";
  578. }
  579. return $table;
  580. }
  581. /**
  582. * Get the HTML for the enum column dropdown
  583. * During grid edit, if we have a enum field, returns the html for the
  584. * dropdown
  585. *
  586. * @param string $db current database
  587. * @param string $table current table
  588. * @param string $column current column
  589. * @param string $curr_value currently selected value
  590. *
  591. * @return string $dropdown html for the dropdown
  592. */
  593. function PMA_getHtmlForEnumColumnDropdown($db, $table, $column, $curr_value)
  594. {
  595. $values = PMA_getValuesForColumn($db, $table, $column);
  596. $dropdown = '<option value="">&nbsp;</option>';
  597. $dropdown .= PMA_getHtmlForOptionsList($values, array($curr_value));
  598. $dropdown = '<select>' . $dropdown . '</select>';
  599. return $dropdown;
  600. }
  601. /**
  602. * Get the HTML for the set column dropdown
  603. * During grid edit, if we have a set field, returns the html for the
  604. * dropdown
  605. *
  606. * @param string $db current database
  607. * @param string $table current table
  608. * @param string $column current column
  609. * @param string $curr_value currently selected value
  610. *
  611. * @return string $dropdown html for the set column
  612. */
  613. function PMA_getHtmlForSetColumn($db, $table, $column, $curr_value)
  614. {
  615. $values = PMA_getValuesForColumn($db, $table, $column);
  616. $dropdown = '';
  617. //converts characters of $curr_value to HTML entities
  618. $converted_curr_value = htmlentities(
  619. $curr_value, ENT_COMPAT, "UTF-8"
  620. );
  621. $selected_values = explode(',', $converted_curr_value);
  622. $dropdown .= PMA_getHtmlForOptionsList($values, $selected_values);
  623. $select_size = (sizeof($values) > 10) ? 10 : sizeof($values);
  624. $dropdown = '<select multiple="multiple" size="' . $select_size . '">'
  625. . $dropdown . '</select>';
  626. return $dropdown;
  627. }
  628. /**
  629. * Get all the values for a enum column or set column in a table
  630. *
  631. * @param string $db current database
  632. * @param string $table current table
  633. * @param string $column current column
  634. *
  635. * @return array $values array containing the value list for the column
  636. */
  637. function PMA_getValuesForColumn($db, $table, $column)
  638. {
  639. $field_info_query = $GLOBALS['dbi']->getColumnsSql($db, $table, $column);
  640. $field_info_result = $GLOBALS['dbi']->fetchResult(
  641. $field_info_query, null, null, null, PMA_DatabaseInterface::QUERY_STORE
  642. );
  643. $values = PMA_Util::parseEnumSetValues($field_info_result[0]['Type']);
  644. return $values;
  645. }
  646. /**
  647. * Get HTML for options list
  648. *
  649. * @param array $values set of values
  650. * @param array $selected_values currently selected values
  651. *
  652. * @return string $options HTML for options list
  653. */
  654. function PMA_getHtmlForOptionsList($values, $selected_values)
  655. {
  656. $options = '';
  657. foreach ($values as $value) {
  658. $options .= '<option value="' . $value . '"';
  659. if (in_array($value, $selected_values, true)) {
  660. $options .= ' selected="selected" ';
  661. }
  662. $options .= '>' . $value . '</option>';
  663. }
  664. return $options;
  665. }
  666. /**
  667. * Function to get html for bookmark support if bookmarks are enabled. Else will
  668. * return null
  669. *
  670. * @param string $disp_mode display mode
  671. * @param bool $cfgBookmark configuration setting for bookmarking
  672. * @param string $sql_query sql query
  673. * @param string $db current database
  674. * @param string $table current table
  675. * @param string $complete_query complete query
  676. * @param string $bkm_user bookmarking user
  677. *
  678. * @return string $html
  679. */
  680. function PMA_getHtmlForBookmark($disp_mode, $cfgBookmark, $sql_query, $db, $table,
  681. $complete_query, $bkm_user
  682. ) {
  683. if ($disp_mode[7] == '1'
  684. && (! empty($cfgBookmark) && empty($_GET['id_bookmark']))
  685. && ! empty($sql_query)
  686. ) {
  687. $html = "\n";
  688. $goto = 'sql.php'
  689. . PMA_URL_getCommon(
  690. array(
  691. 'db' => $db,
  692. 'table' => $table,
  693. 'sql_query' => $sql_query,
  694. 'id_bookmark'=> 1,
  695. )
  696. );
  697. $bkm_sql_query = urlencode(
  698. isset($complete_query) ? $complete_query : $sql_query
  699. );
  700. $html = '<form action="sql.php" method="post"'
  701. . ' onsubmit="return ! emptyFormElements(this,'
  702. . '\'bkm_fields[bkm_label]\');"'
  703. . ' id="bookmarkQueryForm">';
  704. $html .= PMA_URL_getHiddenInputs();
  705. $html .= '<input type="hidden" name="goto" value="' . $goto . '" />';
  706. $html .= '<input type="hidden" name="bkm_fields[bkm_database]"'
  707. . ' value="' . htmlspecialchars($db) . '" />';
  708. $html .= '<input type="hidden" name="bkm_fields[bkm_user]"'
  709. . ' value="' . $bkm_user . '" />';
  710. $html .= '<input type="hidden" name="bkm_fields[bkm_sql_query]"'
  711. . ' value="'
  712. . $bkm_sql_query
  713. . '" />';
  714. $html .= '<fieldset>';
  715. $html .= '<legend>';
  716. $html .= PMA_Util::getIcon(
  717. 'b_bookmark.png', __('Bookmark this SQL query'), true
  718. );
  719. $html .= '</legend>';
  720. $html .= '<div class="formelement">';
  721. $html .= '<label for="fields_label_">' . __('Label:') . '</label>';
  722. $html .= '<input type="text" id="fields_label_"'
  723. . ' name="bkm_fields[bkm_label]" value="" />';
  724. $html .= '</div>';
  725. $html .= '<div class="formelement">';
  726. $html .= '<input type="checkbox" name="bkm_all_users"'
  727. . ' id="bkm_all_users" value="true" />';
  728. $html .= '<label for="bkm_all_users">'
  729. . __('Let every user access this bookmark')
  730. . '</label>';
  731. $html .= '</div>';
  732. $html .= '<div class="clearfloat"></div>';
  733. $html .= '</fieldset>';
  734. $html .= '<fieldset class="tblFooters">';
  735. $html .= '<input type="hidden" name="store_bkm" value="1" />';
  736. $html .= '<input type="submit"'
  737. . ' value="' . __('Bookmark this SQL query') . '" />';
  738. $html .= '</fieldset>';
  739. $html .= '</form>';
  740. } else {
  741. $html = null;
  742. }
  743. return $html;
  744. }
  745. /**
  746. * Function to check whether to remember the sorting order or not
  747. *
  748. * @param array $analyzed_sql_results the analyzed query and other variables set
  749. * after analyzing the query
  750. *
  751. * @return boolean
  752. */
  753. function PMA_isRememberSortingOrder($analyzed_sql_results)
  754. {
  755. $select_from = isset(
  756. $analyzed_sql_results['analyzed_sql'][0]['queryflags']['select_from']
  757. );
  758. if ($GLOBALS['cfg']['RememberSorting']
  759. && ! ($analyzed_sql_results['is_count']
  760. || $analyzed_sql_results['is_export']
  761. || $analyzed_sql_results['is_func']
  762. || $analyzed_sql_results['is_analyse'])
  763. && isset($analyzed_sql_results['analyzed_sql'][0]['select_expr'])
  764. && (count($analyzed_sql_results['analyzed_sql'][0]['select_expr']) == 0)
  765. && $select_from
  766. && count($analyzed_sql_results['analyzed_sql'][0]['table_ref']) == 1
  767. ) {
  768. return true;
  769. } else {
  770. return false;
  771. }
  772. }
  773. /**
  774. * Function to check whether the LIMIT clause should be appended or not
  775. *
  776. * @param array $analyzed_sql_results the analyzed query and other variables set
  777. * after analyzing the query
  778. *
  779. * @return boolean
  780. */
  781. function PMA_isAppendLimitClause($analyzed_sql_results)
  782. {
  783. $select_from = isset(
  784. $analyzed_sql_results['analyzed_sql'][0]['queryflags']['select_from']
  785. );
  786. if (($_SESSION['tmpval']['max_rows'] != 'all')
  787. && ! ($analyzed_sql_results['is_export']
  788. || $analyzed_sql_results['is_analyse'])
  789. && ($select_from || $analyzed_sql_results['is_subquery'])
  790. && ! isset($analyzed_sql_results['analyzed_sql'][0]['queryflags']['offset'])
  791. && empty($analyzed_sql_results['analyzed_sql'][0]['limit_clause'])
  792. ) {
  793. return true;
  794. } else {
  795. return false;
  796. }
  797. }
  798. /**
  799. * Function to check whether this query is for just browsing
  800. *
  801. * @param array $analyzed_sql_results the analyzed query and other variables set
  802. * after analyzing the query
  803. * @param boolean $find_real_end whether the real end should be found
  804. *
  805. * @return boolean
  806. */
  807. function PMA_isJustBrowsing($analyzed_sql_results, $find_real_end)
  808. {
  809. $distinct = isset(
  810. $analyzed_sql_results['analyzed_sql'][0]['queryflags']['distinct']
  811. );
  812. $table_name = isset(
  813. $analyzed_sql_results['analyzed_sql'][0]['table_ref'][1]['table_name']
  814. );
  815. if (! $analyzed_sql_results['is_group']
  816. && ! isset($analyzed_sql_results['analyzed_sql'][0]['queryflags']['union'])
  817. && ! $distinct
  818. && ! $table_name
  819. && (empty($analyzed_sql_results['analyzed_sql'][0]['where_clause'])
  820. || $analyzed_sql_results['analyzed_sql'][0]['where_clause'] == '1 ')
  821. && empty($analyzed_sql_results['analyzed_sql'][0]['group_by_clause'])
  822. && ! isset($find_real_end)
  823. && !$analyzed_sql_results['is_subquery']
  824. && empty($analyzed_sql_results['analyzed_sql'][0]['having_clause'])
  825. ) {
  826. return true;
  827. } else {
  828. return false;
  829. }
  830. }
  831. /**
  832. * Function to check whether the reated transformation information shoul be deleted
  833. *
  834. * @param array $analyzed_sql_results the analyzed query and other variables set
  835. * after analyzing the query
  836. *
  837. * @return boolean
  838. */
  839. function PMA_isDeleteTransformationInfo($analyzed_sql_results)
  840. {
  841. if (!empty($analyzed_sql_results['analyzed_sql'][0]['querytype'])
  842. && (($analyzed_sql_results['analyzed_sql'][0]['querytype'] == 'ALTER')
  843. || ($analyzed_sql_results['analyzed_sql'][0]['querytype'] == 'DROP'))
  844. ) {
  845. return true;
  846. } else {
  847. return false;
  848. }
  849. }
  850. /**
  851. * Function to check whether the user has rights to drop the database
  852. *
  853. * @param array $analyzed_sql_results the analyzed query and other variables set
  854. * after analyzing the query
  855. * @param boolean $allowUserDropDatabase whether the user is allowed to drop db
  856. * @param boolean $is_superuser whether this user is a superuser
  857. *
  858. * @return boolean
  859. */
  860. function PMA_hasNoRightsToDropDatabase($analyzed_sql_results,
  861. $allowUserDropDatabase, $is_superuser
  862. ) {
  863. if (! defined('PMA_CHK_DROP')
  864. && ! $allowUserDropDatabase
  865. && isset ($analyzed_sql_results['drop_database'])
  866. && $analyzed_sql_results['drop_database'] == 1
  867. && ! $is_superuser
  868. ) {
  869. return true;
  870. } else {
  871. return false;
  872. }
  873. }
  874. /**
  875. * Function to set the column order
  876. *
  877. * @param PMA_Table $pmatable PMA_Table instance
  878. *
  879. * @return boolean $retval
  880. */
  881. function PMA_setColumnOrder($pmatable)
  882. {
  883. $col_order = explode(',', $_REQUEST['col_order']);
  884. $retval = $pmatable->setUiProp(
  885. PMA_Table::PROP_COLUMN_ORDER,
  886. $col_order,
  887. $_REQUEST['table_create_time']
  888. );
  889. if (gettype($retval) != 'boolean') {
  890. $response = PMA_Response::getInstance();
  891. $response->isSuccess(false);
  892. $response->addJSON('message', $retval->getString());
  893. exit;
  894. }
  895. return $retval;
  896. }
  897. /**
  898. * Function to set the column visibility
  899. *
  900. * @param PMA_Table $pmatable PMA_Table instance
  901. *
  902. * @return boolean $retval
  903. */
  904. function PMA_setColumnVisibility($pmatable)
  905. {
  906. $col_visib = explode(',', $_REQUEST['col_visib']);
  907. $retval = $pmatable->setUiProp(
  908. PMA_Table::PROP_COLUMN_VISIB, $col_visib,
  909. $_REQUEST['table_create_time']
  910. );
  911. if (gettype($retval) != 'boolean') {
  912. $response = PMA_Response::getInstance();
  913. $response->isSuccess(false);
  914. $response->addJSON('message', $retval->getString());
  915. exit;
  916. }
  917. return $retval;
  918. }
  919. /**
  920. * Function to check the request for setting the column order or visibility
  921. *
  922. * @param String $table the current table
  923. * @param String $db the current database
  924. *
  925. * @return void
  926. */
  927. function PMA_setColumnOrderOrVisibility($table, $db)
  928. {
  929. $pmatable = new PMA_Table($table, $db);
  930. $retval = false;
  931. // set column order
  932. if (isset($_REQUEST['col_order'])) {
  933. $retval = PMA_setColumnOrder($pmatable);
  934. }
  935. // set column visibility
  936. if ($retval === true && isset($_REQUEST['col_visib'])) {
  937. $retval = PMA_setColumnVisibility($pmatable);
  938. }
  939. $response = PMA_Response::getInstance();
  940. $response->isSuccess($retval == true);
  941. exit;
  942. }
  943. /**
  944. * Function to add a bookmark
  945. *
  946. * @param String $pmaAbsoluteUri absolute URI
  947. * @param String $goto goto page URL
  948. *
  949. * @return void
  950. */
  951. function PMA_addBookmark($pmaAbsoluteUri, $goto)
  952. {
  953. $result = PMA_Bookmark_save(
  954. $_POST['bkm_fields'],
  955. (isset($_POST['bkm_all_users'])
  956. && $_POST['bkm_all_users'] == 'true' ? true : false
  957. )
  958. );
  959. $response = PMA_Response::getInstance();
  960. if ($response->isAjax()) {
  961. if ($result) {
  962. $msg = PMA_message::success(__('Bookmark %s has been created.'));
  963. $msg->addParam($_POST['bkm_fields']['bkm_label']);
  964. $response->addJSON('message', $msg);
  965. } else {
  966. $msg = PMA_message::error(__('Bookmark not created!'));
  967. $response->isSuccess(false);
  968. $response->addJSON('message', $msg);
  969. }
  970. exit;
  971. } else {
  972. // go back to sql.php to redisplay query; do not use &amp; in this case:
  973. /**
  974. * @todo In which scenario does this happen?
  975. */
  976. PMA_sendHeaderLocation(
  977. $pmaAbsoluteUri . $goto
  978. . '&label=' . $_POST['bkm_fields']['bkm_label']
  979. );
  980. }
  981. }
  982. /**
  983. * Function to find the real end of rows
  984. *
  985. * @param String $db the current database
  986. * @param String $table the current table
  987. *
  988. * @return mixed the number of rows if "retain" param is true, otherwise true
  989. */
  990. function PMA_findRealEndOfRows($db, $table)
  991. {
  992. $unlim_num_rows = PMA_Table::countRecords($db, $table, true);
  993. $_SESSION['tmpval']['pos'] = PMA_getStartPosToDisplayRow($unlim_num_rows);
  994. return $unlim_num_rows;
  995. }
  996. /**
  997. * Function to get values for the relational columns
  998. *
  999. * @param String $db the current database
  1000. * @param String $table the current table
  1001. *
  1002. * @return void
  1003. */
  1004. function PMA_getRelationalValues($db, $table)
  1005. {
  1006. $column = $_REQUEST['column'];
  1007. if ($_SESSION['tmpval']['relational_display'] == 'D'
  1008. && isset($_REQUEST['relation_key_or_display_column'])
  1009. && $_REQUEST['relation_key_or_display_column']
  1010. ) {
  1011. $curr_value = $_REQUEST['relation_key_or_display_column'];
  1012. } else {
  1013. $curr_value = $_REQUEST['curr_value'];
  1014. }
  1015. $dropdown = PMA_getHtmlForRelationalColumnDropdown(
  1016. $db, $table, $column, $curr_value
  1017. );
  1018. $response = PMA_Response::getInstance();
  1019. $response->addJSON('dropdown', $dropdown);
  1020. exit;
  1021. }
  1022. /**
  1023. * Function to get values for Enum or Set Columns
  1024. *
  1025. * @param String $db the current database
  1026. * @param String $table the current table
  1027. * @param String $columnType whether enum or set
  1028. *
  1029. * @return void
  1030. */
  1031. function PMA_getEnumOrSetValues($db, $table, $columnType)
  1032. {
  1033. $column = $_REQUEST['column'];
  1034. $curr_value = $_REQUEST['curr_value'];
  1035. $response = PMA_Response::getInstance();
  1036. if ($columnType == "enum") {
  1037. $dropdown = PMA_getHtmlForEnumColumnDropdown(
  1038. $db, $table, $column, $curr_value
  1039. );
  1040. $response->addJSON('dropdown', $dropdown);
  1041. } else {
  1042. $select = PMA_getHtmlForSetColumn($db, $table, $column, $curr_value);
  1043. $response->addJSON('select', $select);
  1044. }
  1045. exit;
  1046. }
  1047. /**
  1048. * Function to append the limit clause
  1049. *
  1050. * @param String $full_sql_query full sql query
  1051. * @param array $analyzed_sql analyzed sql query
  1052. * @param String $display_query display query
  1053. *
  1054. * @return array
  1055. */
  1056. function PMA_appendLimitClause($full_sql_query, $analyzed_sql, $display_query)
  1057. {
  1058. $sql_limit_to_append = ' LIMIT ' . $_SESSION['tmpval']['pos']
  1059. . ', ' . $_SESSION['tmpval']['max_rows'] . " ";
  1060. $full_sql_query = PMA_getSqlWithLimitClause(
  1061. $full_sql_query,
  1062. $analyzed_sql,
  1063. $sql_limit_to_append
  1064. );
  1065. /**
  1066. * @todo pretty printing of this modified query
  1067. */
  1068. if ($display_query) {
  1069. // if the analysis of the original query revealed that we found
  1070. // a section_after_limit, we now have to analyze $display_query
  1071. // to display it correctly
  1072. if (! empty($analyzed_sql[0]['section_after_limit'])
  1073. && trim($analyzed_sql[0]['section_after_limit']) != ';'
  1074. ) {
  1075. $analyzed_display_query = PMA_SQP_analyze(
  1076. PMA_SQP_parse($display_query)
  1077. );
  1078. $display_query = $analyzed_display_query[0]['section_before_limit']
  1079. . "\n" . $sql_limit_to_append
  1080. . $analyzed_display_query[0]['section_after_limit'];
  1081. }
  1082. }
  1083. return array($sql_limit_to_append, $full_sql_query, isset(
  1084. $analyzed_display_query)
  1085. ? $analyzed_display_query : null,
  1086. isset($display_query) ? $display_query : null
  1087. );
  1088. }
  1089. /**
  1090. * Function to get the default sql query for browsing page
  1091. *
  1092. * @param String $db the current database
  1093. * @param String $table the current table
  1094. *
  1095. * @return String $sql_query the default $sql_query for browse page
  1096. */
  1097. function PMA_getDefaultSqlQueryForBrowse($db, $table)
  1098. {
  1099. include_once 'libraries/bookmark.lib.php';
  1100. $book_sql_query = PMA_Bookmark_get(
  1101. $db,
  1102. '\'' . PMA_Util::sqlAddSlashes($table) . '\'',
  1103. 'label',
  1104. false,
  1105. true
  1106. );
  1107. if (! empty($book_sql_query)) {
  1108. $GLOBALS['using_bookmark_message'] = PMA_message::notice(
  1109. __('Using bookmark "%s" as default browse query.')
  1110. );
  1111. $GLOBALS['using_bookmark_message']->addParam($table);
  1112. $GLOBALS['using_bookmark_message']->addMessage(
  1113. PMA_Util::showDocu('faq', 'faq6-22')
  1114. );
  1115. $sql_query = $book_sql_query;
  1116. } else {
  1117. $sql_query = 'SELECT * FROM ' . PMA_Util::backquote($table);
  1118. }
  1119. unset($book_sql_query);
  1120. return $sql_query;
  1121. }
  1122. /**
  1123. * Responds an error when an error happens when executing the query
  1124. *
  1125. * @param boolean $is_gotofile whether goto file or not
  1126. * @param String $error error after executing the query
  1127. * @param String $full_sql_query full sql query
  1128. *
  1129. * @return void
  1130. */
  1131. function PMA_handleQueryExecuteError($is_gotofile, $error, $full_sql_query)
  1132. {
  1133. if ($is_gotofile) {
  1134. $message = PMA_Message::rawError($error);
  1135. $response = PMA_Response::getInstance();
  1136. $response->isSuccess(false);
  1137. $response->addJSON('message', $message);
  1138. } else {
  1139. PMA_Util::mysqlDie($error, $full_sql_query, '', '');
  1140. }
  1141. exit;
  1142. }
  1143. /**
  1144. * Function to store the query as a bookmark
  1145. *
  1146. * @param String $db the current database
  1147. * @param String $bkm_user the bookmarking user
  1148. * @param String $sql_query_for_bookmark the query to be stored in bookmark
  1149. * @param String $bkm_label bookmark label
  1150. * @param boolean $bkm_replace whether to replace existing bookmarks
  1151. *
  1152. * @return void
  1153. */
  1154. function PMA_storeTheQueryAsBookmark($db, $bkm_user, $sql_query_for_bookmark,
  1155. $bkm_label, $bkm_replace
  1156. ) {
  1157. include_once 'libraries/bookmark.lib.php';
  1158. $bfields = array(
  1159. 'bkm_database' => $db,
  1160. 'bkm_user' => $bkm_user,
  1161. 'bkm_sql_query' => urlencode($sql_query_for_bookmark),
  1162. 'bkm_label' => $bkm_label
  1163. );
  1164. // Should we replace bookmark?
  1165. if (isset($bkm_replace)) {
  1166. $bookmarks = PMA_Bookmark_getList($db);
  1167. foreach ($bookmarks as $key => $val) {
  1168. if ($val == $bkm_label) {
  1169. PMA_Bookmark_delete($key);
  1170. }
  1171. }
  1172. }
  1173. PMA_Bookmark_save($bfields, isset($_POST['bkm_all_users']));
  1174. }
  1175. /**
  1176. * Function to execute the SQL query and set the execution time
  1177. *
  1178. * @param String $full_sql_query the full sql query
  1179. *
  1180. * @return mixed $result the results after running the query
  1181. */
  1182. function PMA_executeQueryAndStoreResults($full_sql_query)
  1183. {
  1184. // Measure query time.
  1185. $querytime_before = array_sum(explode(' ', microtime()));
  1186. $result = @$GLOBALS['dbi']->tryQuery(
  1187. $full_sql_query, null, PMA_DatabaseInterface::QUERY_STORE
  1188. );
  1189. $querytime_after = array_sum(explode(' ', microtime()));
  1190. $GLOBALS['querytime'] = $querytime_after - $querytime_before;
  1191. // If a stored procedure was called, there may be more results that are
  1192. // queued up and waiting to be flushed from the buffer. So let's do that.
  1193. do {
  1194. $GLOBALS['dbi']->storeResult();
  1195. if (! $GLOBALS['dbi']->moreResults()) {
  1196. break;
  1197. }
  1198. } while ($GLOBALS['dbi']->nextResult());
  1199. return $result;
  1200. }
  1201. /**
  1202. * Function to get the affected or changed number of rows after executing a query
  1203. *
  1204. * @param boolean $is_affected whether the query affected a table
  1205. * @param mixed $result results of executing the query
  1206. * @param int $num_rows number of rows affected or changed
  1207. *
  1208. * @return int $num_rows number of rows affected or changed
  1209. */
  1210. function PMA_getNumberOfRowsAffectedOrChanged($is_affected, $result, $num_rows)
  1211. {
  1212. if (! $is_affected) {
  1213. $num_rows = ($result) ? @$GLOBALS['dbi']->numRows($result) : 0;
  1214. } elseif (! isset($num_rows)) {
  1215. $num_rows = @$GLOBALS['dbi']->affectedRows();
  1216. }
  1217. return $num_rows;
  1218. }
  1219. /**
  1220. * Checks if the current database has changed
  1221. * This could happen if the user sends a query like "USE `database`;"
  1222. *
  1223. * @param String $db the database in the query
  1224. *
  1225. * @return int $reload whether to reload the navigation(1) or not(0)
  1226. */
  1227. function PMA_hasCurrentDbChanged($db)
  1228. {
  1229. // Checks if the current database has changed
  1230. // This could happen if the user sends a query like "USE `database`;"
  1231. $reload = 0;
  1232. if (strlen($db)) {
  1233. $current_db = $GLOBALS['dbi']->fetchValue('SELECT DATABASE()');
  1234. // $current_db is false, except when a USE statement was sent
  1235. if ($current_db != false && $db !== $current_db) {
  1236. $reload = 1;
  1237. }
  1238. }
  1239. return $reload;
  1240. }
  1241. /**
  1242. * If a table, database or column gets dropped, clean comments.
  1243. *
  1244. * @param String $db current database
  1245. * @param String $table current table
  1246. * @param String $dropped_column dropped column if any
  1247. * @param bool $purge whether purge set or not
  1248. * @param array $extra_data extra data
  1249. *
  1250. * @return array $extra_data
  1251. */
  1252. function PMA_cleanupRelations($db, $table, $dropped_column, $purge, $extra_data)
  1253. {
  1254. include_once 'libraries/relation_cleanup.lib.php';
  1255. if (isset($purge) && $purge == 1) {
  1256. if (strlen($table) && strlen($db)) {
  1257. PMA_relationsCleanupTable($db, $table);
  1258. } elseif (strlen($db)) {
  1259. PMA_relationsCleanupDatabase($db);
  1260. }
  1261. }
  1262. if (isset($dropped_column)
  1263. && !empty($dropped_column)
  1264. && strlen($db)
  1265. && strlen($table)
  1266. ) {
  1267. PMA_relationsCleanupColumn($db, $table, $dropped_column);
  1268. // to refresh the list of indexes (Ajax mode)
  1269. $extra_data['indexes_list'] = PMA_Index::getView($table, $db);
  1270. }
  1271. return $extra_data;
  1272. }
  1273. /**
  1274. * Function to count the total number of rows for the same 'SELECT' query without
  1275. * the 'LIMIT' clause that may have been programatically added
  1276. *
  1277. * @param int $num_rows number of rows affected/changed by the query
  1278. * @param bool $is_select whether the query is SELECT or not
  1279. * @param bool $justBrowsing whether just browsing or not
  1280. * @param string $db the current database
  1281. * @param string $table the current table
  1282. * @param array $parsed_sql parsed sql
  1283. * @param array $analyzed_sql_results the analyzed query and other variables set
  1284. * after analyzing the query
  1285. *
  1286. * @return int $unlim_num_rows unlimited number of rows
  1287. */
  1288. function PMA_countQueryResults(
  1289. $num_rows, $is_select, $justBrowsing,
  1290. $db, $table, $parsed_sql, $analyzed_sql_results
  1291. ) {
  1292. if (!PMA_isAppendLimitClause($analyzed_sql_results)) {
  1293. // if we did not append a limit, set this to get a correct
  1294. // "Showing rows..." message
  1295. // $_SESSION['tmpval']['max_rows'] = 'all';
  1296. $unlim_num_rows = $num_rows;
  1297. } elseif ($is_select || $analyzed_sql_results['is_subquery']) {
  1298. // c o u n t q u e r y
  1299. // If we are "just browsing", there is only one table,
  1300. // and no WHERE clause (or just 'WHERE 1 '),
  1301. // we do a quick count (which uses MaxExactCount) because
  1302. // SQL_CALC_FOUND_ROWS is not quick on large InnoDB tables
  1303. // However, do not count again if we did it previously
  1304. // due to $find_real_end == true
  1305. if ($justBrowsing) {
  1306. // Get row count (is approximate for InnoDB)
  1307. $unlim_num_rows = PMA_Table::countRecords(
  1308. $db,
  1309. $table,
  1310. false
  1311. );
  1312. /**
  1313. * @todo Can we know at this point that this is InnoDB,
  1314. * (in this case there would be no need for getting
  1315. * an exact count)?
  1316. */
  1317. if ($unlim_num_rows < $GLOBALS['cfg']['MaxExactCount']) {
  1318. // Get the exact count if approximate count
  1319. // is less than MaxExactCount
  1320. /**
  1321. * @todo In countRecords(), MaxExactCount is also verified,
  1322. * so can we avoid checking it twice?
  1323. */
  1324. $unlim_num_rows = PMA_Table::countRecords(
  1325. $db,
  1326. $table,
  1327. true
  1328. );
  1329. }
  1330. } else {
  1331. // add select expression after the SQL_CALC_FOUND_ROWS
  1332. // for UNION, just adding SQL_CALC_FOUND_ROWS
  1333. // after the first SELECT works.
  1334. // take the left part, could be:
  1335. // SELECT
  1336. // (SELECT
  1337. $analyzed_sql = $analyzed_sql_results['analyzed_sql'];
  1338. $count_query = PMA_SQP_format(
  1339. $parsed_sql,
  1340. 'query_only',
  1341. 0,
  1342. $analyzed_sql[0]['position_of_first_select'] + 1
  1343. );
  1344. $count_query .= ' SQL_CALC_FOUND_ROWS ';
  1345. // add everything that was after the first SELECT
  1346. $count_query .= PMA_SQP_format(
  1347. $parsed_sql,
  1348. 'query_only',
  1349. $analyzed_sql[0]['position_of_first_select'] + 1
  1350. );
  1351. // ensure there is no semicolon at the end of the
  1352. // count query because we'll probably add
  1353. // a LIMIT 1 clause after it
  1354. $count_query = rtrim($count_query);
  1355. $count_query = rtrim($count_query, ';');
  1356. // if using SQL_CALC_FOUND_ROWS, add a LIMIT to avoid
  1357. // long delays. Returned count will be complete anyway.
  1358. // (but a LIMIT would disrupt results in an UNION)
  1359. if (! isset($analyzed_sql[0]['queryflags']['union'])) {
  1360. $count_query .= ' LIMIT 1';
  1361. }
  1362. // run the count query
  1363. $GLOBALS['dbi']->tryQuery($count_query);
  1364. // if (mysql_error()) {
  1365. // void.
  1366. // I tried the case
  1367. // (SELECT `User`, `Host`, `Db`, `Select_priv` FROM `db`)
  1368. // UNION (SELECT `User`, `Host`, "%" AS "Db",
  1369. // `Select_priv`
  1370. // FROM `user`) ORDER BY `User`, `Host`, `Db`;
  1371. // and although the generated count_query is wrong
  1372. // the SELECT FOUND_ROWS() work! (maybe it gets the
  1373. // count from the latest query that worked)
  1374. //
  1375. // another case where the count_query is wrong:
  1376. // SELECT COUNT(*), f1 from t1 group by f1
  1377. // and you click to sort on count(*)
  1378. // }
  1379. $unlim_num_rows = $GLOBALS['dbi']->fetchValue('SELECT FOUND_ROWS()');
  1380. } // end else "just browsing"
  1381. } else {// not $is_select
  1382. $unlim_num_rows = 0;
  1383. }
  1384. return $unlim_num_rows;
  1385. }
  1386. /**
  1387. * Function to handle all aspects relating to executing the query
  1388. *
  1389. * @param array $analyzed_sql_results analyzed sql results
  1390. * @param String $full_sql_query full sql query
  1391. * @param boolean $is_gotofile whether to go to a file
  1392. * @param String $db current database
  1393. * @param String $table current table
  1394. * @param boolean $find_real_end whether to find the real end
  1395. * @param String $sql_query_for_bookmark sql query to be stored as bookmark
  1396. * @param array $extra_data extra data
  1397. *
  1398. * @return mixed
  1399. */
  1400. function PMA_executeTheQuery($analyzed_sql_results, $full_sql_query, $is_gotofile,
  1401. $db, $table, $find_real_end, $sql_query_for_bookmark, $extra_data
  1402. ) {
  1403. // Only if we ask to see the php code
  1404. if (isset($GLOBALS['show_as_php'])) {
  1405. $result = null;
  1406. $num_rows = 0;
  1407. $unlim_num_rows = 0;
  1408. } else { // If we don't ask to see the php code
  1409. if (isset($_SESSION['profiling']) && PMA_Util::profilingSupported()) {
  1410. $GLOBALS['dbi']->query('SET PROFILING=1;');
  1411. }
  1412. $result = PMA_executeQueryAndStoreResults($full_sql_query);
  1413. // Displays an error message if required and stop parsing the script
  1414. $error = $GLOBALS['dbi']->getError();
  1415. if ($error) {
  1416. PMA_handleQueryExecuteError($is_gotofile, $error, $full_sql_query);
  1417. }
  1418. // If there are no errors and bookmarklabel was given,
  1419. // store the query as a bookmark
  1420. if (! empty($_POST['bkm_label']) && ! empty($sql_query_for_bookmark)) {
  1421. PMA_storeTheQueryAsBookmark(
  1422. $db, $GLOBALS['cfg']['Bookmark']['user'],
  1423. $sql_query_for_bookmark, $_POST['bkm_label'],
  1424. isset($_POST['bkm_replace']) ? $_POST['bkm_replace'] : null
  1425. );
  1426. } // end store bookmarks
  1427. // Gets the number of rows affected/returned
  1428. // (This must be done immediately after the query because
  1429. // mysql_affected_rows() reports about the last query done)
  1430. $num_rows = PMA_getNumberOfRowsAffectedOrChanged(
  1431. $analyzed_sql_results['is_affected'], $result,
  1432. isset($num_rows) ? $num_rows : null
  1433. );
  1434. // Grabs the profiling results
  1435. if (isset($_SESSION['profiling']) && PMA_Util::profilingSupported()) {
  1436. $profiling_results = $GLOBALS['dbi']->fetchResult('SHOW PROFILE;');
  1437. }
  1438. $justBrowsing = PMA_isJustBrowsing(
  1439. $analyzed_sql_results, isset($find_real_end) ? $find_real_end : null
  1440. );
  1441. $unlim_num_rows = PMA_countQueryResults(
  1442. $num_rows, $analyzed_sql_results['is_select'], $justBrowsing, $db,
  1443. $table, $analyzed_sql_results['parsed_sql'], $analyzed_sql_results
  1444. );
  1445. $extra_data = PMA_cleanupRelations(
  1446. isset($db) ? $db : '', isset($table) ? $table : '',
  1447. isset($_REQUEST['dropped_column']) ? $_REQUEST['dropped_column'] : null,
  1448. isset($_REQUEST['purge']) ? $_REQUEST['purge'] : null,
  1449. isset($extra_data) ? $extra_data : null
  1450. );
  1451. // Update Indexes list.
  1452. if (isset($_REQUEST['index_change'])) {
  1453. $extra_data['indexes_list'] = PMA_Index::getView($table, $db);
  1454. }
  1455. }
  1456. return array($result, $num_rows, $unlim_num_rows,
  1457. isset($profiling_results) ? $profiling_results : null,
  1458. isset($justBrowsing) ? $justBrowsing : null, $extra_data
  1459. );
  1460. }
  1461. /**
  1462. * Delete related tranformatioinformationn information
  1463. *
  1464. * @param String $db current database
  1465. * @param String $table current table
  1466. * @param array $analyzed_sql analyzed sql query
  1467. *
  1468. * @return void
  1469. */
  1470. function PMA_deleteTransformationInfo($db, $table, $analyzed_sql)
  1471. {
  1472. include_once 'libraries/transformations.lib.php';
  1473. if ($analyzed_sql[0]['querytype'] == 'ALTER') {
  1474. if (stripos($analyzed_sql[0]['unsorted_query'], 'DROP') !== false) {
  1475. $drop_column = PMA_getColumnNameInColumnDropSql(
  1476. $analyzed_sql[0]['unsorted_query']
  1477. );
  1478. if ($drop_column != '') {
  1479. PMA_clearTransformations($db, $table, $drop_column);
  1480. }
  1481. }
  1482. } else if (($analyzed_sql[0]['querytype'] == 'DROP') && ($table != '')) {
  1483. PMA_clearTransformations($db, $table);
  1484. }
  1485. }
  1486. /**
  1487. * Function to get the message for the no rows returned case
  1488. *
  1489. * @param string $message_to_show message to show
  1490. * @param array $analyzed_sql_results analyzed sql results
  1491. * @param int $num_rows number of rows
  1492. *
  1493. * @return string $message
  1494. */
  1495. function PMA_getMessageForNoRowsReturned($message_to_show, $analyzed_sql_results,
  1496. $num_rows
  1497. ) {
  1498. if ($analyzed_sql_results['is_delete']) {
  1499. $message = PMA_Message::getMessageForDeletedRows($num_rows);
  1500. } elseif ($analyzed_sql_results['is_insert']) {
  1501. if ($analyzed_sql_results['is_replace']) {
  1502. // For replace we get DELETED + INSERTED row count,
  1503. // so we have to call it affected
  1504. $message = PMA_Message::getMessageForAffectedRows($num_rows);
  1505. } else {
  1506. $message = PMA_Message::getMessageForInsertedRows($num_rows);
  1507. }
  1508. $insert_id = $GLOBALS['dbi']->insertId();
  1509. if ($insert_id != 0) {
  1510. // insert_id is id of FIRST record inserted in one insert,
  1511. // so if we inserted multiple rows, we had to increment this
  1512. $message->addMessage('[br]');
  1513. // need to use a temporary because the Message class
  1514. // currently supports adding parameters only to the first
  1515. // message
  1516. $_inserted = PMA_Message::notice(__('Inserted row id: %1$d'));
  1517. $_inserted->addParam($insert_id + $num_rows - 1);
  1518. $message->addMessage($_inserted);
  1519. }
  1520. } elseif ($analyzed_sql_results['is_affected']) {
  1521. $message = PMA_Message::getMessageForAffectedRows($num_rows);
  1522. // Ok, here is an explanation for the !$is_select.
  1523. // The form generated by sql_query_form.lib.php
  1524. // and db_sql.php has many submit buttons
  1525. // on the same form, and some confusion arises from the
  1526. // fact that $message_to_show is sent for every case.
  1527. // The $message_to_show containing a success message and sent with
  1528. // the form should not have priority over errors
  1529. } elseif (! empty($message_to_show) && ! $analyzed_sql_results['is_select']) {
  1530. $message = PMA_Message::rawSuccess(htmlspecialchars($message_to_show));
  1531. } elseif (! empty($GLOBALS['show_as_php'])) {
  1532. $message = PMA_Message::success(__('Showing as PHP code'));
  1533. } elseif (isset($GLOBALS['show_as_php'])) {
  1534. /* User disable showing as PHP, query is only displayed */
  1535. $message = PMA_Message::notice(__('Showing SQL query'));
  1536. } else {
  1537. $message = PMA_Message::success(
  1538. __('MySQL returned an empty result set (i.e. zero rows).')
  1539. );
  1540. }
  1541. if (isset($GLOBALS['querytime'])) {
  1542. $_querytime = PMA_Message::notice(
  1543. '(' . __('Query took %01.4f seconds.') . ')'
  1544. );
  1545. $_querytime->addParam($GLOBALS['querytime']);
  1546. $message->addMessage($_querytime);
  1547. }
  1548. return $message;
  1549. }
  1550. /**
  1551. * Function to send the Ajax response when no rows returned
  1552. *
  1553. * @param string $message message to be send
  1554. * @param array $analyzed_sql analyzed sql
  1555. * @param object $displayResultsObject DisplayResult instance
  1556. * @param array $extra_data extra data
  1557. *
  1558. * @return void
  1559. */
  1560. function PMA_sendAjaxResponseForNoResultsReturned($message, $analyzed_sql,
  1561. $displayResultsObject, $extra_data
  1562. ) {
  1563. /**
  1564. * @todo find a better way to make getMessage() in Header.class.php
  1565. * output the intended message
  1566. */
  1567. $GLOBALS['message'] = $message;
  1568. if ($GLOBALS['cfg']['ShowSQL']) {
  1569. $extra_data['sql_query'] = PMA_Util::getMessage(
  1570. $message, $GLOBALS['sql_query'], 'success'
  1571. );
  1572. }
  1573. if (isset($GLOBALS['reload']) && $GLOBALS['reload'] == 1) {
  1574. $extra_data['reload'] = 1;
  1575. $extra_data['db'] = $GLOBALS['db'];
  1576. }
  1577. $response = PMA_Response::getInstance();
  1578. $response->isSuccess($message->isSuccess());
  1579. // No need to manually send the message
  1580. // The Response class will handle that automatically
  1581. $query__type = PMA_DisplayResults::QUERY_TYPE_SELECT;
  1582. if ($analyzed_sql[0]['querytype'] == $query__type) {
  1583. $createViewHTML = $displayResultsObject->getCreateViewQueryResultOp(
  1584. $analyzed_sql
  1585. );
  1586. $response->addHTML($createViewHTML . '<br />');
  1587. }
  1588. $response->addJSON(isset($extra_data) ? $extra_data : array());
  1589. if (empty($_REQUEST['ajax_page_request'])) {
  1590. $response->addJSON('message', $message);
  1591. exit;
  1592. }
  1593. }
  1594. /**
  1595. * Function to respond back when the query returns zero rows
  1596. * This method is called
  1597. * 1-> When browsing an empty table
  1598. * 2-> When executing a query on a non empty table which returns zero results
  1599. * 3-> When executing a query on an empty table
  1600. * 4-> When executing an INSERT, UPDATE, DEDETE query from the SQL tab
  1601. * 5-> When deleting a row from BROWSE tab
  1602. * 6-> When searching using the SEARCH tab which returns zero results
  1603. * 7-> When changing the structure of the table except change operation
  1604. *
  1605. * @param array $analyzed_sql_results analyzed sql results
  1606. * @param string $db current database
  1607. * @param string $table current table
  1608. * @param string $message_to_show message to show
  1609. * @param int $num_rows number of rows
  1610. * @param object $displayResultsObject DisplayResult instance
  1611. * @param array $extra_data extra data
  1612. *
  1613. * @return void
  1614. */
  1615. function PMA_sendQueryResponseForNoResultsReturned($analyzed_sql_results, $db,
  1616. $table, $message_to_show, $num_rows, $displayResultsObject, $extra_data
  1617. ) {
  1618. if (PMA_isDeleteTransformationInfo($analyzed_sql_results)) {
  1619. PMA_deleteTransformationInfo(
  1620. $db, $table, $analyzed_sql_results['analyzed_sql']
  1621. );
  1622. }
  1623. $message = PMA_getMessageForNoRowsReturned(
  1624. isset($message_to_show) ? $message_to_show : null, $analyzed_sql_results,
  1625. $num_rows
  1626. );
  1627. if (!isset($GLOBALS['show_as_php'])) {
  1628. PMA_sendAjaxResponseForNoResultsReturned(
  1629. $message, $analyzed_sql_results['analyzed_sql'],
  1630. $displayResultsObject,
  1631. isset($extra_data) ? $extra_data : null
  1632. );
  1633. }
  1634. exit();
  1635. }
  1636. /**
  1637. * Function to send response for ajax grid edit
  1638. *
  1639. * @param object $result result of the executed query
  1640. *
  1641. * @return void
  1642. */
  1643. function PMA_sendResponseForGridEdit($result)
  1644. {
  1645. $row = $GLOBALS['dbi']->fetchRow($result);
  1646. $response = PMA_Response::getInstance();
  1647. $response->addJSON('value', $row[0]);
  1648. exit;
  1649. }
  1650. /**
  1651. * Function to get html for the sql query results div
  1652. *
  1653. * @param string $previous_update_query_html html for the previously executed query
  1654. * @param string $profiling_chart_html html for profiling
  1655. * @param object $missing_unique_column_msg message for the missing unique column
  1656. * @param object $bookmark_created_msg message for bookmark creation
  1657. * @param string $table_html html for the table for displaying sql
  1658. * results
  1659. * @param string $indexes_problems_html html for displaying errors in indexes
  1660. * @param string $bookmark_support_html html for displaying bookmark form
  1661. * @param string $print_button_html html for the print button in printview
  1662. *
  1663. * @return string $html_output
  1664. */
  1665. function PMA_getHtmlForSqlQueryResults($previous_update_query_html,
  1666. $profiling_chart_html, $missing_unique_column_msg, $bookmark_created_msg,
  1667. $table_html, $indexes_problems_html, $bookmark_support_html, $print_button_html
  1668. ) {
  1669. //begin the sqlqueryresults div here. container div
  1670. $html_output = '<div id="sqlqueryresults" class="ajax">';
  1671. $html_output .= isset($previous_update_query_html)
  1672. ? $previous_update_query_html : '';
  1673. $html_output .= isset($profiling_chart_html) ? $profiling_chart_html : '';
  1674. $html_output .= isset($missing_unique_column_msg)
  1675. ? $missing_unique_column_msg->getDisplay() : '';
  1676. $html_output .= isset($bookmark_created_msg)
  1677. ? $bookmark_created_msg->getDisplay() : '';
  1678. $html_output .= $table_html;
  1679. $html_output .= isset($indexes_problems_html) ? $indexes_problems_html : '';
  1680. $html_output .= isset($bookmark_support_html) ? $bookmark_support_html : '';
  1681. $html_output .= isset($print_button_html) ? $print_button_html : '';
  1682. $html_output .= '</div>'; // end sqlqueryresults div
  1683. return $html_output;
  1684. }
  1685. /**
  1686. * Returns a message for successful creation of a bookmark or null if a bookmark
  1687. * was not created
  1688. *
  1689. * @return PMA_message $bookmark_created_msg
  1690. */
  1691. function PMA_getBookmarkCreatedMessage()
  1692. {
  1693. if (isset($_GET['label'])) {
  1694. $bookmark_created_msg = PMA_message::success(__('Bookmark %s has been created.'));
  1695. $bookmark_created_msg->addParam($_GET['label']);
  1696. } else {
  1697. $bookmark_created_msg = null;
  1698. }
  1699. return $bookmark_created_msg;
  1700. }
  1701. /**
  1702. * Function to get html for the sql query results table
  1703. *
  1704. * @param array $sql_data sql data
  1705. * @param object $displayResultsObject instance of DisplayResult.class
  1706. * @param string $db current database
  1707. * @param string $goto goto page url
  1708. * @param string $pmaThemeImage theme image uri
  1709. * @param string $url_query url query
  1710. * @param string $disp_mode display mode
  1711. * @param string $sql_limit_to_append sql limit to append
  1712. * @param bool $editable whether the result table is editable or not
  1713. * @param int $unlim_num_rows unlimited number of rows
  1714. * @param int $num_rows number of rows
  1715. * @param bool $showtable whether to show table or not
  1716. * @param object $result result of the executed query
  1717. * @param array $analyzed_sql_results analyzed sql results
  1718. *
  1719. * @return String
  1720. */
  1721. function PMA_getHtmlForSqlQueryResultsTable($sql_data, $displayResultsObject, $db,
  1722. $goto, $pmaThemeImage, $url_query, $disp_mode, $sql_limit_to_append,
  1723. $editable, $unlim_num_rows, $num_rows, $showtable, $result,
  1724. $analyzed_sql_results
  1725. ) {
  1726. $printview = isset($_REQUEST['printview']) ? $_REQUEST['printview'] : null;
  1727. if (! empty($sql_data) && ($sql_data['valid_queries'] > 1)
  1728. || $analyzed_sql_results['is_procedure']
  1729. ) {
  1730. $_SESSION['is_multi_query'] = true;
  1731. $table_html = PMA_getTableHtmlForMultipleQueries(
  1732. $displayResultsObject, $db, $sql_data, $goto,
  1733. $pmaThemeImage, $printview, $url_query,
  1734. $disp_mode, $sql_limit_to_append, $editable
  1735. );
  1736. } else {
  1737. if (isset($result) && $result) {
  1738. $fields_meta = $GLOBALS['dbi']->getFieldsMeta($result);
  1739. $fields_cnt = count($fields_meta);
  1740. }
  1741. $_SESSION['is_multi_query'] = false;
  1742. $displayResultsObject->setProperties(
  1743. $unlim_num_rows, $fields_meta, $analyzed_sql_results['is_count'],
  1744. $analyzed_sql_results['is_export'], $analyzed_sql_results['is_func'],
  1745. $analyzed_sql_results['is_analyse'], $num_rows,
  1746. $fields_cnt, $GLOBALS['querytime'], $pmaThemeImage, $GLOBALS['text_dir'],
  1747. $analyzed_sql_results['is_maint'], $analyzed_sql_results['is_explain'],
  1748. $analyzed_sql_results['is_show'], $showtable, $printview, $url_query,
  1749. $editable
  1750. );
  1751. $table_html = $displayResultsObject->getTable(
  1752. $result, $disp_mode, $analyzed_sql_results['analyzed_sql']
  1753. );
  1754. $GLOBALS['dbi']->freeResult($result);
  1755. }
  1756. return $table_html;
  1757. }
  1758. /**
  1759. * Function to get html for the previous query if there is such. If not will return
  1760. * null
  1761. *
  1762. * @param string $disp_query display query
  1763. * @param bool $showSql whether to show sql
  1764. * @param array $sql_data sql data
  1765. * @param string $disp_message display message
  1766. *
  1767. * @return string $previous_update_query_html
  1768. */
  1769. function PMA_getHtmlForPreviousUpdateQuery($disp_query, $showSql, $sql_data,
  1770. $disp_message
  1771. ) {
  1772. // previous update query (from tbl_replace)
  1773. if (isset($disp_query) && ($showSql == true) && empty($sql_data)) {
  1774. $previous_update_query_html = PMA_Util::getMessage(
  1775. $disp_message, $disp_query, 'success'
  1776. );
  1777. } else {
  1778. $previous_update_query_html = null;
  1779. }
  1780. return $previous_update_query_html;
  1781. }
  1782. /**
  1783. * To get the message if a column index is missing. If not will return null
  1784. *
  1785. * @param string $table current table
  1786. * @param string $db current database
  1787. * @param boolean $editable whether the results table can be editable or not
  1788. * @param string $disp_mode display mode
  1789. *
  1790. * @return PMA_message $message
  1791. */
  1792. function PMA_getMessageIfMissingColumnIndex($table, $db, $editable, $disp_mode)
  1793. {
  1794. if (!empty($table) && ($GLOBALS['dbi']->isSystemSchema($db) || !$editable)) {
  1795. $missing_unique_column_msg = PMA_message::notice(
  1796. __(
  1797. 'Current selection does not contain a unique column.'
  1798. . ' Grid edit, checkbox, Edit, Copy and Delete features'
  1799. . ' are not available.'
  1800. )
  1801. );
  1802. } else {
  1803. $missing_unique_column_msg = null;
  1804. }
  1805. return $missing_unique_column_msg;
  1806. }
  1807. /**
  1808. * Function to get html to display problems in indexes
  1809. *
  1810. * @param string $query_type query type
  1811. * @param bool $selected whether check table, optimize table, analyze
  1812. * table or repair table has been selected with
  1813. * respect to the selected tables from the
  1814. * database structure page.
  1815. * @param string $db current database
  1816. *
  1817. * @return string
  1818. */
  1819. function PMA_getHtmlForIndexesProblems($query_type, $selected, $db)
  1820. {
  1821. // BEGIN INDEX CHECK See if indexes should be checked.
  1822. if (isset($query_type)
  1823. && $query_type == 'check_tbl'
  1824. && isset($selected)
  1825. && is_array($selected)
  1826. ) {
  1827. $indexes_problems_html = '';
  1828. foreach ($selected as $tbl_name) {
  1829. $check = PMA_Index::findDuplicates($tbl_name, $db);
  1830. if (! empty($check)) {
  1831. $indexes_problems_html .= sprintf(
  1832. __('Problems with indexes of table `%s`'), $tbl_name
  1833. );
  1834. $indexes_problems_html .= $check;
  1835. }
  1836. }
  1837. } else {
  1838. $indexes_problems_html = null;
  1839. }
  1840. return $indexes_problems_html;
  1841. }
  1842. /**
  1843. * Function to get the html for the print button in printview
  1844. *
  1845. * @return string $print_button_html html for the print button
  1846. */
  1847. function PMA_getHtmlForPrintButton()
  1848. {
  1849. // Do print the page if required
  1850. if (isset($_REQUEST['printview']) && $_REQUEST['printview'] == '1') {
  1851. $print_button_html = PMA_Util::getButton();
  1852. } else {
  1853. $print_button_html = null;
  1854. }
  1855. return $print_button_html;
  1856. }
  1857. /**
  1858. * Function to display results when the executed query returns non empty results
  1859. *
  1860. * @param array $result executed query results
  1861. * @param bool $justBrowsing whether just browsing or not
  1862. * @param array $analyzed_sql_results analysed sql results
  1863. * @param string $db current database
  1864. * @param string $table current table
  1865. * @param string $disp_mode display mode
  1866. * @param string $message message to show
  1867. * @param array $sql_data sql data
  1868. * @param object $displayResultsObject Instance of DisplyResults.class
  1869. * @param string $goto goto page url
  1870. * @param string $pmaThemeImage uri of the theme image
  1871. * @param string $sql_limit_to_append sql limit to append
  1872. * @param int $unlim_num_rows unlimited number of rows
  1873. * @param int $num_rows number of rows
  1874. * @param string $full_sql_query full sql query
  1875. * @param string $disp_query display query
  1876. * @param string $disp_message display message
  1877. * @param array $profiling_results profiling results
  1878. * @param string $query_type query type
  1879. * @param bool $selected whether check table, optimize table, analyze
  1880. * table or repair table has been selected with
  1881. * respect to the selected tables from the
  1882. * database structure page.
  1883. * @param string $sql_query sql query
  1884. * @param string $complete_query complete sql query
  1885. *
  1886. * @return void
  1887. */
  1888. function PMA_sendQueryResponseForResultsReturned($result, $justBrowsing,
  1889. $analyzed_sql_results, $db, $table, $disp_mode, $message, $sql_data,
  1890. $displayResultsObject, $goto, $pmaThemeImage, $sql_limit_to_append,
  1891. $unlim_num_rows, $num_rows, $full_sql_query, $disp_query,
  1892. $disp_message, $profiling_results, $query_type, $selected, $sql_query,
  1893. $complete_query
  1894. ) {
  1895. // If we are retrieving the full value of a truncated field or the original
  1896. // value of a transformed field, show it here
  1897. if (isset($_REQUEST['grid_edit']) && $_REQUEST['grid_edit'] == true) {
  1898. PMA_sendResponseForGridEdit($result);
  1899. // script has exited at this point
  1900. }
  1901. // Gets the list of fields properties
  1902. if (isset($result) && $result) {
  1903. $fields_meta = $GLOBALS['dbi']->getFieldsMeta($result);
  1904. }
  1905. // Should be initialized these parameters before parsing
  1906. $showtable = isset($showtable) ? $showtable : null;
  1907. $url_query = isset($url_query) ? $url_query : null;
  1908. $response = PMA_Response::getInstance();
  1909. $header = $response->getHeader();
  1910. $scripts = $header->getScripts();
  1911. // hide edit and delete links:
  1912. // - for information_schema
  1913. // - if the result set does not contain all the columns of a unique key
  1914. // (unless this is an updatable view)
  1915. $sele_exp_cls = $analyzed_sql_results['analyzed_sql'][0]['select_expr_clause'];
  1916. $updatableView
  1917. = trim($sele_exp_cls) == '*'
  1918. && PMA_Table::isUpdatableView($db, $table);
  1919. $has_unique = PMA_resultSetContainsUniqueKey(
  1920. $db, $table, $fields_meta
  1921. );
  1922. $just_one_table = PMA_resultSetHasJustOneTable($fields_meta);
  1923. $editable = ($has_unique || $updatableView) && $just_one_table;
  1924. // Displays the results in a table
  1925. if (empty($disp_mode)) {
  1926. // see the "PMA_setDisplayMode()" function in
  1927. // libraries/DisplayResults.class.php
  1928. $disp_mode = 'urdr111101';
  1929. }
  1930. if (!empty($table) && ($GLOBALS['dbi']->isSystemSchema($db) || !$editable)) {
  1931. $disp_mode = 'nnnn110111';
  1932. }
  1933. if ( isset($_REQUEST['printview']) && $_REQUEST['printview'] == '1') {
  1934. $disp_mode = 'nnnn000000';
  1935. }
  1936. if (isset($_REQUEST['table_maintenance'])) {
  1937. $scripts->addFile('makegrid.js');
  1938. $scripts->addFile('sql.js');
  1939. $table_maintenance_html = '';
  1940. if (isset($message)) {
  1941. $message = PMA_Message::success($message);
  1942. $table_maintenance_html = PMA_Util::getMessage(
  1943. $message, $GLOBALS['sql_query'], 'success'
  1944. );
  1945. }
  1946. $table_maintenance_html .= PMA_getHtmlForSqlQueryResultsTable(
  1947. isset($sql_data) ? $sql_data : null, $displayResultsObject, $db, $goto,
  1948. $pmaThemeImage, $url_query, $disp_mode, $sql_limit_to_append,
  1949. false, $unlim_num_rows, $num_rows, $showtable, $result,
  1950. $analyzed_sql_results
  1951. );
  1952. if (empty($sql_data) || ($sql_data['valid_queries'] = 1)) {
  1953. $response->addHTML($table_maintenance_html);
  1954. exit();
  1955. }
  1956. }
  1957. if (!isset($_REQUEST['printview']) || $_REQUEST['printview'] != '1') {
  1958. $scripts->addFile('makegrid.js');
  1959. $scripts->addFile('sql.js');
  1960. unset($GLOBALS['message']);
  1961. //we don't need to buffer the output in getMessage here.
  1962. //set a global variable and check against it in the function
  1963. $GLOBALS['buffer_message'] = false;
  1964. }
  1965. $print_view_header_html = PMA_getHtmlForPrintViewHeader(
  1966. $db, $full_sql_query, $num_rows
  1967. );
  1968. $previous_update_query_html = PMA_getHtmlForPreviousUpdateQuery(
  1969. isset($disp_query) ? $disp_query : null,
  1970. $GLOBALS['cfg']['ShowSQL'], isset($sql_data) ? $sql_data : null,
  1971. isset($disp_message) ? $disp_message : null
  1972. );
  1973. $profiling_chart_html = PMA_getHtmlForProfilingChart(
  1974. $disp_mode, $db, isset($profiling_results) ? $profiling_results : null
  1975. );
  1976. $missing_unique_column_msg = PMA_getMessageIfMissingColumnIndex(
  1977. $table, $db, $editable, $disp_mode
  1978. );
  1979. $bookmark_created_msg = PMA_getBookmarkCreatedMessage();
  1980. $table_html = PMA_getHtmlForSqlQueryResultsTable(
  1981. isset($sql_data) ? $sql_data : null, $displayResultsObject, $db, $goto,
  1982. $pmaThemeImage, $url_query, $disp_mode, $sql_limit_to_append,
  1983. $editable, $unlim_num_rows, $num_rows, $showtable, $result,
  1984. $analyzed_sql_results
  1985. );
  1986. $indexes_problems_html = PMA_getHtmlForIndexesProblems(
  1987. isset($query_type) ? $query_type : null,
  1988. isset($selected) ? $selected : null, $db
  1989. );
  1990. if (isset($GLOBALS['cfg']['Bookmark'])) {
  1991. $bookmark_support_html = PMA_getHtmlForBookmark(
  1992. $disp_mode,
  1993. $GLOBALS['cfg']['Bookmark'],
  1994. $sql_query, $db, $table,
  1995. isset($complete_query) ? $complete_query : $sql_query,
  1996. $GLOBALS['cfg']['Bookmark']['user']
  1997. );
  1998. } else {
  1999. $bookmark_support_html = '';
  2000. }
  2001. $print_button_html = PMA_getHtmlForPrintButton();
  2002. $html_output = isset($table_maintenance_html) ? $table_maintenance_html : '';
  2003. $html_output .= isset($print_view_header_html) ? $print_view_header_html : '';
  2004. $html_output .= PMA_getHtmlForSqlQueryResults(
  2005. $previous_update_query_html, $profiling_chart_html,
  2006. $missing_unique_column_msg, $bookmark_created_msg,
  2007. $table_html, $indexes_problems_html, $bookmark_support_html,
  2008. $print_button_html
  2009. );
  2010. $response->addHTML($html_output);
  2011. exit();
  2012. }
  2013. /**
  2014. * Function to send response for both empty results and non empty results
  2015. *
  2016. * @param int $num_rows number of rows returned by the executed query
  2017. * @param int $unlim_num_rows unlimited number of rows
  2018. * @param bool $is_affected is affected
  2019. * @param string $db current database
  2020. * @param string $table current table
  2021. * @param string $message_to_show message to show
  2022. * @param array $analyzed_sql_results analyzed Sql Results
  2023. * @param object $displayResultsObject Instance of DisplayResult class
  2024. * @param array $extra_data extra data
  2025. * @param array $result executed query results
  2026. * @param bool $justBrowsing whether just browsing or not
  2027. * @param string $disp_mode disply mode
  2028. * @param object $message message
  2029. * @param array $sql_data sql data
  2030. * @param string $goto goto page url
  2031. * @param string $pmaThemeImage uri of the PMA theme image
  2032. * @param string $sql_limit_to_append sql limit to append
  2033. * @param string $full_sql_query full sql query
  2034. * @param string $disp_query display query
  2035. * @param string $disp_message display message
  2036. * @param array $profiling_results profiling results
  2037. * @param string $query_type query type
  2038. * @param bool $selected whether check table, optimize table, analyze
  2039. * table or repair table has been selected with
  2040. * respect to the selected tables from the
  2041. * database structure page.
  2042. * @param string $sql_query sql query
  2043. * @param string $complete_query complete query
  2044. *
  2045. * @return void
  2046. */
  2047. function PMA_sendQueryResponse($num_rows, $unlim_num_rows, $is_affected,
  2048. $db, $table, $message_to_show, $analyzed_sql_results, $displayResultsObject,
  2049. $extra_data, $result, $justBrowsing, $disp_mode,$message, $sql_data,
  2050. $goto, $pmaThemeImage, $sql_limit_to_append, $full_sql_query,
  2051. $disp_query, $disp_message, $profiling_results, $query_type, $selected,
  2052. $sql_query, $complete_query
  2053. ) {
  2054. // No rows returned -> move back to the calling page
  2055. if ((0 == $num_rows && 0 == $unlim_num_rows) || $is_affected) {
  2056. PMA_sendQueryResponseForNoResultsReturned(
  2057. $analyzed_sql_results, $db, $table,
  2058. isset($message_to_show) ? $message_to_show : null,
  2059. $num_rows, $displayResultsObject, $extra_data
  2060. );
  2061. } else {
  2062. // At least one row is returned -> displays a table with results
  2063. PMA_sendQueryResponseForResultsReturned(
  2064. isset($result) ? $result : null, $justBrowsing, $analyzed_sql_results,
  2065. $db, $table, isset($disp_mode) ? $disp_mode : null,
  2066. isset($message) ? $message : null, isset($sql_data) ? $sql_data : null,
  2067. $displayResultsObject, $goto, $pmaThemeImage,
  2068. $sql_limit_to_append, $unlim_num_rows,
  2069. $num_rows, $full_sql_query,
  2070. isset($disp_query) ? $disp_query : null,
  2071. isset($disp_message) ? $disp_message : null, $profiling_results,
  2072. isset($query_type) ? $query_type : null,
  2073. isset($selected) ? $selected : null, $sql_query,
  2074. isset($complete_query) ? $complete_query : null
  2075. );
  2076. } // end rows returned
  2077. }
  2078. /**
  2079. * Function to execute the query and send the response
  2080. *
  2081. * @param array $analyzed_sql_results analysed sql results
  2082. * @param bool $is_gotofile whether goto file or not
  2083. * @param string $db current database
  2084. * @param string $table current table
  2085. * @param bool|null $find_real_end whether to find real end or not
  2086. * @param string $sql_query_for_bookmark the sql query to be stored as bookmark
  2087. * @param array|null $extra_data extra data
  2088. * @param bool $is_affected whether affected or not
  2089. * @param string $message_to_show message to show
  2090. * @param string $disp_mode display mode
  2091. * @param string $message message
  2092. * @param array|null $sql_data sql data
  2093. * @param string $goto goto page url
  2094. * @param string $pmaThemeImage uri of the PMA theme image
  2095. * @param string $disp_query display query
  2096. * @param string $disp_message display message
  2097. * @param string $query_type query type
  2098. * @param string $sql_query sql query
  2099. * @param bool|null $selected whether check table, optimize table,
  2100. * analyze table or repair table has been
  2101. * selected with respect to the selected
  2102. * tables from the database structure page
  2103. * @param string $complete_query complete query
  2104. *
  2105. * @return void
  2106. */
  2107. function PMA_executeQueryAndSendQueryResponse($analyzed_sql_results,
  2108. $is_gotofile, $db, $table, $find_real_end, $sql_query_for_bookmark,
  2109. $extra_data, $is_affected, $message_to_show, $disp_mode, $message,
  2110. $sql_data, $goto, $pmaThemeImage, $disp_query, $disp_message,
  2111. $query_type, $sql_query, $selected, $complete_query
  2112. ) {
  2113. // Include PMA_Index class for use in PMA_DisplayResults class
  2114. include_once './libraries/Index.class.php';
  2115. include 'libraries/DisplayResults.class.php';
  2116. // Handle remembered sorting order, only for single table query
  2117. // Handling is not required when it's a union query
  2118. // (the parser never sets the 'union' key to 0)
  2119. if (PMA_isRememberSortingOrder($analyzed_sql_results)
  2120. && ! isset($analyzed_sql_results['analyzed_sql'][0]['queryflags']['union'])
  2121. ) {
  2122. PMA_handleSortOrder($db, $table, $analyzed_sql_results, $sql_query);
  2123. }
  2124. $displayResultsObject = new PMA_DisplayResults(
  2125. $GLOBALS['db'], $GLOBALS['table'], $GLOBALS['goto'], $sql_query
  2126. );
  2127. $displayResultsObject->setConfigParamsForDisplayTable();
  2128. // assign default full_sql_query
  2129. $full_sql_query = $sql_query;
  2130. // Do append a "LIMIT" clause?
  2131. if (PMA_isAppendLimitClause($analyzed_sql_results)) {
  2132. list($sql_limit_to_append,
  2133. $full_sql_query, $analyzed_display_query, $display_query
  2134. ) = PMA_appendLimitClause(
  2135. $full_sql_query, $analyzed_sql_results['analyzed_sql'],
  2136. isset($display_query)
  2137. );
  2138. } else {
  2139. $sql_limit_to_append = '';
  2140. }
  2141. $GLOBALS['reload'] = PMA_hasCurrentDbChanged($db);
  2142. $GLOBALS['dbi']->selectDb($db);
  2143. // Execute the query
  2144. list($result, $num_rows, $unlim_num_rows, $profiling_results,
  2145. $justBrowsing, $extra_data
  2146. ) = PMA_executeTheQuery(
  2147. $analyzed_sql_results,
  2148. $full_sql_query,
  2149. $is_gotofile,
  2150. $db,
  2151. $table,
  2152. isset($find_real_end) ? $find_real_end : null,
  2153. isset($sql_query_for_bookmark) ? $sql_query_for_bookmark : null,
  2154. isset($extra_data) ? $extra_data : null
  2155. );
  2156. PMA_sendQueryResponse(
  2157. $num_rows,
  2158. $unlim_num_rows,
  2159. $is_affected,
  2160. $db,
  2161. $table,
  2162. isset($message_to_show) ? $message_to_show : null,
  2163. $analyzed_sql_results,
  2164. $displayResultsObject,
  2165. $extra_data,
  2166. isset($result) ? $result : null,
  2167. $justBrowsing,
  2168. isset($disp_mode) ? $disp_mode : null,
  2169. isset($message) ? $message : null,
  2170. isset($sql_data) ? $sql_data : null,
  2171. $goto,
  2172. $pmaThemeImage,
  2173. $sql_limit_to_append,
  2174. $full_sql_query,
  2175. isset($disp_query) ? $disp_query : null,
  2176. isset($disp_message) ? $disp_message : null,
  2177. $profiling_results,
  2178. isset($query_type) ? $query_type : null,
  2179. isset($selected) ? $selected : null,
  2180. $sql_query,
  2181. isset($complete_query) ? $complete_query : null
  2182. );
  2183. }
  2184. /**
  2185. * Function to define pos to display a row
  2186. *
  2187. * @param Int $number_of_line Number of the line to display
  2188. * @param Int $max_rows Number of rows by page
  2189. *
  2190. * @return Int Start position to display the line
  2191. */
  2192. function PMA_getStartPosToDisplayRow($number_of_line, $max_rows = null)
  2193. {
  2194. if (null === $max_rows) {
  2195. $max_rows = $_SESSION['tmpval']['max_rows'];
  2196. }
  2197. return @((ceil($number_of_line / $max_rows) - 1) * $max_rows);
  2198. }
  2199. /**
  2200. * Function to calculate new pos if pos is higher than number of rows
  2201. * of displayed table
  2202. *
  2203. * @param String $db Database name
  2204. * @param String $table Table name
  2205. * @param Int $pos Initial position
  2206. *
  2207. * @return Int Number of pos to display last page
  2208. */
  2209. function PMA_calculatePosForLastPage($db, $table, $pos)
  2210. {
  2211. if (null === $pos) {
  2212. $pos = $_SESSION['tmpval']['pos'];
  2213. }
  2214. $unlim_num_rows = PMA_Table::countRecords($db, $table, true);
  2215. //If position is higher than number of rows
  2216. if ($unlim_num_rows <= $pos && 0 != $pos) {
  2217. $pos = PMA_getStartPosToDisplayRow($unlim_num_rows);
  2218. }
  2219. return $pos;
  2220. }
  2221. ?>