[Phpmyadmin-git] [SCM] phpMyAdmin branch, master, updated. RELEASE_3_3_6-9320-g4f48778

Michal Čihař nijel at users.sourceforge.net
Mon Aug 30 17:19:28 CEST 2010


The branch, master has been updated
       via  4f487780a07d2a89e97bb3249fd4389c7362681a (commit)
       via  68e1ff379806ab49b17855a66a9086b8f5714d69 (commit)
       via  8ce53e5bc81a8b798db7b4701d7afdad88c1406f (commit)
       via  c63d3dde811b9e0deaf7eb8599871e3d47b76126 (commit)
      from  fefd6a7def3433b7b9c52b0016044726015d43eb (commit)


- Log -----------------------------------------------------------------
commit 4f487780a07d2a89e97bb3249fd4389c7362681a
Author: Michal Čihař <mcihar at novell.com>
Date:   Mon Aug 30 17:17:07 2010 +0200

    bug #3042665 [parser] Add workaround for MySQL way of handling backtick.

commit 68e1ff379806ab49b17855a66a9086b8f5714d69
Author: Michal Čihař <mcihar at novell.com>
Date:   Mon Aug 30 17:16:44 2010 +0200

    Do not fail if parsing query has failed.

commit 8ce53e5bc81a8b798db7b4701d7afdad88c1406f
Author: Michal Čihař <mcihar at novell.com>
Date:   Mon Aug 30 17:03:55 2010 +0200

    Not used anywhere.

commit c63d3dde811b9e0deaf7eb8599871e3d47b76126
Author: Michal Čihař <mcihar at novell.com>
Date:   Mon Aug 30 16:59:53 2010 +0200

    Add more testcases.

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                    |    1 +
 libraries/import/sql.php     |   14 +++++-
 libraries/sqlparser.lib.php  |   39 +++++++++++++--
 test/PMA_SQL_parser_test.php |  104 +++++++++++++++++++++++++++++++++++++----
 4 files changed, 140 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3613acb..bdbba03 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 fe62ca5..0e61080 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 b8b2bba..7c8e8fa 100644
--- a/libraries/sqlparser.lib.php
+++ b/libraries/sqlparser.lib.php
@@ -211,7 +211,6 @@ if (! defined('PMA_MINIMUM_COMMON')) {
      */
     function PMA_SQP_parse($sql)
     {
-        global $cfg;
         global $PMA_SQPdata_column_attrib, $PMA_SQPdata_reserved_word, $PMA_SQPdata_column_type, $PMA_SQPdata_function_name,
                $PMA_SQPdata_column_attrib_cnt, $PMA_SQPdata_reserved_word_cnt, $PMA_SQPdata_column_type_cnt, $PMA_SQPdata_function_name_cnt;
         global $mysql_charsets, $mysql_collations_flat, $mysql_charsets_count, $mysql_collations_count;
@@ -342,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
@@ -806,7 +833,7 @@ if (! defined('PMA_MINIMUM_COMMON')) {
      */
     function PMA_SQP_analyze($arr)
     {
-        if ($arr == array()) {
+        if ($arr == array() || !isset($arr['len'])) {
             return array();
         }
         $result          = array();
diff --git a/test/PMA_SQL_parser_test.php b/test/PMA_SQL_parser_test.php
index 2774ba1..aa3299c 100644
--- a/test/PMA_SQL_parser_test.php
+++ b/test/PMA_SQL_parser_test.php
@@ -149,12 +149,13 @@ class PMA_SQL_parser_test extends PHPUnit_Framework_TestCase
     public function testParse_4()
     {
         $this->assertParser('SELECT * from `aaa;', array (
-          'raw' => 'SELECT * from `aaa;',
+          'raw' => 'SELECT * from `aaa`;',
           0 =>
           array (
-            'type' => 'alpha',
+            'type' => 'alpha_reservedWord',
             'data' => 'SELECT',
             'pos' => 6,
+            'forbidden' => true,
           ),
           1 =>
           array (
@@ -164,18 +165,99 @@ class PMA_SQL_parser_test extends PHPUnit_Framework_TestCase
           ),
           2 =>
           array (
-            'type' => 'alpha',
+            'type' => 'alpha_reservedWord',
             'data' => 'from',
             'pos' => 13,
+            'forbidden' => true,
           ),
-        ),
-'<p>There seems to be an error in your SQL query. The MySQL server error output below, if there is any, may also help you in diagnosing the problem</p>
-<pre>
-ERROR: Unclosed quote @ 14
-STR: `
-SQL: SELECT * from `aaa;
-</pre>
-');
+          3 =>
+          array (
+            'type' => 'quote_backtick',
+            'data' => '`aaa`',
+            'pos' => 0,
+          ),
+          4 =>
+          array (
+            'type' => 'punct_queryend',
+            'data' => ';',
+            'pos' => 0,
+          ),
+          'len' => 5,
+        ));
+    }
+
+    public function testParse_5()
+    {
+        $this->assertParser('SELECT * FROM `a_table` tbla INNER JOIN b_table` tblb ON tblb.id = tbla.id WHERE tblb.field1 != tbla.field1`;', array (
+          'raw' => 'SELECT * FROM `a_table` tbla INNER JOIN b_table` tblb ON tblb.id = tbla.id WHERE tblb.field1 != tbla.field1`;',
+          0 =>
+          array (
+            'type' => 'alpha_reservedWord',
+            'data' => 'SELECT',
+            'pos' => 6,
+            'forbidden' => true,
+          ),
+          1 =>
+          array (
+            'type' => 'punct',
+            'data' => '*',
+            'pos' => 0,
+          ),
+          2 =>
+          array (
+            'type' => 'alpha_reservedWord',
+            'data' => 'FROM',
+            'pos' => 13,
+            'forbidden' => true,
+          ),
+          3 =>
+          array (
+            'type' => 'quote_backtick',
+            'data' => '`a_table`',
+            'pos' => 0,
+          ),
+          4 =>
+          array (
+            'type' => 'alpha_identifier',
+            'data' => 'tbla',
+            'pos' => 28,
+            'forbidden' => false,
+          ),
+          5 =>
+          array (
+            'type' => 'alpha_reservedWord',
+            'data' => 'INNER',
+            'pos' => 34,
+            'forbidden' => true,
+          ),
+          6 =>
+          array (
+            'type' => 'alpha_reservedWord',
+            'data' => 'JOIN',
+            'pos' => 39,
+            'forbidden' => true,
+          ),
+          7 =>
+          array (
+            'type' => 'alpha_identifier',
+            'data' => 'b_table',
+            'pos' => 47,
+            'forbidden' => false,
+          ),
+          8 =>
+          array (
+            'type' => 'quote_backtick',
+            'data' => '` tblb ON tblb.id = tbla.id WHERE tblb.field1 != tbla.field1`',
+            'pos' => 0,
+          ),
+          9 =>
+          array (
+            'type' => 'punct_queryend',
+            'data' => ';',
+            'pos' => 0,
+          ),
+          'len' => 10,
+        ));
     }
 }
 ?>


hooks/post-receive
-- 
phpMyAdmin




More information about the Git mailing list