Documentation TYPO3 par Ameos

sqlparser.lib.php

00001 <?php
00002 /* $Id: sqlparser.lib.php,v 2.6 2004/01/09 23:17:21 rabus Exp $ */
00003 // vim: expandtab sw=4 ts=4 sts=4:
00004 
00038 if (!isset($is_minimum_common)) {
00039     $is_minimum_common = FALSE;
00040 }
00041 
00042 if ($is_minimum_common == FALSE) {
00046     require_once('./libraries/string.lib.php');
00047 
00051     require_once('./libraries/sqlparser.data.php');
00052     require_once('./libraries/mysql_charsets.lib.php');
00053     if (!isset($mysql_charsets)) {
00054         $mysql_charsets = array();
00055         $mysql_charsets_count = 0;
00056         $mysql_collations_flat = array();
00057         $mysql_collations_count = 0;
00058     }
00059 
00060     if (!defined('DEBUG_TIMING')) {
00061         function PMA_SQP_arrayAdd(&$arr, $type, $data, &$arrsize)
00062         {
00063             $arr[] = array('type' => $type, 'data' => $data);
00064             $arrsize++;
00065         } // end of the "PMA_SQP_arrayAdd()" function
00066     } else {
00067         function PMA_SQP_arrayAdd(&$arr, $type, $data, &$arrsize)
00068         {
00069             global $timer;
00070 
00071             $t     = $timer;
00072             $arr[] = array('type' => $type, 'data' => $data , 'time' => $t);
00073             $timer = microtime();
00074             $arrsize++;
00075         } // end of the "PMA_SQP_arrayAdd()" function
00076     } // end if... else...
00077 
00078 
00084     // Added, Robbat2 - 13 Janurary 2003, 2:59PM
00085     function PMA_SQP_resetError() {
00086         global $SQP_errorString;
00087         $SQP_errorString = '';
00088         unset($SQP_errorString);
00089     }
00090 
00098     // Added, Robbat2 - 13 Janurary 2003, 2:59PM
00099     function PMA_SQP_getErrorString() {
00100         global $SQP_errorString;
00101         return isset($SQP_errorString) ? $SQP_errorString : '';
00102     }
00103 
00111     // Added, Robbat2 - 13 Janurary 2003, 2:59PM
00112     function PMA_SQP_isError() {
00113         global $SQP_errorString;
00114         return isset($SQP_errorString) && !empty($SQP_errorString);
00115     }
00116 
00126     // Revised, Robbat2 - 13 Janurary 2003, 2:59PM
00127     function PMA_SQP_throwError($message, $sql)
00128     {
00129 
00130         global $SQP_errorString;
00131         $SQP_errorString = '<p>'.$GLOBALS['strSQLParserUserError'] . '</p>' . "\n"
00132             . '<pre>' . "\n"
00133             . 'ERROR: ' . $message . "\n"
00134             . 'SQL: ' . htmlspecialchars($sql) .  "\n"
00135             . '</pre>' . "\n";
00136 
00137     } // end of the "PMA_SQP_throwError()" function
00138 
00139 
00148     function PMA_SQP_bug($message, $sql)
00149     {
00150         global $SQP_errorString;
00151         $debugstr = 'ERROR: ' . $message . "\n";
00152         $debugstr .= 'CVS: $Id: sqlparser.lib.php,v 2.6 2004/01/09 23:17:21 rabus Exp $' . "\n";
00153         $debugstr .= 'MySQL: '.PMA_MYSQL_STR_VERSION . "\n";
00154         $debugstr .= 'USR OS, AGENT, VER: ' . PMA_USR_OS . ' ' . PMA_USR_BROWSER_AGENT . ' ' . PMA_USR_BROWSER_VER . "\n";
00155         $debugstr .= 'PMA: ' . PMA_VERSION . "\n";
00156         $debugstr .= 'PHP VER,OS: ' . PMA_PHP_STR_VERSION . ' ' . PHP_OS . "\n";
00157         $debugstr .= 'LANG: ' . $GLOBALS['lang'] . "\n";
00158         $debugstr .= 'SQL: ' . htmlspecialchars($sql);
00159 
00160         $encodedstr     = $debugstr;
00161         if (@function_exists('gzcompress')) {
00162             $encodedstr = gzcompress($debugstr, 9);
00163         }
00164         $encodedstr     = preg_replace("/(\015\012)|(\015)|(\012)/", '<br />' . "\n", chunk_split(base64_encode($encodedstr)));
00165 
00166         $SQP_errorString .= $GLOBALS['strSQLParserBugMessage'] . '<br />' . "\n"
00167              . '----' . $GLOBALS['strBeginCut'] . '----' . '<br />' . "\n"
00168              . $encodedstr . "\n"
00169              . '----' . $GLOBALS['strEndCut'] . '----' . '<br />' . "\n";
00170 
00171         $SQP_errorString .= '----' . $GLOBALS['strBeginRaw'] . '----<br />' . "\n"
00172              . '<pre>' . "\n"
00173              . $debugstr
00174              . '</pre>' . "\n"
00175              . '----' . $GLOBALS['strEndRaw'] . '----<br />' . "\n";
00176 
00177     } // end of the "PMA_SQP_bug()" function
00178 
00179 
00203     function PMA_SQP_parse($sql)
00204     {
00205         global $cfg;
00206         global $PMA_SQPdata_column_attrib, $PMA_SQPdata_reserved_word, $PMA_SQPdata_column_type, $PMA_SQPdata_function_name,
00207                $PMA_SQPdata_column_attrib_cnt, $PMA_SQPdata_reserved_word_cnt, $PMA_SQPdata_column_type_cnt, $PMA_SQPdata_function_name_cnt;
00208         global $mysql_charsets, $mysql_collations_flat, $mysql_charsets_count, $mysql_collations_count;
00209 
00210         // rabus: Convert all line feeds to Unix style
00211         $sql = str_replace("\r\n", "\n", $sql);
00212         $sql = str_replace("\r", "\n", $sql);
00213 
00214         $len = $GLOBALS['PMA_strlen']($sql);
00215         if ($len == 0) {
00216             return array();
00217         }
00218 
00219         $sql_array               = array();
00220         $sql_array['raw']        = $sql;
00221         $count1                  = 0;
00222         $count2                  = 0;
00223         $punct_queryend          = ';';
00224         $punct_qualifier         = '.';
00225         $punct_listsep           = ',';
00226         $punct_level_plus        = '(';
00227         $punct_level_minus       = ')';
00228         $digit_floatdecimal      = '.';
00229         $digit_hexset            = 'x';
00230         $bracket_list            = '()[]{}';
00231         $allpunct_list           =  '-,;:!?/.^~\*&%+<=>|';
00232         $allpunct_list_pair      = array (
00233             0 => '!=',
00234             1 => '&&',
00235             2 => ':=',
00236             3 => '<<',
00237             4 => '<=',
00238             5 => '<=>',
00239             6 => '<>',
00240             7 => '>=',
00241             8 => '>>',
00242             9 => '||'
00243         );
00244         $allpunct_list_pair_size = 10; //count($allpunct_list_pair);
00245         $quote_list              = '\'"`';
00246         $arraysize               = 0;
00247 
00248         while ($count2 < $len) {
00249             $c      = $sql[$count2];
00250             $count1 = $count2;
00251 
00252             if (($c == "\n")) {
00253                 $count2++;
00254                 PMA_SQP_arrayAdd($sql_array, 'white_newline', '', $arraysize);
00255                 continue;
00256             }
00257 
00258             // Checks for white space
00259             if (PMA_STR_isSpace($c)) {
00260                 $count2++;
00261                 continue;
00262             }
00263 
00264             // Checks for comment lines.
00265             // MySQL style #
00266             // C style /* */
00267             // ANSI style --
00268             if (($c == '#')
00269                 || (($count2 + 1 < $len) && ($c == '/') && ($sql[$count2 + 1] == '*'))
00270                 || (($count2 + 2 < $len) && ($c == '-') && ($sql[$count2 + 1] == '-') && (($sql[$count2 + 2] == ' ') || ($sql[$count2 + 2] == "\n")))) {
00271                 $count2++;
00272                 $pos  = 0;
00273                 $type = 'bad';
00274                 switch ($c) {
00275                     case '#':
00276                         $type = 'mysql';
00277                     case '-':
00278                         $type = 'ansi';
00279                         $pos  = $GLOBALS['PMA_strpos']($sql, "\n", $count2);
00280                         break;
00281                     case '/':
00282                         $type = 'c';
00283                         $pos  = $GLOBALS['PMA_strpos']($sql, '*/', $count2);
00284                         $pos  += 2;
00285                         break;
00286                     default:
00287                         break;
00288                 } // end switch
00289                 $count2 = ($pos < $count2) ? $len : $pos;
00290                 $str    = $GLOBALS['PMA_substr']($sql, $count1, $count2 - $count1);
00291                 PMA_SQP_arrayAdd($sql_array, 'comment_' . $type, $str, $arraysize);
00292                 continue;
00293             } // end if
00294 
00295             // Checks for something inside quotation marks
00296             if (PMA_STR_strInStr($c, $quote_list)) {
00297                 $startquotepos   = $count2;
00298                 $quotetype       = $c;
00299                 $count2++;
00300                 $escaped         = FALSE;
00301                 $escaped_escaped = FALSE;
00302                 $pos             = $count2;
00303                 $oldpos          = 0;
00304                 do {
00305                     $oldpos = $pos;
00306                     $pos    = $GLOBALS['PMA_strpos'](' ' . $sql, $quotetype, $oldpos + 1) - 1;
00307                     // ($pos === FALSE)
00308                     if ($pos < 0) {
00309                         $debugstr = $GLOBALS['strSQPBugUnclosedQuote'] . ' @ ' . $startquotepos. "\n"
00310                                   . 'STR: ' . $quotetype;
00311                         PMA_SQP_throwError($debugstr, $sql);
00312                         return $sql;
00313                     }
00314 
00315                     // If the quote is the first character, it can't be
00316                     // escaped, so don't do the rest of the code
00317                     if ($pos == 0) {
00318                         break;
00319                     }
00320 
00321                     // Checks for MySQL escaping using a \
00322                     // And checks for ANSI escaping using the $quotetype character
00323                     if (($pos < $len) && PMA_STR_charIsEscaped($sql, $pos)) {
00324                         $pos ++;
00325                         continue;
00326                     } else if (($pos + 1 < $len) && ($sql[$pos] == $quotetype) && ($sql[$pos + 1] == $quotetype)) {
00327                         $pos = $pos + 2;
00328                         continue;
00329                     } else {
00330                         break;
00331                     }
00332                 } while ($len > $pos); // end do
00333 
00334                 $count2       = $pos;
00335                 $count2++;
00336                 $type         = 'quote_';
00337                 switch ($quotetype) {
00338                     case '\'':
00339                         $type .= 'single';
00340                         break;
00341                     case '"':
00342                         $type .= 'double';
00343                         break;
00344                     case '`':
00345                         $type .= 'backtick';
00346                         break;
00347                     default:
00348                         break;
00349                 } // end switch
00350                 $data = $GLOBALS['PMA_substr']($sql, $count1, $count2 - $count1);
00351                 PMA_SQP_arrayAdd($sql_array, $type, $data, $arraysize);
00352                 continue;
00353             }
00354 
00355             // Checks for brackets
00356             if (PMA_STR_strInStr($c, $bracket_list)) {
00357                 // All bracket tokens are only one item long
00358                 $count2++;
00359                 $type_type     = '';
00360                 if (PMA_STR_strInStr($c, '([{')) {
00361                     $type_type = 'open';
00362                 } else {
00363                     $type_type = 'close';
00364                 }
00365 
00366                 $type_style     = '';
00367                 if (PMA_STR_strInStr($c, '()')) {
00368                     $type_style = 'round';
00369                 } elseif (PMA_STR_strInStr($c, '[]')) {
00370                     $type_style = 'square';
00371                 } else {
00372                     $type_style = 'curly';
00373                 }
00374 
00375                 $type = 'punct_bracket_' . $type_type . '_' . $type_style;
00376                 PMA_SQP_arrayAdd($sql_array, $type, $c, $arraysize);
00377                 continue;
00378             }
00379 
00380             // Checks for punct
00381             if (PMA_STR_strInStr($c, $allpunct_list)) {
00382                 while (($count2 < $len) && PMA_STR_strInStr($sql[$count2], $allpunct_list)) {
00383                     $count2++;
00384                 }
00385                 $l = $count2 - $count1;
00386                 if ($l == 1) {
00387                     $punct_data = $c;
00388                 } else {
00389                     $punct_data = $GLOBALS['PMA_substr']($sql, $count1, $l);
00390                 }
00391 
00392                 // Special case, sometimes, althought two characters are
00393                 // adjectent directly, they ACTUALLY need to be seperate
00394                 if ($l == 1) {
00395                     $t_suffix         = '';
00396                     switch ($punct_data) {
00397                         case $punct_queryend:
00398                             $t_suffix = '_queryend';
00399                             break;
00400                         case $punct_qualifier:
00401                             $t_suffix = '_qualifier';
00402                             break;
00403                         case $punct_listsep:
00404                             $t_suffix = '_listsep';
00405                             break;
00406                         default:
00407                             break;
00408                     }
00409                     PMA_SQP_arrayAdd($sql_array, 'punct' . $t_suffix, $punct_data, $arraysize);
00410                 }
00411                 else if (PMA_STR_binarySearchInArr($punct_data, $allpunct_list_pair, $allpunct_list_pair_size)) {
00412                     // Ok, we have one of the valid combined punct expressions
00413                     PMA_SQP_arrayAdd($sql_array, 'punct', $punct_data, $arraysize);
00414                 }
00415                 else {
00416                     // Bad luck, lets split it up more
00417                     $first  = $punct_data[0];
00418                     $first2 = $punct_data[0] . $punct_data[1];
00419                     $last2  = $punct_data[$l - 2] . $punct_data[$l - 1];
00420                     $last   = $punct_data[$l - 1];
00421                     if (($first == ',') || ($first == ';') || ($first == '.') || ($first == '*')) {
00422                         $count2     = $count1 + 1;
00423                         $punct_data = $first;
00424                     } else if (($last2 == '/*') || ($last2 == '--')) {
00425                         $count2     -= 2;
00426                         $punct_data = $GLOBALS['PMA_substr']($sql, $count1, $count2 - $count1);
00427                     } else if (($last == '-') || ($last == '+') || ($last == '!')) {
00428                         $count2--;
00429                         $punct_data = $GLOBALS['PMA_substr']($sql, $count1, $count2 - $count1);
00430                     // TODO: for negation operator, split in 2 tokens ?
00431                     // "select x&~1 from t"
00432                     // becomes "select x & ~ 1 from t" ?
00433 
00434                     } else if ($last != '~') {
00435                         $debugstr =  $GLOBALS['strSQPBugUnknownPunctuation'] . ' @ ' . ($count1+1) . "\n"
00436                                   . 'STR: ' . $punct_data;
00437                         PMA_SQP_throwError($debugstr, $sql);
00438                         return $sql;
00439                     }
00440                     PMA_SQP_arrayAdd($sql_array, 'punct', $punct_data, $arraysize);
00441                     continue;
00442                 } // end if... else if... else
00443                 continue;
00444             }
00445 
00446             // Checks for alpha
00447             if (PMA_STR_isSqlIdentifier($c, FALSE) || ($c == '@')) {
00448                 $count2 ++;
00449 
00450                 //TODO: a @ can also be present in expressions like
00451                 // FROM 'user'@'%'
00452                 // in this case, the @ is wrongly marked as alpha_variable
00453 
00454                 $is_sql_variable         = ($c == '@');
00455                 $is_digit                = (!$is_sql_variable) && PMA_STR_isDigit($c);
00456                 $is_hex_digit            = ($is_digit) && ($c == '0') && ($count2 < $len) && ($sql[$count2] == 'x');
00457                 $is_float_digit          = FALSE;
00458                 $is_float_digit_exponent = FALSE;
00459 
00460                 if ($is_hex_digit) {
00461                     $count2++;
00462                 }
00463 
00464                 while (($count2 < $len) && PMA_STR_isSqlIdentifier($sql[$count2], ($is_sql_variable || $is_digit))) {
00465                     $c2 = $sql[$count2];
00466                     if ($is_sql_variable && ($c2 == '.')) {
00467                         $count2++;
00468                         continue;
00469                     }
00470                     if ($is_digit && (!$is_hex_digit) && ($c2 == '.')) {
00471                         $count2++;
00472                         if (!$is_float_digit) {
00473                             $is_float_digit = TRUE;
00474                             continue;
00475                         } else {
00476                             $debugstr = $GLOBALS['strSQPBugInvalidIdentifer'] . ' @ ' . ($count1+1) . "\n"
00477                                       . 'STR: ' . $GLOBALS['PMA_substr']($sql, $count1, $count2 - $count1);
00478                             PMA_SQP_throwError($debugstr, $sql);
00479                             return $sql;
00480                         }
00481                     }
00482                     if ($is_digit && (!$is_hex_digit) && (($c2 == 'e') || ($c2 == 'E'))) {
00483                         if (!$is_float_digit_exponent) {
00484                             $is_float_digit_exponent = TRUE;
00485                             $is_float_digit          = TRUE;
00486                             $count2++;
00487                             continue;
00488                         } else {
00489                             $is_digit                = FALSE;
00490                             $is_float_digit          = FALSE;
00491                         }
00492                     }
00493                     if (($is_hex_digit && PMA_STR_isHexDigit($c2)) || ($is_digit && PMA_STR_isDigit($c2))) {
00494                         $count2++;
00495                         continue;
00496                     } else {
00497                         $is_digit     = FALSE;
00498                         $is_hex_digit = FALSE;
00499                     }
00500 
00501                     $count2++;
00502                 } // end while
00503 
00504                 $l    = $count2 - $count1;
00505                 $str  = $GLOBALS['PMA_substr']($sql, $count1, $l);
00506 
00507                 $type = '';
00508                 if ($is_digit) {
00509                     $type     = 'digit';
00510                     if ($is_float_digit) {
00511                         $type .= '_float';
00512                     } else if ($is_hex_digit) {
00513                         $type .= '_hex';
00514                     } else {
00515                         $type .= '_integer';
00516                     }
00517                 }
00518                 else {
00519                     if ($is_sql_variable != FALSE) {
00520                         $type = 'alpha_variable';
00521                     } else {
00522                         $type = 'alpha';
00523                     }
00524                 } // end if... else....
00525                 PMA_SQP_arrayAdd($sql_array, $type, $str, $arraysize);
00526 
00527                 continue;
00528             }
00529 
00530             // DEBUG
00531             $count2++;
00532 
00533             $debugstr = 'C1 C2 LEN: ' . $count1 . ' ' . $count2 . ' ' . $len .  "\n"
00534                       . 'STR: ' . $GLOBALS['PMA_substr']($sql, $count1, $count2 - $count1) . "\n";
00535             PMA_SQP_bug($debugstr, $sql);
00536             return $sql;
00537 
00538         } // end while ($count2 < $len)
00539 
00540 
00541         if ($arraysize > 0) {
00542           $t_next           = $sql_array[0]['type'];
00543           $t_prev           = '';
00544           $t_bef_prev       = '';
00545           $t_cur            = '';
00546           $d_next           = $sql_array[0]['data'];
00547           $d_prev           = '';
00548           $d_bef_prev       = '';
00549           $d_cur            = '';
00550           $d_next_upper     = $t_next == 'alpha' ? strtoupper($d_next) : $d_next;
00551           $d_prev_upper     = '';
00552           $d_bef_prev_upper = '';
00553           $d_cur_upper      = '';
00554         }
00555 
00556         for ($i = 0; $i < $arraysize; $i++) {
00557           $t_bef_prev       = $t_prev;
00558           $t_prev           = $t_cur;
00559           $t_cur            = $t_next;
00560           $d_bef_prev       = $d_prev;
00561           $d_prev           = $d_cur;
00562           $d_cur            = $d_next;
00563           $d_bef_prev_upper = $d_prev_upper;
00564           $d_prev_upper     = $d_cur_upper;
00565           $d_cur_upper      = $d_next_upper;
00566           if (($i + 1) < $arraysize) {
00567             $t_next = $sql_array[$i + 1]['type'];
00568             $d_next = $sql_array[$i + 1]['data'];
00569             $d_next_upper = $t_next == 'alpha' ? strtoupper($d_next) : $d_next;
00570           } else {
00571             $t_next       = '';
00572             $d_next       = '';
00573             $d_next_upper = '';
00574           }
00575 
00576           //DEBUG echo "[prev: <b>".$d_prev."</b> ".$t_prev."][cur: <b>".$d_cur."</b> ".$t_cur."][next: <b>".$d_next."</b> ".$t_next."]<br>";
00577 
00578           if ($t_cur == 'alpha') {
00579             $t_suffix     = '_identifier';
00580             if (($t_next == 'punct_qualifier') || ($t_prev == 'punct_qualifier')) {
00581               $t_suffix = '_identifier';
00582             } else if (($t_next == 'punct_bracket_open_round')
00583             && PMA_STR_binarySearchInArr($d_cur_upper, $PMA_SQPdata_function_name, $PMA_SQPdata_function_name_cnt)) {
00584               $t_suffix = '_functionName';
00585             } else if (PMA_STR_binarySearchInArr($d_cur_upper, $PMA_SQPdata_column_type, $PMA_SQPdata_column_type_cnt))  {
00586               $t_suffix = '_columnType';
00587 
00588               // Temporary fix for BUG #621357
00589               //TODO FIX PROPERLY NEEDS OVERHAUL OF SQL TOKENIZER
00590               if ($d_cur_upper == 'SET' && $t_next != 'punct_bracket_open_round') {
00591                 $t_suffix = '_reservedWord';
00592               }
00593               //END OF TEMPORARY FIX
00594 
00595               // CHARACTER is a synonym for CHAR, but can also be meant as
00596               // CHARACTER SET. In this case, we have a reserved word.
00597               if ($d_cur_upper == 'CHARACTER' && $d_next_upper == 'SET') {
00598                 $t_suffix = '_reservedWord';
00599               }
00600 
00601               // experimental
00602               // current is a column type, so previous must not be
00603               // a reserved word but an identifier
00604               // CREATE TABLE SG_Persons (first varchar(64))
00605 
00606               //if ($sql_array[$i-1]['type'] =='alpha_reservedWord') {
00607               //    $sql_array[$i-1]['type'] = 'alpha_identifier';
00608               //}
00609 
00610             } else if (PMA_STR_binarySearchInArr($d_cur_upper, $PMA_SQPdata_reserved_word, $PMA_SQPdata_reserved_word_cnt)) {
00611               $t_suffix = '_reservedWord';
00612             } else if (PMA_STR_binarySearchInArr($d_cur_upper, $PMA_SQPdata_column_attrib, $PMA_SQPdata_column_attrib_cnt)) {
00613               $t_suffix = '_columnAttrib';
00614               // INNODB is a MySQL table type, but in "SHOW INNODB STATUS",
00615               // it should be regarded as a reserved word.
00616               if ($d_cur_upper == 'INNODB' && $d_prev_upper == 'SHOW' && $d_next_upper == 'STATUS') {
00617                 $t_suffix = '_reservedWord';
00618               }
00619 
00620               if ($d_cur_upper == 'DEFAULT' && $d_next_upper == 'CHARACTER') {
00621                 $t_suffix = '_reservedWord';
00622               }
00623               // Binary as character set
00624               if ($d_cur_upper == 'BINARY' && (
00625                   ($d_bef_prev_upper == 'CHARACTER' && $d_prev_upper == 'SET')
00626                   || ($d_bef_prev_upper == 'SET' && $d_prev_upper == '=')
00627                   || ($d_bef_prev_upper == 'CHARSET' && $d_prev_upper == '=')
00628                   || $prev_upper == 'CHARSET'
00629                   ) && PMA_STR_binarySearchInArr($d_cur, $mysql_charsets, count($mysql_charsets))) {
00630                   $t_suffix = '_charset';
00631               }
00632             } elseif (PMA_STR_binarySearchInArr($d_cur, $mysql_charsets, $mysql_charsets_count)
00633               || PMA_STR_binarySearchInArr($d_cur, $mysql_collations_flat, $mysql_collations_count)
00634               || ($d_cur{0} == '_' && PMA_STR_binarySearchInArr(substr($d_cur, 1), $mysql_charsets, $mysql_charsets_count))) {
00635               $t_suffix = '_charset';
00636             } else {
00637               // Do nothing
00638             }
00639             $sql_array[$i]['type'] .= $t_suffix;
00640           }
00641         } // end for
00642 
00643         // Stores the size of the array inside the array, as count() is a slow
00644         // operation.
00645         $sql_array['len'] = $arraysize;
00646 
00647         // Sends the data back
00648         return $sql_array;
00649     } // end of the "PMA_SQP_parse()" function
00650 
00661     function PMA_SQP_typeCheck($toCheck, $whatWeWant)
00662     {
00663         $typeSeperator = '_';
00664         if(strcmp($whatWeWant, $toCheck) == 0) {
00665             return TRUE;
00666         } else {
00667             //if(strpos($whatWeWant, $typeSeperator) === FALSE) {
00668             // PHP3 compatible (works unless there is a real ff character)
00669             if(!strpos("\xff" . $whatWeWant, $typeSeperator)) {
00670                 return strncmp($whatWeWant, $toCheck , strpos($toCheck, $typeSeperator)) == 0;
00671             } else {
00672                 return FALSE;
00673             }
00674         }
00675     }
00676 
00677 
00687     function PMA_SQP_analyze($arr)
00688     {
00689         $result          = array();
00690         $size            = $arr['len'];
00691         $subresult       = array(
00692             'querytype'      => '',
00693             'select_expr_clause'=> '', // the whole stuff between SELECT and FROM , except DISTINCT
00694             'position_of_first_select' => '', // the array index
00695             'from_clause'=> '',
00696             'group_by_clause'=> '',
00697             'order_by_clause'=> '',
00698             'having_clause'  => '',
00699             'where_clause'   => '',
00700             'where_clause_identifiers'   => array(),
00701             'queryflags'     => array(),
00702             'select_expr'    => array(),
00703             'table_ref'      => array(),
00704             'foreign_keys'   => array()
00705         );
00706         $subresult_empty = $subresult;
00707         $seek_queryend         = FALSE;
00708         $seen_end_of_table_ref = FALSE;
00709 
00710         // for SELECT EXTRACT(YEAR_MONTH FROM CURDATE())
00711         // we must not use CURDATE as a table_ref
00712         // so we track wether we are in the EXTRACT()
00713         $in_extract          = FALSE;
00714 
00715 /* Description of analyzer results
00716  *
00717  * lem9: db, table, column, alias
00718  *      ------------------------
00719  *
00720  * Inside the $subresult array, we create ['select_expr'] and ['table_ref'] arrays.
00721  *
00722  * The SELECT syntax (simplified) is
00723  *
00724  * SELECT
00725  *    select_expression,...
00726  *    [FROM [table_references]
00727  *
00728  *
00729  * ['select_expr'] is filled with each expression, the key represents the
00730  * expression position in the list (0-based) (so we don't lose track of
00731  * multiple occurences of the same column).
00732  *
00733  * ['table_ref'] is filled with each table ref, same thing for the key.
00734  *
00735  * I create all sub-values empty, even if they are
00736  * not present (for example no select_expression alias).
00737  *
00738  * There is a debug section at the end of loop #1, if you want to
00739  * see the exact contents of select_expr and table_ref
00740  *
00741  * lem9: queryflags
00742  *       ----------
00743  *
00744  * In $subresult, array 'queryflags' is filled, according to what we
00745  * find in the query.
00746  *
00747  * Currently, those are generated:
00748  *
00749  * ['queryflags']['need_confirm'] = 1; if the query needs confirmation
00750  * ['queryflags']['select_from'] = 1; if this is a real SELECT...FROM
00751  * ['queryflags']['distinct'] = 1;    for a DISTINCT
00752  * ['queryflags']['union'] = 1;       for a UNION
00753  *
00754  * lem9:  query clauses
00755  *        -------------
00756  *
00757  * The select is splitted in those clauses:
00758  * ['select_expr_clause']
00759  * ['from_clause']
00760  * ['group_by_clause']
00761  * ['order_by_clause']
00762  * ['having_clause']
00763  * ['where_clause']
00764  *
00765  * and the identifiers of the where clause are put into the array
00766  * ['where_clause_identifier']
00767  *
00768  * lem9:   foreign keys
00769  *         ------------
00770  * The CREATE TABLE may contain FOREIGN KEY clauses, so they get
00771  * analyzed and ['foreign_keys'] is an array filled with
00772  * the constraint name, the index list,
00773  * the REFERENCES table name and REFERENCES index list,
00774  * and ON UPDATE | ON DELETE clauses
00775  *
00776  * lem9: position_of_first_select
00777  *       ------------------------
00778  *
00779  * The array index of the first SELECT we find. Will be used to
00780  * insert a SQL_CALC_FOUND_ROWS.
00781  */
00782 
00783         // must be sorted
00784         // TODO: current logic checks for only one word, so I put only the
00785         // first word of the reserved expressions that end a table ref;
00786         // maybe this is not ok (the first word might mean something else)
00787 //        $words_ending_table_ref = array(
00788 //            'FOR UPDATE',
00789 //            'GROUP BY',
00790 //            'HAVING',
00791 //            'LIMIT',
00792 //            'LOCK IN SHARE MODE',
00793 //            'ORDER BY',
00794 //            'PROCEDURE',
00795 //            'UNION',
00796 //            'WHERE'
00797 //        );
00798         $words_ending_table_ref = array(
00799             'FOR',
00800             'GROUP',
00801             'HAVING',
00802             'LIMIT',
00803             'LOCK',
00804             'ORDER',
00805             'PROCEDURE',
00806             'UNION',
00807             'WHERE'
00808         );
00809         $words_ending_table_ref_cnt = 9; //count($words_ending_table_ref);
00810 
00811         $words_ending_clauses = array(
00812             'FOR',
00813             'LIMIT',
00814             'LOCK',
00815             'PROCEDURE',
00816             'UNION'
00817         );
00818         $words_ending_clauses_cnt = 5; //count($words_ending_clauses);
00819 
00820 
00821 
00822 
00823         // must be sorted
00824         $supported_query_types = array(
00825             'SELECT'
00826             /*
00827             // Support for these additional query types will come later on.
00828             'DELETE',
00829             'INSERT',
00830             'REPLACE',
00831             'TRUNCATE',
00832             'UPDATE'
00833             'EXPLAIN',
00834             'DESCRIBE',
00835             'SHOW',
00836             'CREATE',
00837             'SET',
00838             'ALTER'
00839             */
00840         );
00841         $supported_query_types_cnt = count($supported_query_types);
00842 
00843         // loop #1 for each token: select_expr, table_ref for SELECT
00844 
00845         for ($i = 0; $i < $size; $i++) {
00846 //echo "trace <b>"  . $arr[$i]['data'] . "</b> (" . $arr[$i]['type'] . ")<br>";
00847 
00848             // High speed seek for locating the end of the current query
00849             if ($seek_queryend == TRUE) {
00850                 if ($arr[$i]['type'] == 'punct_queryend') {
00851                     $seek_queryend = FALSE;
00852                 } else {
00853                     continue;
00854                 } // end if (type == punct_queryend)
00855             } // end if ($seek_queryend)
00856 
00857             // TODO: when we find a UNION, should we split
00858             // in another subresult?
00859             if ($arr[$i]['type'] == 'punct_queryend') {
00860                 $result[]  = $subresult;
00861                 $subresult = $subresult_empty;
00862                 continue;
00863             } // end if (type == punct_queryend)
00864 
00865 // ==============================================================
00866             if ($arr[$i]['type'] == 'punct_bracket_open_round') {
00867                 if ($in_extract) {
00868                     $number_of_brackets_in_extract++;
00869                 }
00870             }
00871 // ==============================================================
00872             if ($arr[$i]['type'] == 'punct_bracket_close_round') {
00873                 if ($in_extract) {
00874                     $number_of_brackets_in_extract--;
00875                     if ($number_of_brackets_in_extract == 0) {
00876                        $in_extract = FALSE;
00877                     }
00878                 }
00879             }
00880 // ==============================================================
00881             if ($arr[$i]['type'] == 'alpha_functionName') {
00882                 $upper_data = strtoupper($arr[$i]['data']);
00883                 if ($upper_data =='EXTRACT') {
00884                     $in_extract = TRUE;
00885                     $number_of_brackets_in_extract = 0;
00886                 }
00887             }
00888 
00889 // ==============================================================
00890             if ($arr[$i]['type'] == 'alpha_reservedWord') {
00891                 // We don't know what type of query yet, so run this
00892                 if ($subresult['querytype'] == '') {
00893                     $subresult['querytype'] = strtoupper($arr[$i]['data']);
00894                 } // end if (querytype was empty)
00895 
00896                 // Check if we support this type of query
00897                 if (!PMA_STR_binarySearchInArr($subresult['querytype'], $supported_query_types, $supported_query_types_cnt)) {
00898                     // Skip ahead to the next one if we don't
00899                     $seek_queryend = TRUE;
00900                     continue;
00901                 } // end if (query not supported)
00902 
00903                 // upper once
00904                 $upper_data = strtoupper($arr[$i]['data']);
00905                 //TODO: reset for each query?
00906 
00907                 if ($upper_data == 'SELECT') {
00908                     $seen_from = FALSE;
00909                     $previous_was_identifier = FALSE;
00910                     $current_select_expr = -1;
00911                     $seen_end_of_table_ref = FALSE;
00912                 } // end if ( data == SELECT)
00913 
00914                 if ($upper_data =='FROM' && !$in_extract) {
00915                     $current_table_ref = -1;
00916                     $seen_from = TRUE;
00917                     $previous_was_identifier = FALSE;
00918                     $save_table_ref = TRUE;
00919                 } // end if (data == FROM)
00920 
00921                 // here, do not 'continue' the loop, as we have more work for
00922                 // reserved words below
00923             } // end if (type == alpha_reservedWord)
00924 
00925 // ==============================
00926             if (($arr[$i]['type'] == 'quote_backtick')
00927              || ($arr[$i]['type'] == 'quote_double')
00928              || ($arr[$i]['type'] == 'quote_single')
00929              || ($arr[$i]['type'] == 'alpha_identifier')) {
00930 
00931                 switch ($arr[$i]['type']) {
00932                     case 'alpha_identifier':
00933                         $identifier = $arr[$i]['data'];
00934                         break;
00935 
00936                 //TODO: check embedded double quotes or backticks?
00937                 // and/or remove just the first and last character?
00938                     case 'quote_backtick':
00939                         $identifier = str_replace('`','',$arr[$i]['data']);
00940                         break;
00941                     case 'quote_double':
00942                         $identifier = str_replace('"','',$arr[$i]['data']);
00943                         break;
00944                     case 'quote_single':
00945                         $identifier = str_replace("'","",$arr[$i]['data']);
00946                         break;
00947                 } // end switch
00948 
00949                 if ($subresult['querytype'] == 'SELECT') {
00950                     if (!$seen_from) {
00951                         if ($previous_was_identifier && isset($chain)) {
00952                             // found alias for this select_expr, save it
00953                             // but only if we got something in $chain
00954                             // (for example, SELECT COUNT(*) AS cnt
00955                             // puts nothing in $chain, so we avoid
00956                             // setting the alias)
00957                             $alias_for_select_expr = $identifier;
00958                         } else {
00959                             $chain[] = $identifier;
00960                             $previous_was_identifier = TRUE;
00961 
00962                         } // end if !$previous_was_identifier
00963                     } else {
00964                         // ($seen_from)
00965                         if ($save_table_ref && !$seen_end_of_table_ref) {
00966                             if ($previous_was_identifier) {
00967                                 // found alias for table ref
00968                                 // save it for later
00969                                 $alias_for_table_ref = $identifier;
00970                             } else {
00971                                 $chain[] = $identifier;
00972                                 $previous_was_identifier = TRUE;
00973 
00974                             } // end if ($previous_was_identifier)
00975                         } // end if ($save_table_ref &&!$seen_end_of_table_ref)
00976                     } // end if (!$seen_from)
00977                 } // end if (querytype SELECT)
00978             } // end if ( quote_backtick or double quote or alpha_identifier)
00979 
00980 // ===================================
00981             if ($arr[$i]['type'] == 'punct_qualifier') {
00982                 // to be able to detect an identifier following another
00983                 $previous_was_identifier = FALSE;
00984                 continue;
00985             } // end if (punct_qualifier)
00986 
00987             // TODO: check if 3 identifiers following one another -> error
00988 
00989             //    s a v e    a    s e l e c t    e x p r
00990             // finding a list separator or FROM
00991             // means that we must save the current chain of identifiers
00992             // into a select expression
00993 
00994             // for now, we only save a select expression if it contains
00995             // at least one identifier, as we are interested in checking
00996             // the columns and table names, so in "select * from persons",
00997             // the "*" is not saved
00998 
00999             if (isset($chain) && !$seen_end_of_table_ref
01000                && (   (!$seen_from
01001                    && $arr[$i]['type'] == 'punct_listsep')
01002                   || ($arr[$i]['type'] == 'alpha_reservedWord' && $upper_data == 'FROM')) ) {
01003                 $size_chain = count($chain);
01004                 $current_select_expr++;
01005                 $subresult['select_expr'][$current_select_expr] = array(
01006                   'expr' => '',
01007                   'alias' => '',
01008                   'db'   => '',
01009                   'table_name' => '',
01010                   'table_true_name' => '',
01011                   'column' => ''
01012                  );
01013 
01014                 if (!empty($alias_for_select_expr)) {
01015                     // we had found an alias for this select expression
01016                     $subresult['select_expr'][$current_select_expr]['alias'] = $alias_for_select_expr;
01017                     unset($alias_for_select_expr);
01018                 }
01019                 // there is at least a column
01020                 $subresult['select_expr'][$current_select_expr]['column'] = $chain[$size_chain - 1];
01021                 $subresult['select_expr'][$current_select_expr]['expr'] = $chain[$size_chain - 1];
01022 
01023                 // maybe a table
01024                 if ($size_chain > 1) {
01025                     $subresult['select_expr'][$current_select_expr]['table_name'] = $chain[$size_chain - 2];
01026                     // we assume for now that this is also the true name
01027                     $subresult['select_expr'][$current_select_expr]['table_true_name'] = $chain[$size_chain - 2];
01028                     $subresult['select_expr'][$current_select_expr]['expr']
01029                      = $subresult['select_expr'][$current_select_expr]['table_name']
01030                       . '.' . $subresult['select_expr'][$current_select_expr]['expr'];
01031                 } // end if ($size_chain > 1)
01032 
01033                 // maybe a db
01034                 if ($size_chain > 2) {
01035                     $subresult['select_expr'][$current_select_expr]['db'] = $chain[$size_chain - 3];
01036                     $subresult['select_expr'][$current_select_expr]['expr']
01037                      = $subresult['select_expr'][$current_select_expr]['db']
01038                       . '.' . $subresult['select_expr'][$current_select_expr]['expr'];
01039                 } // end if ($size_chain > 2)
01040                 unset($chain);
01041 
01042                 // TODO: explain this:
01043                 if (($arr[$i]['type'] == 'alpha_reservedWord')
01044                  && ($upper_data != 'FROM')) {
01045                     $previous_was_identifier = TRUE;
01046                 }
01047 
01048             } // end if (save a select expr)
01049 
01050 
01051             //======================================
01052             //    s a v e    a    t a b l e    r e f
01053             //======================================
01054 
01055             // maybe we just saw the end of table refs
01056             // but the last table ref has to be saved
01057             // or we are at the last token (TODO: there could be another
01058             // query after this one)
01059             // or we just got a reserved word
01060 
01061             if (isset($chain) && $seen_from && $save_table_ref
01062              && ($arr[$i]['type'] == 'punct_listsep'
01063                || ($arr[$i]['type'] == 'alpha_reservedWord' && $upper_data!="AS")
01064                || $seen_end_of_table_ref
01065                || $i==$size-1 )) {
01066 
01067                 $size_chain = count($chain);
01068                 $current_table_ref++;
01069                 $subresult['table_ref'][$current_table_ref] = array(
01070                   'expr'            => '',
01071                   'db'              => '',
01072                   'table_name'      => '',
01073                   'table_alias'     => '',
01074                   'table_true_name' => ''
01075                  );
01076                 if (!empty($alias_for_table_ref)) {
01077                     $subresult['table_ref'][$current_table_ref]['table_alias'] = $alias_for_table_ref;
01078                     unset($alias_for_table_ref);
01079                 }
01080                 $subresult['table_ref'][$current_table_ref]['table_name'] = $chain[$size_chain - 1];
01081                 // we assume for now that this is also the true name
01082                 $subresult['table_ref'][$current_table_ref]['table_true_name'] = $chain[$size_chain - 1];
01083                 $subresult['table_ref'][$current_table_ref]['expr']
01084                      = $subresult['table_ref'][$current_table_ref]['table_name'];
01085                 // maybe a db
01086                 if ($size_chain > 1) {
01087                     $subresult['table_ref'][$current_table_ref]['db'] = $chain[$size_chain - 2];
01088                     $subresult['table_ref'][$current_table_ref]['expr']
01089                      = $subresult['table_ref'][$current_table_ref]['db']
01090                       . '.' . $subresult['table_ref'][$current_table_ref]['expr'];
01091                 } // end if ($size_chain > 1)
01092 
01093                 // add the table alias into the whole expression
01094                 $subresult['table_ref'][$current_table_ref]['expr']
01095                  .= ' ' . $subresult['table_ref'][$current_table_ref]['table_alias'];
01096 
01097                 unset($chain);
01098                 $previous_was_identifier = TRUE;
01099                 //continue;
01100 
01101             } // end if (save a table ref)
01102 
01103 
01104             // when we have found all table refs,
01105             // for each table_ref alias, put the true name of the table
01106             // in the corresponding select expressions
01107 
01108             if (isset($current_table_ref) && ($seen_end_of_table_ref || $i == $size-1)) {
01109                 for ($tr=0; $tr <= $current_table_ref; $tr++) {
01110                     $alias = $subresult['table_ref'][$tr]['table_alias'];
01111                     $truename = $subresult['table_ref'][$tr]['table_true_name'];
01112                     for ($se=0; $se <= $current_select_expr; $se++) {
01113                         if (!empty($alias) && $subresult['select_expr'][$se]['table_true_name']
01114                            == $alias) {
01115                             $subresult['select_expr'][$se]['table_true_name']
01116                              = $truename;
01117                         } // end if (found the alias)
01118                     } // end for (select expressions)
01119 
01120                 } // end for (table refs)
01121             } // end if (set the true names)
01122 
01123 
01124            // e n d i n g    l o o p  #1
01125            // set the $previous_was_identifier to FALSE if the current
01126            // token is not an identifier
01127            if (($arr[$i]['type'] != 'alpha_identifier')
01128             && ($arr[$i]['type'] != 'quote_double')
01129             && ($arr[$i]['type'] != 'quote_single')
01130             && ($arr[$i]['type'] != 'quote_backtick')) {
01131                $previous_was_identifier = FALSE;
01132            } // end if
01133 
01134            // however, if we are on AS, we must keep the $previous_was_identifier
01135            if (($arr[$i]['type'] == 'alpha_reservedWord')
01136             && ($upper_data == 'AS'))  {
01137                $previous_was_identifier = TRUE;
01138            }
01139 
01140            if (($arr[$i]['type'] == 'alpha_reservedWord')
01141             && ($upper_data =='ON' || $upper_data =='USING')) {
01142                $save_table_ref = FALSE;
01143            } // end if (data == ON)
01144 
01145            if (($arr[$i]['type'] == 'alpha_reservedWord')
01146             && ($upper_data =='JOIN' || $upper_data =='FROM')) {
01147                $save_table_ref = TRUE;
01148            } // end if (data == JOIN)
01149 
01150            // no need to check the end of table ref if we already did
01151            // TODO: maybe add "&& $seen_from"
01152            if (!$seen_end_of_table_ref) {
01153                // if this is the last token, it implies that we have
01154                // seen the end of table references
01155                // Check for the end of table references
01156                if (($i == $size-1)
01157                || ($arr[$i]['type'] == 'alpha_reservedWord'
01158                   && PMA_STR_binarySearchInArr($upper_data, $words_ending_table_ref, $words_ending_table_ref_cnt))) {
01159                    $seen_end_of_table_ref = TRUE;
01160 
01161                    // to be able to save the last table ref, but do not
01162                    // set it true if we found a word like "ON" that has
01163                    // already set it to false
01164                    if (isset($save_table_ref) && $save_table_ref != FALSE) {
01165                       $save_table_ref = TRUE;
01166                    } //end if
01167 
01168                } // end if (check for end of table ref)
01169            } //end if (!$seen_end_of_table_ref)
01170 
01171            if ($seen_end_of_table_ref) {
01172                $save_table_ref = FALSE;
01173            } // end if
01174 
01175         } // end for $i (loop #1)
01176 
01177         // -------------------------------------------------------
01178         // This is a big hunk of debugging code by Marc for this.
01179         // -------------------------------------------------------
01180         /*
01181           if (isset($current_select_expr)) {
01182            for ($trace=0; $trace<=$current_select_expr; $trace++) {
01183 
01184            echo "<br>";
01185            reset ($subresult['select_expr'][$trace]);
01186            while (list ($key, $val) = each ($subresult['select_expr'][$trace]))
01187            echo "sel expr $trace $key => $val<br />\n";
01188            }
01189           }
01190 
01191           if (isset($current_table_ref)) {
01192            for ($trace=0; $trace<=$current_table_ref; $trace++) {
01193 
01194            echo "<br>";
01195            reset ($subresult['table_ref'][$trace]);
01196            while (list ($key, $val) = each ($subresult['table_ref'][$trace]))
01197            echo "table ref $trace $key => $val<br />\n";
01198            }
01199           }
01200         */
01201         // -------------------------------------------------------
01202 
01203 
01204         // loop #2: for queryflags
01205         //          ,querytype (for queries != 'SELECT')
01206         //
01207         // we will also need this queryflag in loop 2
01208         // so set it here
01209         if (isset($current_table_ref) && $current_table_ref > -1) {
01210             $subresult['queryflags']['select_from'] = 1;
01211         }
01212 
01213         $seen_reserved_word = FALSE;
01214         $seen_group = FALSE;
01215         $seen_order = FALSE;
01216         $in_group_by = FALSE; // true when we are into the GROUP BY clause
01217         $in_order_by = FALSE; // true when we are into the ORDER BY clause
01218         $in_having = FALSE; // true when we are into the HAVING clause
01219         $in_select_expr = FALSE; // true when we are into the select expr clause
01220         $in_where = FALSE; // true when we are into the WHERE clause
01221         $in_from = FALSE;
01222 
01223         for ($i = 0; $i < $size; $i++) {
01224 //DEBUG echo "trace loop2 <b>"  . $arr[$i]['data'] . "</b> (" . $arr[$i]['type'] . ")<br>";
01225 
01226            // need_confirm
01227            //
01228            // check for reserved words that will have to generate
01229            // a confirmation request later in sql.php
01230            // the cases are:
01231            //   DROP TABLE
01232            //   DROP DATABASE
01233            //   ALTER TABLE... DROP
01234            //   DELETE FROM...
01235            //
01236            // this code is not used for confirmations coming from functions.js
01237 
01238            // TODO: check for punct_queryend
01239 
01240            if ($arr[$i]['type'] == 'alpha_reservedWord') {
01241                $upper_data = strtoupper($arr[$i]['data']);
01242                if (!$seen_reserved_word) {
01243                    $first_reserved_word = $upper_data;
01244                    $subresult['querytype'] = $upper_data;
01245                    $seen_reserved_word = TRUE;
01246 
01247                    // if the first reserved word is DROP or DELETE,
01248                    // we know this is a query that needs to be confirmed
01249                    if ($first_reserved_word=='DROP'
01250                        || $first_reserved_word == 'DELETE'
01251                        || $first_reserved_word == 'TRUNCATE') {
01252                       $subresult['queryflags']['need_confirm'] = 1;
01253                    }
01254 
01255                    if ($first_reserved_word=='SELECT'){
01256                        $position_of_first_select = $i;
01257                    }
01258 
01259                } else {
01260                    if ($upper_data=='DROP' && $first_reserved_word=='ALTER') {
01261                       $subresult['queryflags']['need_confirm'] = 1;
01262                    }
01263                }
01264 
01265                if ($upper_data == 'SELECT') {
01266                    $in_select_expr = TRUE;
01267                    $select_expr_clause = '';
01268                }
01269                if ($upper_data == 'DISTINCT') {
01270                       $subresult['queryflags']['distinct'] = 1;
01271                }
01272 
01273                if ($upper_data == 'UNION') {
01274                       $subresult['queryflags']['union'] = 1;
01275                }
01276 
01277                // if this is a real SELECT...FROM
01278                if ($upper_data == 'FROM' && isset($subresult['queryflags']['select_from']) && $subresult['queryflags']['select_from'] == 1) {
01279                    $in_from = TRUE;
01280                    $from_clause = '';
01281                    $in_select_expr = FALSE;
01282                }
01283 
01284 
01285                // (we could have less resetting of variables to FALSE
01286                // if we trust that the query respects the standard
01287                // MySQL order for clauses)
01288 
01289                // we use $seen_group and $seen_order because we are looking
01290                // for the BY
01291                if ($upper_data == 'GROUP') {
01292                    $seen_group = TRUE;
01293                    $seen_order = FALSE;
01294                    $in_having = FALSE;
01295                    $in_order_by = FALSE;
01296                    $in_where = FALSE;
01297                    $in_select_expr = FALSE;
01298                    $in_from = FALSE;
01299                }
01300                if ($upper_data == 'ORDER') {
01301                    $seen_order = TRUE;
01302                    $seen_group = FALSE;
01303                    $in_having = FALSE;
01304                    $in_group_by = FALSE;
01305                    $in_where = FALSE;
01306                    $in_select_expr = FALSE;
01307                    $in_from = FALSE;
01308                }
01309                if ($upper_data == 'HAVING') {
01310                    $in_having = TRUE;
01311                    $having_clause = '';
01312                    $seen_group = FALSE;
01313                    $seen_order = FALSE;
01314                    $in_group_by = FALSE;
01315                    $in_order_by = FALSE;
01316                    $in_where = FALSE;
01317                    $in_select_expr = FALSE;
01318                    $in_from = FALSE;
01319                }
01320 
01321                if ($upper_data == 'WHERE') {
01322                    $in_where = TRUE;
01323                    $where_clause = '';
01324                    $where_clause_identifiers = array();
01325                    $seen_group = FALSE;
01326                    $seen_order = FALSE;
01327                    $in_group_by = FALSE;
01328                    $in_order_by = FALSE;
01329                    $in_having = FALSE;
01330                    $in_select_expr = FALSE;
01331                    $in_from = FALSE;
01332                }
01333 
01334                if ($upper_data == 'BY') {
01335                    if ($seen_group) {
01336                        $in_group_by = TRUE;
01337                        $group_by_clause = '';
01338                    }
01339                    if ($seen_order) {
01340                        $in_order_by = TRUE;
01341                        $order_by_clause = '';
01342                    }
01343                }
01344 
01345                // if we find one of the words that could end the clause
01346                if (PMA_STR_binarySearchInArr($upper_data, $words_ending_clauses, $words_ending_clauses_cnt)) {
01347 
01348                    $in_group_by = FALSE;
01349                    $in_order_by = FALSE;
01350                    $in_having   = FALSE;
01351                    $in_where    = FALSE;
01352                    $in_select_expr = FALSE;
01353                    $in_from = FALSE;
01354                }
01355 
01356            } // endif (reservedWord)
01357 
01358 
01359            // do not add a blank after a function name
01360 
01361            $sep=' ';
01362            if ($arr[$i]['type'] == 'alpha_functionName') {
01363                $sep='';
01364            }
01365 
01366            if ($in_select_expr && $upper_data != 'SELECT' && $upper_data != 'DISTINCT') {
01367                $select_expr_clause .= $arr[$i]['data'] . $sep;
01368            }
01369            if ($in_from && $upper_data != 'FROM') {
01370                $from_clause .= $arr[$i]['data'] . $sep;
01371            }
01372            if ($in_group_by && $upper_data != 'GROUP' && $upper_data != 'BY') {
01373                $group_by_clause .= $arr[$i]['data'] . $sep;
01374            }
01375            if ($in_order_by && $upper_data != 'ORDER' && $upper_data != 'BY') {
01376                $order_by_clause .= $arr[$i]['data'] . $sep;
01377            }
01378            if ($in_having && $upper_data != 'HAVING') {
01379                $having_clause .= $arr[$i]['data'] . $sep;
01380            }
01381            if ($in_where && $upper_data != 'WHERE') {
01382                $where_clause .= $arr[$i]['data'] . $sep;
01383 
01384                if (($arr[$i]['type'] == 'quote_backtick')
01385                 || ($arr[$i]['type'] == 'alpha_identifier')) {
01386                    $where_clause_identifiers[] = $arr[$i]['data'];
01387                }
01388            }
01389 
01390            // clear $upper_data for next iteration
01391            $upper_data='';
01392 
01393         } // end for $i (loop #2)
01394 
01395         // -----------------------------------------------------
01396         // loop #3: foreign keys
01397         // (for now, check only the first query)
01398         // (for now, identifiers must be backquoted)
01399 
01400         $seen_foreign = FALSE;
01401         $seen_references = FALSE;
01402         $seen_constraint = FALSE;
01403         $in_bracket = FALSE;
01404         $foreign_key_number = -1;
01405 
01406         for ($i = 0; $i < $size; $i++) {
01407         // DEBUG echo "<b>" . $arr[$i]['data'] . "</b> " . $arr[$i]['type'] . "<br>";
01408             if ($arr[$i]['type'] == 'alpha_reservedWord') {
01409                $upper_data = strtoupper($arr[$i]['data']);
01410 
01411                if ($upper_data == 'CONSTRAINT') {
01412                    $foreign_key_number++;
01413                    $seen_foreign = FALSE;
01414                    $seen_references = FALSE;
01415                    $seen_constraint = TRUE;
01416                }
01417                if ($upper_data == 'FOREIGN') {
01418                    $seen_foreign = TRUE;
01419                    $seen_references = FALSE;
01420                    $seen_constraint = FALSE;
01421                }
01422                if ($upper_data == 'REFERENCES') {
01423                    $seen_foreign = FALSE;
01424                    $seen_references = TRUE;
01425                    $seen_constraint = FALSE;
01426                }
01427 
01428 
01429               // [ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
01430               // [ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
01431 
01432               // but we set ['on_delete'] or ['on_cascade'] to
01433               // CASCADE | SET_NULL | NO_ACTION | RESTRICT
01434 
01435                if ($upper_data == 'ON') {
01436                    unset($clause);
01437                    if ($arr[$i+1]['type'] == 'alpha_reservedWord') {
01438                        $second_upper_data = strtoupper($arr[$i+1]['data']);
01439                        if ($second_upper_data == 'DELETE') {
01440                             $clause = 'on_delete';
01441                        }
01442                        if ($second_upper_data == 'UPDATE') {
01443                             $clause = 'on_update';
01444                        }
01445                        if (isset($clause)
01446                        && ($arr[$i+2]['type'] == 'alpha_reservedWord'
01447 
01448              // ugly workaround because currently, NO is not
01449              // in the list of reserved words in sqlparser.data
01450              // (we got a bug report about not being able to use
01451              // 'no' as an identifier)
01452                            || ($arr[$i+2]['type'] == 'alpha_identifier'
01453                               && strtoupper($arr[$i+2]['data'])=='NO') )
01454                           ) {
01455                           $third_upper_data = strtoupper($arr[$i+2]['data']);
01456                           if ($third_upper_data == 'CASCADE'
01457                            || $third_upper_data == 'RESTRICT') {
01458                               $value = $third_upper_data;
01459                           } elseif ($third_upper_data == 'SET'
01460                                  || $third_upper_data == 'NO') {
01461                               if ($arr[$i+3]['type'] == 'alpha_reservedWord') {
01462                                   $value = $third_upper_data . '_' . strtoupper($arr[$i+3]['data']);
01463                               }
01464                           }
01465                           $foreign[$foreign_key_number][$clause] = $value;
01466                        }
01467                    }
01468                }
01469 
01470             }
01471 
01472             if ($arr[$i]['type'] == 'punct_bracket_open_round') {
01473                 $in_bracket = TRUE;
01474             }
01475 
01476             if ($arr[$i]['type'] == 'punct_bracket_close_round') {
01477                 $in_bracket = FALSE;
01478                 if ($seen_references) {
01479                     $seen_references = FALSE;
01480                 }
01481             }
01482 
01483             if (($arr[$i]['type'] == 'quote_backtick')) {
01484 
01485                 if ($seen_constraint) {
01486                     // remove backquotes
01487                     $identifier = str_replace('`','',$arr[$i]['data']);
01488                     $foreign[$foreign_key_number]['constraint'] = $identifier;
01489                 }
01490                 if ($seen_foreign && $in_bracket) {
01491                     // remove backquotes
01492                     $identifier = str_replace('`','',$arr[$i]['data']);
01493                     $foreign[$foreign_key_number]['index_list'][] = $identifier;
01494                 }
01495 
01496                 if ($seen_references) {
01497                     $identifier = str_replace('`','',$arr[$i]['data']);
01498                     if ($in_bracket) {
01499                         $foreign[$foreign_key_number]['ref_index_list'][] = $identifier;
01500                     } else {
01501                         // identifier can be table or db.table
01502                         $db_table = explode('.',$identifier);
01503                         if (isset($db_table[1])) {
01504                             $foreign[$foreign_key_number]['ref_db_name'] = $db_table[0];
01505                             $foreign[$foreign_key_number]['ref_table_name'] = $db_table[1];
01506                         } else {
01507                             $foreign[$foreign_key_number]['ref_table_name'] = $db_table[0];
01508                         }
01509                     }
01510                 }
01511             }
01512         } // end for $i (loop #3)
01513 
01514         if (isset($foreign)) {
01515             $subresult['foreign_keys'] = $foreign;
01516         }
01517         //DEBUG print_r($foreign);
01518 
01519         if (isset($select_expr_clause)) {
01520             $subresult['select_expr_clause'] = $select_expr_clause;
01521         }
01522         if (isset($from_clause)) {
01523             $subresult['from_clause'] = $from_clause;
01524         }
01525         if (isset($group_by_clause)) {
01526             $subresult['group_by_clause'] = $group_by_clause;
01527         }
01528         if (isset($order_by_clause)) {
01529             $subresult['order_by_clause'] = $order_by_clause;
01530         }
01531         if (isset($having_clause)) {
01532             $subresult['having_clause'] = $having_clause;
01533         }
01534         if (isset($where_clause)) {
01535             $subresult['where_clause'] = $where_clause;
01536         }
01537         if (isset($where_clause_identifiers)) {
01538             $subresult['where_clause_identifiers'] = $where_clause_identifiers;
01539         }
01540 
01541         if (isset($position_of_first_select)) {
01542             $subresult['position_of_first_select'] = $position_of_first_select;
01543         }
01544 
01545 
01546         // They are naughty and didn't have a trailing semi-colon,
01547         // then still handle it properly
01548         if ($subresult['querytype'] != '') {
01549             $result[] = $subresult;
01550         }
01551         return $result;
01552     } // end of the "PMA_SQP_analyze()" function
01553 
01554 
01564     function PMA_SQP_formatHtml_colorize($arr)
01565     {
01566         $i         = $GLOBALS['PMA_strpos']($arr['type'], '_');
01567         $class     = '';
01568         if ($i > 0) {
01569             $class = 'syntax_' . $GLOBALS['PMA_substr']($arr['type'], 0, $i) . ' ';
01570         }
01571 
01572         $class     .= 'syntax_' . $arr['type'];
01573 
01574         //TODO: check why adding a "\n" after the </span> would cause extra
01575         //      blanks to be displayed:
01576         //      SELECT p . person_name
01577 
01578         return '<span class="' . $class . '">' . htmlspecialchars($arr['data']) . '</span>';
01579     } // end of the "PMA_SQP_formatHtml_colorize()" function
01580 
01581 
01594     function PMA_SQP_formatHtml($arr, $mode='color', $start_token=0,
01595         $number_of_tokens=-1)
01596     {
01597         // first check for the SQL parser having hit an error
01598         if (PMA_SQP_isError()) {
01599             return $arr;
01600         }
01601         // then check for an array
01602         if (!is_array($arr)) {
01603             return $arr;
01604         }
01605         // else do it properly
01606         switch ($mode) {
01607             case 'color':
01608                 $str                                = '<span class="syntax">';
01609                 $html_line_break                    = '<br />';
01610                 break;
01611             case 'query_only':
01612                 $str                                = '';
01613                 $html_line_break                    = "\n";
01614                 break;
01615             case 'text':
01616                 $str                                = '';
01617                 $html_line_break                    = '<br />';
01618                 break;
01619         } // end switch
01620         $indent                                     = 0;
01621         $bracketlevel                               = 0;
01622         $functionlevel                              = 0;
01623         $infunction                                 = FALSE;
01624         $space_punct_listsep                        = ' ';
01625         $space_punct_listsep_function_name          = ' ';
01626         // $space_alpha_reserved_word = '<br />'."\n";
01627         $space_alpha_reserved_word                  = ' ';
01628 
01629         $keywords_with_brackets_1before            = array(
01630             'INDEX',
01631             'KEY',
01632             'ON',
01633             'USING'
01634         );
01635         $keywords_with_brackets_1before_cnt        = 4;
01636 
01637         $keywords_with_brackets_2before            = array(
01638             'IGNORE',
01639             'INDEX',
01640             'INTO',
01641             'KEY',
01642             'PRIMARY',
01643             'PROCEDURE',
01644             'REFERENCES',
01645             'UNIQUE',
01646             'USE'
01647         );
01648         // $keywords_with_brackets_2before_cnt = count($keywords_with_brackets_2before);
01649         $keywords_with_brackets_2before_cnt        = 9;
01650 
01651         // These reserved words do NOT get a newline placed near them.
01652         $keywords_no_newline               = array(
01653             'AND',
01654             'AS',
01655             'ASC',
01656             'DESC',
01657             'DISTINCT',
01658             'HOUR',
01659             'INTERVAL',
01660             'IS',
01661             'NOT',
01662             'NULL',
01663             'ON',
01664             'OR'
01665         );
01666         $keywords_no_newline_cnt           = 12;
01667 
01668         // These reserved words introduce a privilege list
01669         $keywords_priv_list                = array(
01670             'GRANT',
01671             'REVOKE'
01672         );
01673         $keywords_priv_list_cnt            = 2;
01674 
01675         if ($number_of_tokens == -1) {
01676             $arraysize = $arr['len'];
01677         } else {
01678             $arraysize = $number_of_tokens;
01679         }
01680         $typearr   = array();
01681         if ($arraysize >= 0) {
01682             $typearr[0] = '';
01683             $typearr[1] = '';
01684             $typearr[2] = '';
01685             //$typearr[3] = $arr[0]['type'];
01686             $typearr[3] = $arr[$start_token]['type'];
01687         }
01688 
01689         $in_priv_list = FALSE;
01690         for ($i = $start_token; $i < $arraysize; $i++) {
01691 // DEBUG echo "<b>" . $arr[$i]['data'] . "</b> " . $arr[$i]['type'] . "<br />";
01692             $before = '';
01693             $after  = '';
01694             $indent = 0;
01695             // array_shift($typearr);
01696             /*
01697             0 prev2
01698             1 prev
01699             2 current
01700             3 next
01701             */
01702             if (($i + 1) < $arraysize) {
01703                 // array_push($typearr, $arr[$i + 1]['type']);
01704                 $typearr[4] = $arr[$i + 1]['type'];
01705             } else {
01706                 //array_push($typearr, NULL);
01707                 $typearr[4] = '';
01708             }
01709 
01710             for ($j=0; $j<4; $j++) {
01711                 $typearr[$j] = $typearr[$j + 1];
01712             }
01713 
01714             switch ($typearr[2]) {
01715                 case 'white_newline':
01716 //                    $after      = '<br />';
01717                     $before     = '';
01718                     break;
01719                 case 'punct_bracket_open_round':
01720                     $bracketlevel++;
01721                     $infunction = FALSE;
01722                     // Make sure this array is sorted!
01723                     if (($typearr[1] == 'alpha_functionName') || ($typearr[1] == 'alpha_columnType') || ($typearr[1] == 'punct')
01724                         || ($typearr[3] == 'digit_integer') || ($typearr[3] == 'digit_hex') || ($typearr[3] == 'digit_float')
01725                         || (($typearr[0] == 'alpha_reservedWord')
01726                             && PMA_STR_binarySearchInArr(strtoupper($arr[$i - 2]['data']), $keywords_with_brackets_2before, $keywords_with_brackets_2before_cnt))
01727                         || (($typearr[1] == 'alpha_reservedWord')
01728                             && PMA_STR_binarySearchInArr(strtoupper($arr[$i - 1]['data']), $keywords_with_brackets_1before, $keywords_with_brackets_1before_cnt))
01729                         ) {
01730                         $functionlevel++;
01731                         $infunction = TRUE;
01732                         $after      .= ' ';
01733                     } else {
01734                         $indent++;
01735                         $after      .= ($mode != 'query_only' ? '<div class="syntax_indent' . $indent . '">' : ' ');
01736                     }
01737                     break;
01738                 case 'alpha_identifier':
01739                     if (($typearr[1] == 'punct_qualifier') || ($typearr[3] == 'punct_qualifier')) {
01740                         $after      = '';
01741                         $before     = '';
01742                     }
01743                     if (($typearr[3] == 'alpha_columnType') || ($typearr[3] == 'alpha_identifier')) {
01744                         $after      .= ' ';
01745                     }
01746                     break;
01747                 case 'punct_qualifier':
01748                     $before         = '';
01749                     $after          = '';
01750                     break;
01751                 case 'punct_listsep':
01752                     if ($infunction == TRUE) {
01753                         $after      .= $space_punct_listsep_function_name;
01754                     } else {
01755                         $after      .= $space_punct_listsep;
01756                     }
01757                     break;
01758                 case 'punct_queryend':
01759                     if (($typearr[3] != 'comment_mysql') && ($typearr[3] != 'comment_ansi') && $typearr[3] != 'comment_c') {
01760                         $after     .= $html_line_break;
01761                         $after     .= $html_line_break;
01762                     }
01763                     $space_punct_listsep               = ' ';
01764                     $space_punct_listsep_function_name = ' ';
01765                     $space_alpha_reserved_word         = ' ';
01766                     $in_priv_list                      = FALSE;
01767                     break;
01768                 case 'comment_mysql':
01769                 case 'comment_ansi':
01770                     $after         .= $html_line_break;
01771                     break;
01772                 case 'punct':
01773                     $before         .= ' ';
01774                     // workaround for
01775                     // select * from mytable limit 0,-1
01776                     // (a side effect of this workaround is that
01777                     // select 20 - 9
01778                     // becomes
01779                     // select 20 -9
01780                     // )
01781                     if ($typearr[3] != 'digit_integer') {
01782                        $after        .= ' ';
01783                     }
01784                     break;
01785                 case 'punct_bracket_close_round':
01786                     $bracketlevel--;
01787                     if ($infunction == TRUE) {
01788                         $functionlevel--;
01789                         $after     .= ' ';
01790                         $before    .= ' ';
01791                     } else {
01792                         $indent--;
01793                         $before    .= ($mode != 'query_only' ? '</div>' : ' ');
01794                     }
01795                     $infunction    = ($functionlevel > 0) ? TRUE : FALSE;
01796                     break;
01797                 case 'alpha_columnType':
01798                     if ($typearr[3] == 'alpha_columnAttrib') {
01799                         $after     .= ' ';
01800                     }
01801                     if ($typearr[1] == 'alpha_columnType') {
01802                         $before    .= ' ';
01803                     }
01804                     break;
01805                 case 'alpha_columnAttrib':
01806 
01807                     // ALTER TABLE tbl_name AUTO_INCREMENT = 1
01808                     if ($typearr[1] == 'alpha_identifier') {
01809                         $before .= ' ';
01810                     }
01811                     if (($typearr[3] == 'alpha_columnAttrib') || ($typearr[3] == 'quote_single') || ($typearr[3] == 'digit_integer')) {
01812                         $after     .= ' ';
01813                     }
01814                     // workaround for
01815                     // select * from mysql.user where binary user="root"
01816                     // binary is marked as alpha_columnAttrib
01817                     // but should be marked as a reserved word
01818                     if (strtoupper($arr[$i]['data']) == 'BINARY'
01819                       && $typearr[3] == 'alpha_identifier') {
01820                         $after     .= ' ';
01821                     }
01822                     break;
01823                 case 'alpha_reservedWord':
01824                     $arr[$i]['data'] = strtoupper($arr[$i]['data']);
01825                     if ((($typearr[1] != 'alpha_reservedWord')
01826                         || (($typearr[1] == 'alpha_reservedWord')
01827                             && PMA_STR_binarySearchInArr(strtoupper($arr[$i - 1]['data']), $keywords_no_newline, $keywords_no_newline_cnt)))
01828                         && ($typearr[1] != 'punct_level_plus')
01829                         && (!PMA_STR_binarySearchInArr($arr[$i]['data'], $keywords_no_newline, $keywords_no_newline_cnt))) {
01830                         // do not put a space before the first token, because
01831                         // we use a lot of eregi() checking for the first
01832                         // reserved word at beginning of query
01833                         // so do not put a newline before
01834                         //
01835                         // also we must not be inside a privilege list
01836                         if ($i > 0) {
01837                             if (!$in_priv_list) {
01838                                 $before    .= $space_alpha_reserved_word;
01839                             }
01840                         } else {
01841                         // on first keyword, check if it introduces a
01842                         // privilege list
01843                             if (PMA_STR_binarySearchInArr($arr[$i]['data'], $keywords_priv_list, $keywords_priv_list_cnt)) {
01844                                 $in_priv_list = TRUE;
01845                             }
01846                         }
01847                     } else {
01848                         $before    .= ' ';
01849                     }
01850 
01851                     switch ($arr[$i]['data']) {
01852                         case 'CREATE':
01853                             if (!$in_priv_list) {
01854                                 $space_punct_listsep       = $html_line_break;
01855                                 $space_alpha_reserved_word = ' ';
01856                             }
01857                             break;
01858                         case 'EXPLAIN':
01859                         case 'DESCRIBE':
01860                         case 'SET':
01861                         case 'ALTER':
01862                         case 'DELETE':
01863                         case 'SHOW':
01864                         case 'DROP':
01865                         case 'UPDATE':
01866                         case 'TRUNCATE':
01867                         case 'ANALYZE':
01868                         case 'ANALYSE':
01869                             if (!$in_priv_list) {
01870                                 $space_punct_listsep       = $html_line_break;
01871                                 $space_alpha_reserved_word = ' ';
01872                             }
01873                             break;
01874                         case 'INSERT':
01875                         case 'REPLACE':
01876                             if (!$in_priv_list) {
01877                                 $space_punct_listsep       = $html_line_break;
01878                                 $space_alpha_reserved_word = $html_line_break;
01879                             }
01880                             break;
01881                         case 'VALUES':
01882                             $space_punct_listsep       = ' ';
01883                             $space_alpha_reserved_word = $html_line_break;
01884                             break;
01885                         case 'SELECT':
01886                             $space_punct_listsep       = ' ';
01887                             $space_alpha_reserved_word = $html_line_break;
01888                             break;
01889                         default:
01890                             break;
01891                     } // end switch ($arr[$i]['data'])
01892 
01893                     $after         .= ' ';
01894                     break;
01895                 case 'digit_integer':
01896                 case 'digit_float':
01897                 case 'digit_hex':
01898                     //TODO: could there be other types preceding a digit?
01899                     if ($typearr[1] == 'alpha_reservedWord') {
01900                         $after .= ' ';
01901                     }
01902                     if ($infunction && $typearr[3] == 'punct_bracket_close_round') {
01903                         $after     .= ' ';
01904                     }
01905                     break;
01906                 case 'alpha_variable':
01907                     $after      = ' ';
01908                     break;
01909                 case 'quote_double':
01910                 case 'quote_single':
01911                     // workaround: for the query
01912                     // REVOKE SELECT ON `base2\_db`.* FROM 'user'@'%'
01913                     // the @ is incorrectly marked as alpha_variable
01914                     // in the parser, and here, the '%' gets a blank before,
01915                     // which is a syntax error
01916                     if ($typearr[1]!='alpha_variable') {
01917                         $before        .= ' ';
01918                     }
01919                     if ($infunction && $typearr[3] == 'punct_bracket_close_round') {
01920                         $after     .= ' ';
01921                     }
01922                     break;
01923                 case 'quote_backtick':
01924                     if ($typearr[3] != 'punct_qualifier') {
01925                         $after     .= ' ';
01926                     }
01927                     if ($typearr[1] != 'punct_qualifier') {
01928                         $before    .= ' ';
01929                     }
01930                     break;
01931                 default:
01932                     break;
01933             } // end switch ($typearr[2])
01934 
01935 /*
01936             if ($typearr[3] != 'punct_qualifier') {
01937                 $after             .= ' ';
01938             }
01939             $after                 .= "\n";
01940 */
01941             $str .= $before . ($mode=='color' ? PMA_SQP_formatHTML_colorize($arr[$i]) : $arr[$i]['data']). $after;
01942         } // end for
01943         if ($mode=='color') {
01944             $str .= '</span>';
01945         }
01946 
01947         return $str;
01948     } // end of the "PMA_SQP_formatHtml()" function
01949 }
01950 
01964 function PMA_SQP_buildCssRule($classname, $property, $value)
01965 {
01966     $str     = '.' . $classname . ' {';
01967     if ($value != '') {
01968         $str .= $property . ': ' . $value . ';';
01969     }
01970     $str     .= '}' . "\n";
01971 
01972     return $str;
01973 } // end of the "PMA_SQP_buildCssRule()" function
01974 
01975 
01987 function PMA_SQP_buildCssData()
01988 {
01989     global $cfg;
01990 
01991     $css_string     = '';
01992     foreach($cfg['SQP']['fmtColor'] AS $key => $col) {
01993         $css_string .= PMA_SQP_buildCssRule('syntax_' . $key, 'color', $col);
01994     }
01995 
01996     for ($i = 0; $i < 8; $i++) {
01997         $css_string .= PMA_SQP_buildCssRule('syntax_indent' . $i, 'margin-left', ($i * $cfg['SQP']['fmtInd']) . $cfg['SQP']['fmtIndUnit']);
01998     }
01999 
02000     return $css_string;
02001 } // end of the "PMA_SQP_buildCssData()" function
02002 
02003 if ($is_minimum_common == FALSE) {
02013     function PMA_SQP_formatNone($arr)
02014     {
02015         $formatted_sql = htmlspecialchars($arr['raw']);
02016         $formatted_sql = preg_replace("@((\015\012)|(\015)|(\012)){3,}@", "\n\n", $formatted_sql);
02017 
02018         return $formatted_sql;
02019     } // end of the "PMA_SQP_formatNone()" function
02020 
02021 
02031     function PMA_SQP_formatText($arr)
02032     {
02036          return PMA_SQP_formatNone($arr);
02037     } // end of the "PMA_SQP_formatText()" function
02038 } // end if: minimal common.lib needed?
02039 
02040 ?>


Généré par Les experts TYPO3 avec  doxygen 1.4.6