diff --git a/ChangeLog b/ChangeLog index 3613acbf0..bdbba0324 100644 --- a/ChangeLog +++ b/ChangeLog @@ -112,6 +112,7 @@ $Id$ + [interface] Added charts to status tab, profiling page and query results + [interface] AJAXification on various pages - [core] Remove last remaining parts of profiling code which was removed in 2006. +- bug #3042665 [parser] Add workaround for MySQL way of handling backtick. 3.3.7.0 (not yet released) - patch #3050492 [PDF scratchboard] Cannot drag table box to the edge after diff --git a/libraries/import/sql.php b/libraries/import/sql.php index fe62ca571..0e61080ca 100644 --- a/libraries/import/sql.php +++ b/libraries/import/sql.php @@ -168,8 +168,20 @@ while (!($GLOBALS['finished'] && $i >= $len) && !$error && !$timeout_passed) { while (!$endq) { // Find next quote $pos = strpos($buffer, $quote, $i + 1); + /* + * Behave same as MySQL and accept end of query as end of backtick. + * I know this is sick, but MySQL behaves like this: + * + * SELECT * FROM `table + * + * is treated like + * + * SELECT * FROM `table` + */ + if ($pos === FALSE && $quote == '`' && $found_delimiter) { + $pos = $first_sql_delimiter - 1; // No quote? Too short string - if ($pos === FALSE) { + } elseif ($pos === FALSE) { // We hit end of string => unclosed quote, but we handle it as end of query if ($GLOBALS['finished']) { $endq = TRUE; diff --git a/libraries/sqlparser.lib.php b/libraries/sqlparser.lib.php index 88c52d63d..7c8e8fae4 100644 --- a/libraries/sqlparser.lib.php +++ b/libraries/sqlparser.lib.php @@ -341,10 +341,38 @@ if (! defined('PMA_MINIMUM_COMMON')) { $pos = $GLOBALS['PMA_strpos'](' ' . $sql, $quotetype, $oldpos + 1) - 1; // ($pos === FALSE) if ($pos < 0) { - $debugstr = __('Unclosed quote') . ' @ ' . $startquotepos. "\n" - . 'STR: ' . htmlspecialchars($quotetype); - PMA_SQP_throwError($debugstr, $sql); - return $sql_array; + if ($c == '`') { + /* + * Behave same as MySQL and accept end of query as end of backtick. + * I know this is sick, but MySQL behaves like this: + * + * SELECT * FROM `table + * + * is treated like + * + * SELECT * FROM `table` + */ + $pos_quote_separator = $GLOBALS['PMA_strpos'](' ' . $sql, $GLOBALS['sql_delimiter'], $oldpos + 1) - 1; + if ($pos_quote_separator < 0) { + $len += 1; + $sql .= '`'; + $sql_array['raw'] .= '`'; + $pos = $len; + } else { + $len += 1; + $sql = $GLOBALS['PMA_substr']($sql, 0, $pos_quote_separator) . '`' . $GLOBALS['PMA_substr']($sql, $pos_quote_separator); + $sql_array['raw'] = $sql; + $pos = $pos_quote_separator; + } + if (class_exists('PMA_Message')) { + PMA_Message::warning(__('Automatically appended backtick to the end of query!'))->display(); + } + } else { + $debugstr = __('Unclosed quote') . ' @ ' . $startquotepos. "\n" + . 'STR: ' . htmlspecialchars($quotetype); + PMA_SQP_throwError($debugstr, $sql); + return $sql_array; + } } // If the quote is the first character, it can't be