diff --git a/ChangeLog b/ChangeLog index d97a1f67a9..15a1359c63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -47,6 +47,17 @@ phpMyAdmin - ChangeLog - issue #12511 Clarify documentation on ArbitraryServerRegexp - issue #12508 Remove duplicate code in SQL escaping - issue #12475 Cleanup code for getting table information +- issue #12579 phpMyAdmin's export of a Select statment without a FROM clause generates Wrong SQL +- issue #12316 Correct export of complex SELECT statements +- issue #12080 Fixed parsing of subselect queries +- issue #11740 Fixed handling DELETE ... USING queries +- issue #12100 Fixed handling of CASE operator +- issue #12455 Query history stores separate entry for every letter typed +- issue #12327 Create PHP code no longer works +- issue #12179 Fixed bookmarking of query with multiple statements +- issue #12419 Wrong description on GRANT OPTION +- issue #12615 Fixed regexp for matching browser versions +- issue #12569 Avoid showing import errors twice 4.6.4 (2016-08-16) - issue [security] Weaknesses with cookie encryption, see PMASA-2016-29 diff --git a/doc/config.rst b/doc/config.rst index 9ea10df8f4..36c1b974d9 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -1558,7 +1558,7 @@ Cookie authentication options $cfg['ArbitraryServerRegexp'] = '/^(server|another|yetdifferent)$/'; // Allow connection to range of IP addresses: - $cfg['ArbitraryServerRegexp'] = '@^192.168.0.[0-9]{1,}$@'; + $cfg['ArbitraryServerRegexp'] = '@^192\.168\.0\.[0-9]{1,}$@'; // Allow connection to server name ending with -mysql: $cfg['ArbitraryServerRegexp'] = '@^[^:]\-mysql$@'; diff --git a/import.php b/import.php index 231c03feaf..2b269e0dcf 100644 --- a/import.php +++ b/import.php @@ -199,7 +199,10 @@ if ($_POST == array() && $_GET == array()) { $_SESSION['Import_message']['message'] = $message->getDisplay(); $_SESSION['Import_message']['go_back_url'] = $GLOBALS['goto']; - $message->display(); + $response = PMA\libraries\Response::getInstance(); + $response->setRequestStatus(false); + $response->addJSON('message', $message); + exit; // the footer is displayed automatically } @@ -785,6 +788,7 @@ if ($go_sql) { } $html_output = ''; + foreach ($sql_queries as $sql_query) { // parse sql query @@ -820,7 +824,7 @@ if ($go_sql) { $db, // db $table, // table null, // find_real_end - $_REQUEST['sql_query'], // sql_query_for_bookmark + null, // sql_query_for_bookmark - see below null, // extra_data null, // message_to_show null, // message @@ -836,6 +840,18 @@ if ($go_sql) { ); } + // sql_query_for_bookmark is not included in PMA_executeQueryAndGetQueryResponse + // since only one bookmark has to be added for all the queries submitted through + // the SQL tab + if (! empty($_POST['bkm_label']) && ! empty($import_text)) { + $cfgBookmark = PMA_Bookmark_getParams(); + PMA_storeTheQueryAsBookmark( + $db, $cfgBookmark['user'], + $_REQUEST['sql_query'], $_POST['bkm_label'], + isset($_POST['bkm_replace']) ? $_POST['bkm_replace'] : null + ); + } + $response = PMA\libraries\Response::getInstance(); $response->addJSON('ajax_reload', $ajax_reload); $response->addHTML($html_output); diff --git a/js/codemirror/addon/lint/sql-lint.js b/js/codemirror/addon/lint/sql-lint.js index 92b30f2702..0afa9c49cf 100644 --- a/js/codemirror/addon/lint/sql-lint.js +++ b/js/codemirror/addon/lint/sql-lint.js @@ -33,6 +33,7 @@ CodeMirror.sqlLint = function(text, updateLinting, options, cm) { token: PMA_commonParams.get('token'), server: PMA_commonParams.get('server'), options: options.lintOptions, + no_history: true, }, success: handleResponse }); diff --git a/libraries/Config.php b/libraries/Config.php index 6fcc9c5817..b3dce0e5e7 100644 --- a/libraries/Config.php +++ b/libraries/Config.php @@ -193,20 +193,20 @@ class Config // (must check everything else before Mozilla) $is_mozilla = preg_match( - '@Mozilla/([0-9].[0-9]{1,2})@', + '@Mozilla/([0-9]\.[0-9]{1,2})@', $HTTP_USER_AGENT, $mozilla_version ); if (preg_match( - '@Opera(/| )([0-9].[0-9]{1,2})@', + '@Opera(/| )([0-9]\.[0-9]{1,2})@', $HTTP_USER_AGENT, $log_version )) { $this->set('PMA_USR_BROWSER_VER', $log_version[2]); $this->set('PMA_USR_BROWSER_AGENT', 'OPERA'); } elseif (preg_match( - '@(MS)?IE ([0-9]{1,2}.[0-9]{1,2})@', + '@(MS)?IE ([0-9]{1,2}\.[0-9]{1,2})@', $HTTP_USER_AGENT, $log_version )) { @@ -220,7 +220,7 @@ class Config $this->set('PMA_USR_BROWSER_VER', intval($log_version[1]) + 4); $this->set('PMA_USR_BROWSER_AGENT', 'IE'); } elseif (preg_match( - '@OmniWeb/([0-9].[0-9]{1,2})@', + '@OmniWeb/([0-9]{1,3})@', $HTTP_USER_AGENT, $log_version )) { @@ -265,7 +265,7 @@ class Config 'PMA_USR_BROWSER_VER', $log_version[1] ); $this->set('PMA_USR_BROWSER_AGENT', 'FIREFOX'); - } elseif (preg_match('@rv:1.9(.*)Gecko@', $HTTP_USER_AGENT)) { + } elseif (preg_match('@rv:1\.9(.*)Gecko@', $HTTP_USER_AGENT)) { $this->set('PMA_USR_BROWSER_VER', '1.9'); $this->set('PMA_USR_BROWSER_AGENT', 'GECKO'); } elseif ($is_mozilla) { diff --git a/libraries/Util.php b/libraries/Util.php index 91b144765e..27d83f2276 100644 --- a/libraries/Util.php +++ b/libraries/Util.php @@ -1164,6 +1164,8 @@ class Util if (! empty($GLOBALS['show_as_php'])) { $query_base = '$sql = \'' . $query_base; + $query_base = '
' . "\n"
+                    . $query_base;
             } elseif (isset($query_base)) {
                 $query_base = self::formatSql($query_base);
             }
@@ -1234,7 +1236,9 @@ class Util
 
             // even if the query is big and was truncated, offer the chance
             // to edit it (unless it's enormous, see linkOrButton() )
-            if (! empty($cfg['SQLQuery']['Edit'])) {
+            if (! empty($cfg['SQLQuery']['Edit'])
+                && empty($GLOBALS['show_as_php'])
+            ) {
                 $edit_link .= PMA_URL_getCommon($url_params) . '#querybox';
                 $edit_link = ' ['
                     . self::linkOrButton($edit_link, __('Edit'))
@@ -1307,7 +1311,8 @@ class Util
 
             //Clean up the end of the PHP
             if (! empty($GLOBALS['show_as_php'])) {
-                $retval .= '\';';
+                $retval .= '\';' . "\n"
+                    . '
'; } $retval .= ''; @@ -1333,7 +1338,10 @@ class Util /** * TODO: Should we have $cfg['SQLQuery']['InlineEdit']? */ - if (! empty($cfg['SQLQuery']['Edit']) && ! $query_too_big) { + if (! empty($cfg['SQLQuery']['Edit']) + && ! $query_too_big + && empty($GLOBALS['show_as_php']) + ) { $inline_edit_link = ' [' . self::linkOrButton( '#', diff --git a/libraries/server_privileges.lib.php b/libraries/server_privileges.lib.php index 932d7a3d13..0d59e80724 100644 --- a/libraries/server_privileges.lib.php +++ b/libraries/server_privileges.lib.php @@ -1032,8 +1032,8 @@ function PMA_getTriggerPrivilegeTable() 'Grant', 'GRANT', __( - 'Allows adding users and privileges ' - . 'without reloading the privilege tables.' + 'Allows user to give to other users or remove from other users ' + . 'privileges that user possess on this routine.' ) ), array( @@ -1402,16 +1402,16 @@ function PMA_getStructurePrivilegeTable($table, $row) */ function PMA_getAdministrationPrivilegeTable($db) { - $adminPrivTable = array( - array('Grant', - 'GRANT', - __( - 'Allows adding users and privileges ' - . 'without reloading the privilege tables.' - ) - ), - ); if ($db == '*') { + $adminPrivTable = array( + array('Grant', + 'GRANT', + __( + 'Allows adding users and privileges ' + . 'without reloading the privilege tables.' + ) + ), + ); $adminPrivTable[] = array('Super', 'SUPER', __( @@ -1438,6 +1438,17 @@ function PMA_getAdministrationPrivilegeTable($db) __('Gives access to the complete list of databases.') ); } + else { + $adminPrivTable = array( + array('Grant', + 'GRANT', + __( + 'Allows user to give to other users or remove from other' + . ' users the privileges that user possess yourself.' + ) + ), + ); + } $adminPrivTable[] = array('Lock_tables', 'LOCK TABLES', __('Allows locking tables for the current thread.') @@ -5153,7 +5164,9 @@ function PMA_addUserAndCreateDatabase($_error, $real_sql_query, $sql_query, // Grant all privileges on wildcard name (username\_%) $q = 'GRANT ALL PRIVILEGES ON ' . Util::backquote( - Util::sqlAddSlashes($username) . '\_%' + Util::escapeMysqlWildcards( + Util::sqlAddSlashes($username) + ) . '\_%' ) . '.* TO \'' . Util::sqlAddSlashes($username) . '\'@\'' . Util::sqlAddSlashes($hostname) . '\';'; diff --git a/libraries/sql-parser/src/Component.php b/libraries/sql-parser/src/Component.php index 2e406c5c7b..08720cfa14 100644 --- a/libraries/sql-parser/src/Component.php +++ b/libraries/sql-parser/src/Component.php @@ -20,8 +20,7 @@ require_once 'common.php'; * * @category Components * @package SqlParser - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ abstract class Component { diff --git a/libraries/sql-parser/src/Components/AlterOperation.php b/libraries/sql-parser/src/Components/AlterOperation.php index 3481e985df..c2344c607f 100644 --- a/libraries/sql-parser/src/Components/AlterOperation.php +++ b/libraries/sql-parser/src/Components/AlterOperation.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Components * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class AlterOperation extends Component { diff --git a/libraries/sql-parser/src/Components/Array2d.php b/libraries/sql-parser/src/Components/Array2d.php index a46813b081..2199efe1d4 100644 --- a/libraries/sql-parser/src/Components/Array2d.php +++ b/libraries/sql-parser/src/Components/Array2d.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Array2d extends Component { diff --git a/libraries/sql-parser/src/Components/ArrayObj.php b/libraries/sql-parser/src/Components/ArrayObj.php index 627f8c750e..bed7fc7391 100644 --- a/libraries/sql-parser/src/Components/ArrayObj.php +++ b/libraries/sql-parser/src/Components/ArrayObj.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Components * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ArrayObj extends Component { diff --git a/libraries/sql-parser/src/Components/CaseExpression.php b/libraries/sql-parser/src/Components/CaseExpression.php new file mode 100644 index 0000000000..df5a1bd381 --- /dev/null +++ b/libraries/sql-parser/src/Components/CaseExpression.php @@ -0,0 +1,249 @@ +idx; // Skip 'CASE' + + for (; $list->idx < $list->count; ++$list->idx) { + + /** + * Token parsed at this moment. + * + * @var Token $token + */ + $token = $list->tokens[$list->idx]; + + // Skipping whitespaces and comments. + if (($token->type === Token::TYPE_WHITESPACE) + || ($token->type === Token::TYPE_COMMENT) + ) { + continue; + } + + if ($state === 0) { + if ($token->type === Token::TYPE_KEYWORD + && $token->value === 'WHEN' + ) { + ++$list->idx; // Skip 'WHEN' + $new_condition = Condition::parse($parser, $list); + $type = 1; + $state = 1; + $ret->conditions[] = $new_condition; + } elseif ($token->type === Token::TYPE_KEYWORD + && $token->value === 'ELSE' + ) { + ++$list->idx; // Skip 'ELSE' + $ret->else_result = Expression::parse($parser, $list); + $state = 0; // last clause of CASE expression + } elseif ($token->type === Token::TYPE_KEYWORD + && ($token->value === 'END' + || $token->value === 'end') + ) { + $state = 3; // end of CASE expression + ++$list->idx; + break; + } elseif ($token->type === Token::TYPE_KEYWORD) { + $parser->error(__('Unexpected keyword.'), $token); + break; + } else { + $ret->value = Expression::parse($parser, $list); + $type = 0; + $state = 1; + } + } elseif ($state === 1) { + if ($type === 0) { + if ($token->type === Token::TYPE_KEYWORD + && $token->value === 'WHEN' + ) { + ++$list->idx; // Skip 'WHEN' + $new_value = Expression::parse($parser, $list); + $state = 2; + $ret->compare_values[] = $new_value; + } elseif ($token->type === Token::TYPE_KEYWORD + && $token->value === 'ELSE' + ) { + ++$list->idx; // Skip 'ELSE' + $ret->else_result = Expression::parse($parser, $list); + $state = 0; // last clause of CASE expression + } elseif ($token->type === Token::TYPE_KEYWORD + && ($token->value === 'END' + || $token->value === 'end') + ) { + $state = 3; // end of CASE expression + ++$list->idx; + break; + } elseif ($token->type === Token::TYPE_KEYWORD) { + $parser->error(__('Unexpected keyword.'), $token); + break; + } + } else { + if ($token->type === Token::TYPE_KEYWORD + && $token->value === 'THEN' + ) { + ++$list->idx; // Skip 'THEN' + $new_result = Expression::parse($parser, $list); + $state = 0; + $ret->results[] = $new_result; + } elseif ($token->type === Token::TYPE_KEYWORD) { + $parser->error(__('Unexpected keyword.'), $token); + break; + } + } + } elseif ($state === 2) { + if ($type === 0) { + if ($token->type === Token::TYPE_KEYWORD + && $token->value === 'THEN' + ) { + ++$list->idx; // Skip 'THEN' + $new_result = Expression::parse($parser, $list); + $ret->results[] = $new_result; + $state = 1; + } elseif ($token->type === Token::TYPE_KEYWORD) { + $parser->error(__('Unexpected keyword.'), $token); + break; + } + } + } + } + + if ($state !== 3) { + $parser->error( + __('Unexpected end of CASE expression'), + $list->tokens[$list->idx - 1] + ); + } + + --$list->idx; + return $ret; + } + + /** + * @param Expression $component The component to be built. + * @param array $options Parameters for building. + * + * @return string + */ + public static function build($component, array $options = array()) + { + $ret = 'CASE '; + if (isset($component->value)) { + // Syntax type 0 + $ret .= $component->value . ' '; + for ( + $i = 0; + $i < count($component->compare_values) && $i < count($component->results); + ++$i + ) { + $ret .= 'WHEN ' . $component->compare_values[$i] . ' '; + $ret .= 'THEN ' . $component->results[$i] . ' '; + } + } else { + // Syntax type 1 + for ( + $i = 0; + $i < count($component->conditions) && $i < count($component->results); + ++$i + ) { + $ret .= 'WHEN ' . Condition::build($component->conditions[$i]) . ' '; + $ret .= 'THEN ' . $component->results[$i] . ' '; + } + } + if (isset($component->else_result)) { + $ret .= 'ELSE ' . $component->else_result . ' '; + } + $ret .= 'END'; + + return $ret; + } +} diff --git a/libraries/sql-parser/src/Components/Condition.php b/libraries/sql-parser/src/Components/Condition.php index cb1a5f8af5..c69441aa35 100644 --- a/libraries/sql-parser/src/Components/Condition.php +++ b/libraries/sql-parser/src/Components/Condition.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Condition extends Component { diff --git a/libraries/sql-parser/src/Components/CreateDefinition.php b/libraries/sql-parser/src/Components/CreateDefinition.php index 6e302d08d1..0ef8a31160 100644 --- a/libraries/sql-parser/src/Components/CreateDefinition.php +++ b/libraries/sql-parser/src/Components/CreateDefinition.php @@ -24,8 +24,7 @@ use SqlParser\TokensList; * @category Components * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class CreateDefinition extends Component { diff --git a/libraries/sql-parser/src/Components/DataType.php b/libraries/sql-parser/src/Components/DataType.php index aac40ee3fa..378ec9d88e 100644 --- a/libraries/sql-parser/src/Components/DataType.php +++ b/libraries/sql-parser/src/Components/DataType.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Components * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class DataType extends Component { diff --git a/libraries/sql-parser/src/Components/Expression.php b/libraries/sql-parser/src/Components/Expression.php index 592207bf24..1ca05968c8 100644 --- a/libraries/sql-parser/src/Components/Expression.php +++ b/libraries/sql-parser/src/Components/Expression.php @@ -22,8 +22,7 @@ use SqlParser\TokensList; * @category Components * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Expression extends Component { diff --git a/libraries/sql-parser/src/Components/ExpressionArray.php b/libraries/sql-parser/src/Components/ExpressionArray.php index f108ad8002..e2aa86eb1a 100644 --- a/libraries/sql-parser/src/Components/ExpressionArray.php +++ b/libraries/sql-parser/src/Components/ExpressionArray.php @@ -1,7 +1,7 @@ - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ExpressionArray extends Component { @@ -73,13 +72,21 @@ class ExpressionArray extends Component && ((~$token->flags & Token::FLAG_KEYWORD_FUNCTION)) && ($token->value !== 'DUAL') && ($token->value !== 'NULL') + && ($token->value !== 'CASE') ) { // No keyword is expected. break; } if ($state === 0) { - $expr = Expression::parse($parser, $list, $options); + if ($token->type === Token::TYPE_KEYWORD + && $token->value === 'CASE' + ) { + $expr = CaseExpression::parse($parser, $list, $options); + } else { + $expr = Expression::parse($parser, $list, $options); + } + if ($expr === null) { break; } diff --git a/libraries/sql-parser/src/Components/FunctionCall.php b/libraries/sql-parser/src/Components/FunctionCall.php index 9d2dfed5d8..e260532bb8 100644 --- a/libraries/sql-parser/src/Components/FunctionCall.php +++ b/libraries/sql-parser/src/Components/FunctionCall.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class FunctionCall extends Component { diff --git a/libraries/sql-parser/src/Components/IntoKeyword.php b/libraries/sql-parser/src/Components/IntoKeyword.php index 783ac3cdb3..d90963db76 100644 --- a/libraries/sql-parser/src/Components/IntoKeyword.php +++ b/libraries/sql-parser/src/Components/IntoKeyword.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class IntoKeyword extends Component { @@ -46,6 +45,13 @@ class IntoKeyword extends Component */ public $columns; + /** + * The values to be selected into (SELECT .. INTO @var1) + * + * @var ExpressionArray + */ + public $values; + /** * @param Parser $parser The parser that serves as context. * @param TokensList $list The list of tokens that are being parsed. @@ -103,14 +109,22 @@ class IntoKeyword extends Component } if ($state === 0) { - $ret->dest = Expression::parse( - $parser, - $list, - array( - 'parseField' => 'table', - 'breakOnAlias' => true, - ) - ); + if ((isset($options['fromInsert']) + && $options['fromInsert']) + || (isset($options['fromReplace']) + && $options['fromReplace']) + ) { + $ret->dest = Expression::parse( + $parser, + $list, + array( + 'parseField' => 'table', + 'breakOnAlias' => true, + ) + ); + } else { + $ret->values = ExpressionArray::parse($parser, $list); + } $state = 1; } elseif ($state === 1) { if (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) { @@ -141,8 +155,10 @@ class IntoKeyword extends Component $columns = !empty($component->columns) ? '(`' . implode('`, `', $component->columns) . '`)' : ''; return $component->dest . $columns; + } elseif (isset($component->values)) { + return ExpressionArray::build($component->values); } else { return 'OUTFILE "' . $component->dest . '"'; } } -} +} \ No newline at end of file diff --git a/libraries/sql-parser/src/Components/JoinKeyword.php b/libraries/sql-parser/src/Components/JoinKeyword.php index e7f62a6ff8..7062783c30 100644 --- a/libraries/sql-parser/src/Components/JoinKeyword.php +++ b/libraries/sql-parser/src/Components/JoinKeyword.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class JoinKeyword extends Component { @@ -147,6 +146,9 @@ class JoinKeyword extends Component $state = 3; } elseif ($token->value === 'USING') { $state = 4; + } else { + /* Next clause is starting */ + break; } } } elseif ($state === 3) { @@ -183,8 +185,9 @@ class JoinKeyword extends Component foreach ($component as $c) { $ret[] = array_search($c->type, static::$JOINS) . ' ' . $c->expr . (!empty($c->on) - ? ' ON ' . Condition::build($c->on) - : ' USING ' . ArrayObj::build($c->using)); + ? ' ON ' . Condition::build($c->on) : '') + . (!empty($c->using) + ? ' USING ' . ArrayObj::build($c->using) : ''); } return implode(' ', $ret); } diff --git a/libraries/sql-parser/src/Components/Key.php b/libraries/sql-parser/src/Components/Key.php index ef066dd179..24cc363290 100644 --- a/libraries/sql-parser/src/Components/Key.php +++ b/libraries/sql-parser/src/Components/Key.php @@ -22,8 +22,7 @@ use SqlParser\TokensList; * @category Components * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Key extends Component { diff --git a/libraries/sql-parser/src/Components/Limit.php b/libraries/sql-parser/src/Components/Limit.php index 30881dcbef..13a11277fb 100644 --- a/libraries/sql-parser/src/Components/Limit.php +++ b/libraries/sql-parser/src/Components/Limit.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Limit extends Component { @@ -127,10 +126,6 @@ class Limit extends Component */ public static function build($component, array $options = array()) { - if (empty($component->offset)) { - return (string) $component->rowCount; - } else { - return $component->offset . ', ' . $component->rowCount; - } + return $component->offset . ', ' . $component->rowCount; } } diff --git a/libraries/sql-parser/src/Components/OptionsArray.php b/libraries/sql-parser/src/Components/OptionsArray.php index 684e5cc12d..0c80e0d742 100644 --- a/libraries/sql-parser/src/Components/OptionsArray.php +++ b/libraries/sql-parser/src/Components/OptionsArray.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Components * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class OptionsArray extends Component { diff --git a/libraries/sql-parser/src/Components/OrderKeyword.php b/libraries/sql-parser/src/Components/OrderKeyword.php index 7d23013836..ba773a8496 100644 --- a/libraries/sql-parser/src/Components/OrderKeyword.php +++ b/libraries/sql-parser/src/Components/OrderKeyword.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class OrderKeyword extends Component { diff --git a/libraries/sql-parser/src/Components/ParameterDefinition.php b/libraries/sql-parser/src/Components/ParameterDefinition.php index aea8f9c199..274555e938 100644 --- a/libraries/sql-parser/src/Components/ParameterDefinition.php +++ b/libraries/sql-parser/src/Components/ParameterDefinition.php @@ -20,8 +20,7 @@ use SqlParser\TokensList; * @category Components * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ParameterDefinition extends Component { diff --git a/libraries/sql-parser/src/Components/PartitionDefinition.php b/libraries/sql-parser/src/Components/PartitionDefinition.php index 85342d7050..33c369287a 100644 --- a/libraries/sql-parser/src/Components/PartitionDefinition.php +++ b/libraries/sql-parser/src/Components/PartitionDefinition.php @@ -23,8 +23,7 @@ use SqlParser\TokensList; * @category Components * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class PartitionDefinition extends Component { diff --git a/libraries/sql-parser/src/Components/Reference.php b/libraries/sql-parser/src/Components/Reference.php index 7acd92e042..24d633ca90 100644 --- a/libraries/sql-parser/src/Components/Reference.php +++ b/libraries/sql-parser/src/Components/Reference.php @@ -20,8 +20,7 @@ use SqlParser\TokensList; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Reference extends Component { diff --git a/libraries/sql-parser/src/Components/RenameOperation.php b/libraries/sql-parser/src/Components/RenameOperation.php index c0ecf6c01b..291bd43011 100644 --- a/libraries/sql-parser/src/Components/RenameOperation.php +++ b/libraries/sql-parser/src/Components/RenameOperation.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class RenameOperation extends Component { diff --git a/libraries/sql-parser/src/Components/SetOperation.php b/libraries/sql-parser/src/Components/SetOperation.php index ffe754aef5..0a1a54ca9a 100644 --- a/libraries/sql-parser/src/Components/SetOperation.php +++ b/libraries/sql-parser/src/Components/SetOperation.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class SetOperation extends Component { diff --git a/libraries/sql-parser/src/Components/UnionKeyword.php b/libraries/sql-parser/src/Components/UnionKeyword.php index 6286cd0542..138a79e51a 100644 --- a/libraries/sql-parser/src/Components/UnionKeyword.php +++ b/libraries/sql-parser/src/Components/UnionKeyword.php @@ -17,8 +17,7 @@ use SqlParser\Statements\SelectStatement; * @category Keywords * @package SqlParser * @subpackage Components - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class UnionKeyword extends Component { diff --git a/libraries/sql-parser/src/Context.php b/libraries/sql-parser/src/Context.php index a62fa16b9e..0bdc6960db 100644 --- a/libraries/sql-parser/src/Context.php +++ b/libraries/sql-parser/src/Context.php @@ -15,8 +15,7 @@ namespace SqlParser; * * @category Contexts * @package SqlParser - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ abstract class Context { diff --git a/libraries/sql-parser/src/Contexts/ContextMySql50000.php b/libraries/sql-parser/src/Contexts/ContextMySql50000.php index d9a254479b..4931faa1ff 100644 --- a/libraries/sql-parser/src/Contexts/ContextMySql50000.php +++ b/libraries/sql-parser/src/Contexts/ContextMySql50000.php @@ -19,8 +19,7 @@ use SqlParser\Context; * @category Contexts * @package SqlParser * @subpackage Contexts - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ContextMySql50000 extends Context { diff --git a/libraries/sql-parser/src/Contexts/ContextMySql50100.php b/libraries/sql-parser/src/Contexts/ContextMySql50100.php index ffa8ad8cc9..a547e6405d 100644 --- a/libraries/sql-parser/src/Contexts/ContextMySql50100.php +++ b/libraries/sql-parser/src/Contexts/ContextMySql50100.php @@ -19,8 +19,7 @@ use SqlParser\Context; * @category Contexts * @package SqlParser * @subpackage Contexts - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ContextMySql50100 extends Context { diff --git a/libraries/sql-parser/src/Contexts/ContextMySql50500.php b/libraries/sql-parser/src/Contexts/ContextMySql50500.php index ed64233200..a15744a8b0 100644 --- a/libraries/sql-parser/src/Contexts/ContextMySql50500.php +++ b/libraries/sql-parser/src/Contexts/ContextMySql50500.php @@ -19,8 +19,7 @@ use SqlParser\Context; * @category Contexts * @package SqlParser * @subpackage Contexts - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ContextMySql50500 extends Context { diff --git a/libraries/sql-parser/src/Contexts/ContextMySql50600.php b/libraries/sql-parser/src/Contexts/ContextMySql50600.php index 4a2c132528..7a0cf56234 100644 --- a/libraries/sql-parser/src/Contexts/ContextMySql50600.php +++ b/libraries/sql-parser/src/Contexts/ContextMySql50600.php @@ -19,8 +19,7 @@ use SqlParser\Context; * @category Contexts * @package SqlParser * @subpackage Contexts - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ContextMySql50600 extends Context { diff --git a/libraries/sql-parser/src/Contexts/ContextMySql50700.php b/libraries/sql-parser/src/Contexts/ContextMySql50700.php index 1b6eb9c18c..8682032dc3 100644 --- a/libraries/sql-parser/src/Contexts/ContextMySql50700.php +++ b/libraries/sql-parser/src/Contexts/ContextMySql50700.php @@ -19,8 +19,7 @@ use SqlParser\Context; * @category Contexts * @package SqlParser * @subpackage Contexts - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ContextMySql50700 extends Context { diff --git a/libraries/sql-parser/src/Exceptions/LexerException.php b/libraries/sql-parser/src/Exceptions/LexerException.php index 3bbc0c72cd..2dd30412e6 100644 --- a/libraries/sql-parser/src/Exceptions/LexerException.php +++ b/libraries/sql-parser/src/Exceptions/LexerException.php @@ -14,8 +14,7 @@ namespace SqlParser\Exceptions; * @category Exceptions * @package SqlParser * @subpackage Exceptions - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class LexerException extends \Exception { diff --git a/libraries/sql-parser/src/Exceptions/ParserException.php b/libraries/sql-parser/src/Exceptions/ParserException.php index 5a9fac0442..81f6259304 100644 --- a/libraries/sql-parser/src/Exceptions/ParserException.php +++ b/libraries/sql-parser/src/Exceptions/ParserException.php @@ -16,8 +16,7 @@ use SqlParser\Token; * @category Exceptions * @package SqlParser * @subpackage Exceptions - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ParserException extends \Exception { diff --git a/libraries/sql-parser/src/Lexer.php b/libraries/sql-parser/src/Lexer.php index 8c609db08f..7fb2356d76 100644 --- a/libraries/sql-parser/src/Lexer.php +++ b/libraries/sql-parser/src/Lexer.php @@ -38,8 +38,7 @@ if (!defined('USE_UTF_STRINGS')) { * * @category Lexer * @package SqlParser - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ * @see Context */ class Lexer diff --git a/libraries/sql-parser/src/Parser.php b/libraries/sql-parser/src/Parser.php index e37b36374b..21e1b395f9 100644 --- a/libraries/sql-parser/src/Parser.php +++ b/libraries/sql-parser/src/Parser.php @@ -21,8 +21,7 @@ use SqlParser\Statements\TransactionStatement; * * @category Parser * @package SqlParser - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Parser { @@ -163,7 +162,7 @@ class Parser 'FROM' => array( 'class' => 'SqlParser\\Components\\ExpressionArray', 'field' => 'from', - 'options' => array('parseField' => 'table'), + 'options' => array('field' => 'table'), ), 'GROUP BY' => array( 'class' => 'SqlParser\\Components\\OrderKeyword', diff --git a/libraries/sql-parser/src/Statement.php b/libraries/sql-parser/src/Statement.php index 9f3341ea25..c23db67bb5 100644 --- a/libraries/sql-parser/src/Statement.php +++ b/libraries/sql-parser/src/Statement.php @@ -17,8 +17,7 @@ use SqlParser\Components\OptionsArray; * * @category Statements * @package SqlParser - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ abstract class Statement { diff --git a/libraries/sql-parser/src/Statements/AlterStatement.php b/libraries/sql-parser/src/Statements/AlterStatement.php index e76599958d..abad5dadb1 100644 --- a/libraries/sql-parser/src/Statements/AlterStatement.php +++ b/libraries/sql-parser/src/Statements/AlterStatement.php @@ -22,8 +22,7 @@ use SqlParser\Components\OptionsArray; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class AlterStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/AnalyzeStatement.php b/libraries/sql-parser/src/Statements/AnalyzeStatement.php index b6ae99e8c0..f7e8f816e5 100644 --- a/libraries/sql-parser/src/Statements/AnalyzeStatement.php +++ b/libraries/sql-parser/src/Statements/AnalyzeStatement.php @@ -20,8 +20,7 @@ use SqlParser\Components\Expression; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class AnalyzeStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/BackupStatement.php b/libraries/sql-parser/src/Statements/BackupStatement.php index 5a58a2acb4..df759398f9 100644 --- a/libraries/sql-parser/src/Statements/BackupStatement.php +++ b/libraries/sql-parser/src/Statements/BackupStatement.php @@ -16,8 +16,7 @@ namespace SqlParser\Statements; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class BackupStatement extends MaintenanceStatement { diff --git a/libraries/sql-parser/src/Statements/CallStatement.php b/libraries/sql-parser/src/Statements/CallStatement.php index bac73ee530..42a21d753a 100644 --- a/libraries/sql-parser/src/Statements/CallStatement.php +++ b/libraries/sql-parser/src/Statements/CallStatement.php @@ -23,8 +23,7 @@ use SqlParser\Components\FunctionCall; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class CallStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/CheckStatement.php b/libraries/sql-parser/src/Statements/CheckStatement.php index 8ffa9460f5..ef99ed3154 100644 --- a/libraries/sql-parser/src/Statements/CheckStatement.php +++ b/libraries/sql-parser/src/Statements/CheckStatement.php @@ -16,8 +16,7 @@ namespace SqlParser\Statements; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class CheckStatement extends MaintenanceStatement { diff --git a/libraries/sql-parser/src/Statements/ChecksumStatement.php b/libraries/sql-parser/src/Statements/ChecksumStatement.php index 7c66bed786..8b623353bc 100644 --- a/libraries/sql-parser/src/Statements/ChecksumStatement.php +++ b/libraries/sql-parser/src/Statements/ChecksumStatement.php @@ -16,8 +16,7 @@ namespace SqlParser\Statements; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ChecksumStatement extends MaintenanceStatement { diff --git a/libraries/sql-parser/src/Statements/CreateStatement.php b/libraries/sql-parser/src/Statements/CreateStatement.php index 1c768cbbf1..ed13952364 100644 --- a/libraries/sql-parser/src/Statements/CreateStatement.php +++ b/libraries/sql-parser/src/Statements/CreateStatement.php @@ -27,8 +27,7 @@ use SqlParser\Statements\SelectStatement; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class CreateStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/DeleteStatement.php b/libraries/sql-parser/src/Statements/DeleteStatement.php index 0e13881926..0c661389c3 100644 --- a/libraries/sql-parser/src/Statements/DeleteStatement.php +++ b/libraries/sql-parser/src/Statements/DeleteStatement.php @@ -9,11 +9,16 @@ namespace SqlParser\Statements; use SqlParser\Statement; +use SqlParser\Parser; +use SqlParser\Token; +use SqlParser\TokensList; use SqlParser\Components\ArrayObj; use SqlParser\Components\Expression; +use SqlParser\Components\ExpressionArray; use SqlParser\Components\Limit; use SqlParser\Components\OrderKeyword; use SqlParser\Components\Condition; +use SqlParser\Components\OptionsArray; /** * `DELETE` statement. @@ -24,11 +29,25 @@ use SqlParser\Components\Condition; * [ORDER BY ...] * [LIMIT row_count] * + * Multi-table syntax + * + * DELETE [LOW_PRIORITY] [QUICK] [IGNORE] + * tbl_name[.*] [, tbl_name[.*]] ... + * FROM table_references + * [WHERE where_condition] + * + * OR + * + * DELETE [LOW_PRIORITY] [QUICK] [IGNORE] + * FROM tbl_name[.*] [, tbl_name[.*]] ... + * USING table_references + * [WHERE where_condition] + * + * * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class DeleteStatement extends Statement { @@ -57,18 +76,33 @@ class DeleteStatement extends Statement '_OPTIONS' => array('_OPTIONS', 1), 'FROM' => array('FROM', 3), 'PARTITION' => array('PARTITION', 3), + 'USING' => array('USING', 3), 'WHERE' => array('WHERE', 3), 'ORDER BY' => array('ORDER BY', 3), 'LIMIT' => array('LIMIT', 3), ); /** - * Tables used as sources for this statement. + * Table(s) used as sources for this statement. * * @var Expression[] */ public $from; + /** + * Tables used as sources for this statement + * + * @var Expression[] + */ + public $using; + + /** + * Columns used in this statement + * + * @var Expression[] + */ + public $columns; + /** * Partitions used as source for this statement. * @@ -96,4 +130,220 @@ class DeleteStatement extends Statement * @var Limit */ public $limit; + + + /** + * @return string + */ + public function build() + { + $ret = 'DELETE ' . OptionsArray::build($this->options); + + if ($this->columns != NULL && count($this->columns) > 0) { + $ret .= ' ' . ExpressionArray::build($this->columns); + } + if ($this->from != NULL && count($this->from) > 0) { + $ret .= ' FROM ' . ExpressionArray::build($this->from); + } + if ($this->using != NULL && count($this->using) > 0) { + $ret .= ' USING ' . ExpressionArray::build($this->using); + } + if ($this->where != NULL && count($this->where) > 0) { + $ret .= ' WHERE ' . Condition::build($this->where); + } + if ($this->order != NULL && count($this->order) > 0) { + $ret .= ' ORDER BY ' . ExpressionArray::build($this->order); + } + if ($this->limit != NULL && count($this->limit) > 0) { + $ret .= ' LIMIT ' . Limit::build($this->limit); + } + + return $ret; + + } + + + /** + * @param Parser $parser The instance that requests parsing. + * @param TokensList $list The list of tokens to be parsed. + * + * @return void + */ + public function parse(Parser $parser, TokensList $list) + { + ++$list->idx; // Skipping `DELETE`. + + // parse any options if provided + $this->options = OptionsArray::parse( + $parser, + $list, + static::$OPTIONS + ); + ++$list->idx; + + /** + * The state of the parser. + * + * Below are the states of the parser. + * + * 0 ---------------------------------[ FROM ]----------------------------------> 2 + * 0 ------------------------------[ table[.*] ]--------------------------------> 1 + * 1 ---------------------------------[ FROM ]----------------------------------> 2 + * 2 --------------------------------[ USING ]----------------------------------> 3 + * 2 --------------------------------[ WHERE ]----------------------------------> 4 + * 2 --------------------------------[ ORDER ]----------------------------------> 5 + * 2 --------------------------------[ LIMIT ]----------------------------------> 6 + * + * @var int $state + */ + $state = 0; + + /** + * If the query is multi-table or not + * + * @var bool $multiTable + */ + $multiTable = false; + + for (; $list->idx < $list->count; ++$list->idx) { + /** + * Token parsed at this moment. + * + * @var Token $token + */ + $token = $list->tokens[$list->idx]; + + // End of statement. + if ($token->type === Token::TYPE_DELIMITER) { + break; + } + + if ($state === 0) { + if ($token->type === Token::TYPE_KEYWORD + && $token->value !== 'FROM' + ) { + $parser->error(__('Unexpected keyword.'), $token); + break; + } elseif ($token->type === Token::TYPE_KEYWORD + && $token->value === 'FROM' + ) { + ++$list->idx; // Skip 'FROM' + $this->from = ExpressionArray::parse($parser, $list); + $state = 2; + } else { + $this->columns = ExpressionArray::parse($parser, $list); + $state = 1; + } + } elseif ($state === 1) { + if ($token->type === Token::TYPE_KEYWORD + && $token->value !== 'FROM' + ) { + $parser->error(__('Unexpected keyword.'), $token); + break; + } elseif ($token->type === Token::TYPE_KEYWORD + && $token->value === 'FROM' + ) { + ++$list->idx; // Skip 'FROM' + $this->from = ExpressionArray::parse($parser, $list); + $state = 2; + } else { + $parser->error(__('Unexpected token.'), $token); + break; + } + } elseif ($state === 2) { + if ($token->type === Token::TYPE_KEYWORD + && $token->value === 'USING' + ) { + ++$list->idx; // Skip 'USING' + $this->using = ExpressionArray::parse($parser, $list); + $state = 3; + + $multiTable = true; + } elseif ($token->type === Token::TYPE_KEYWORD + && $token->value === 'WHERE' + ) { + ++$list->idx; // Skip 'WHERE' + $this->where = Condition::parse($parser, $list); + $state = 4; + } elseif ($token->type === Token::TYPE_KEYWORD + && $token->value === 'ORDER BY' + ) { + ++$list->idx; // Skip 'ORDER BY' + $this->order = OrderKeyword::parse($parser, $list); + $state = 5; + } elseif ($token->type === Token::TYPE_KEYWORD + && $token->value === 'LIMIT' + ) { + ++$list->idx; // Skip 'LIMIT' + $this->limit = Limit::parse($parser, $list); + $state = 6; + } elseif ($token->type === Token::TYPE_KEYWORD) { + $parser->error(__('Unexpected keyword.'), $token); + break; + } + } elseif ($state === 3) { + if ($token->type === Token::TYPE_KEYWORD + && $token->value === 'WHERE' + ) { + ++$list->idx; // Skip 'WHERE' + $this->where = Condition::parse($parser, $list); + $state = 4; + } elseif ($token->type === Token::TYPE_KEYWORD) { + $parser->error(__('Unexpected keyword.'), $token); + break; + } else { + $parser->error(__('Unexpected token.'), $token); + break; + } + } elseif ($state === 4) { + if ($multiTable === true + && $token->type === Token::TYPE_KEYWORD + ) { + $parser->error( + __('This type of clause is not valid in Multi-table queries.'), + $token + ); + break; + } + + if ($token->type === Token::TYPE_KEYWORD + && $token->value === 'ORDER BY' + ) { + ++$list->idx; // Skip 'ORDER BY' + $this->order = OrderKeyword::parse($parser, $list); + $state = 5; + } elseif ($token->type === Token::TYPE_KEYWORD + && $token->value === 'LIMIT' + ) { + ++$list->idx; // Skip 'LIMIT' + $this->limit = Limit::parse($parser, $list); + $state = 6; + } elseif ($token->type === Token::TYPE_KEYWORD) { + $parser->error(__('Unexpected keyword.'), $token); + break; + } + } elseif ($state === 5) { + if ($token->type === Token::TYPE_KEYWORD + && $token->value === 'LIMIT' + ) { + ++$list->idx; // Skip 'LIMIT' + $this->limit = Limit::parse($parser, $list); + $state = 6; + } elseif ($token->type === Token::TYPE_KEYWORD) { + $parser->error(__('Unexpected keyword.'), $token); + break; + } + } + } + + if ($state >= 2) { + foreach ($this->from as $from_expr) { + $from_expr->database = $from_expr->table; + $from_expr->table = $from_expr->column; + $from_expr->column = null; + } + } + + --$list->idx; + } } diff --git a/libraries/sql-parser/src/Statements/DropStatement.php b/libraries/sql-parser/src/Statements/DropStatement.php index 063146e1f5..b75ab0e555 100644 --- a/libraries/sql-parser/src/Statements/DropStatement.php +++ b/libraries/sql-parser/src/Statements/DropStatement.php @@ -17,8 +17,7 @@ use SqlParser\Components\Expression; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class DropStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/ExplainStatement.php b/libraries/sql-parser/src/Statements/ExplainStatement.php index eb869643cb..78c7acd219 100644 --- a/libraries/sql-parser/src/Statements/ExplainStatement.php +++ b/libraries/sql-parser/src/Statements/ExplainStatement.php @@ -14,8 +14,7 @@ namespace SqlParser\Statements; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ExplainStatement extends NotImplementedStatement { diff --git a/libraries/sql-parser/src/Statements/InsertStatement.php b/libraries/sql-parser/src/Statements/InsertStatement.php index 164b52c967..2270f5897e 100644 --- a/libraries/sql-parser/src/Statements/InsertStatement.php +++ b/libraries/sql-parser/src/Statements/InsertStatement.php @@ -54,8 +54,7 @@ use SqlParser\Components\SetOperation; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class InsertStatement extends Statement { @@ -201,7 +200,11 @@ class InsertStatement extends Statement break; } else { ++$list->idx; - $this->into = IntoKeyword::parse($parser, $list); + $this->into = IntoKeyword::parse( + $parser, + $list, + array('fromInsert' => true) + ); } $state = 1; diff --git a/libraries/sql-parser/src/Statements/MaintenanceStatement.php b/libraries/sql-parser/src/Statements/MaintenanceStatement.php index 952314e8f2..9097527c54 100644 --- a/libraries/sql-parser/src/Statements/MaintenanceStatement.php +++ b/libraries/sql-parser/src/Statements/MaintenanceStatement.php @@ -24,8 +24,7 @@ use SqlParser\Components\OptionsArray; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class MaintenanceStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/NotImplementedStatement.php b/libraries/sql-parser/src/Statements/NotImplementedStatement.php index 0a1dc338eb..8bdff2d776 100644 --- a/libraries/sql-parser/src/Statements/NotImplementedStatement.php +++ b/libraries/sql-parser/src/Statements/NotImplementedStatement.php @@ -21,8 +21,7 @@ use SqlParser\TokensList; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class NotImplementedStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/OptimizeStatement.php b/libraries/sql-parser/src/Statements/OptimizeStatement.php index 07150150da..f688333e4f 100644 --- a/libraries/sql-parser/src/Statements/OptimizeStatement.php +++ b/libraries/sql-parser/src/Statements/OptimizeStatement.php @@ -20,8 +20,7 @@ use SqlParser\Components\Expression; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class OptimizeStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/RenameStatement.php b/libraries/sql-parser/src/Statements/RenameStatement.php index 6b4f1888e0..0205f84633 100644 --- a/libraries/sql-parser/src/Statements/RenameStatement.php +++ b/libraries/sql-parser/src/Statements/RenameStatement.php @@ -23,8 +23,7 @@ use SqlParser\Components\RenameOperation; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class RenameStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/RepairStatement.php b/libraries/sql-parser/src/Statements/RepairStatement.php index b1d840b624..f98fcc62b8 100644 --- a/libraries/sql-parser/src/Statements/RepairStatement.php +++ b/libraries/sql-parser/src/Statements/RepairStatement.php @@ -18,8 +18,7 @@ namespace SqlParser\Statements; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class RepairStatement extends MaintenanceStatement { diff --git a/libraries/sql-parser/src/Statements/ReplaceStatement.php b/libraries/sql-parser/src/Statements/ReplaceStatement.php index df00272657..4142c886c8 100644 --- a/libraries/sql-parser/src/Statements/ReplaceStatement.php +++ b/libraries/sql-parser/src/Statements/ReplaceStatement.php @@ -42,8 +42,7 @@ use SqlParser\Components\SetOperation; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ReplaceStatement extends Statement { @@ -167,7 +166,11 @@ class ReplaceStatement extends Statement break; } else { ++$list->idx; - $this->into = IntoKeyword::parse($parser, $list); + $this->into = IntoKeyword::parse( + $parser, + $list, + array('fromReplace' => true) + ); } $state = 1; diff --git a/libraries/sql-parser/src/Statements/RestoreStatement.php b/libraries/sql-parser/src/Statements/RestoreStatement.php index be83dd64e1..8500479bbd 100644 --- a/libraries/sql-parser/src/Statements/RestoreStatement.php +++ b/libraries/sql-parser/src/Statements/RestoreStatement.php @@ -16,8 +16,7 @@ namespace SqlParser\Statements; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class RestoreStatement extends MaintenanceStatement { diff --git a/libraries/sql-parser/src/Statements/SelectStatement.php b/libraries/sql-parser/src/Statements/SelectStatement.php index 5d306f0662..34a68c3e45 100644 --- a/libraries/sql-parser/src/Statements/SelectStatement.php +++ b/libraries/sql-parser/src/Statements/SelectStatement.php @@ -49,8 +49,7 @@ use SqlParser\Components\Condition; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class SelectStatement extends Statement { @@ -88,6 +87,7 @@ class SelectStatement extends Statement '_OPTIONS' => array('_OPTIONS', 1), // Used for selected expressions. '_SELECT' => array('SELECT', 1), + 'INTO' => array('INTO', 3), 'FROM' => array('FROM', 3), 'PARTITION' => array('PARTITION', 3), @@ -105,7 +105,6 @@ class SelectStatement extends Statement 'ORDER BY' => array('ORDER BY', 3), 'LIMIT' => array('LIMIT', 3), 'PROCEDURE' => array('PROCEDURE', 3), - 'INTO' => array('INTO', 3), 'UNION' => array('UNION', 1), // These are available only when `UNION` is present. // 'ORDER BY' => array('ORDER BY', 3), diff --git a/libraries/sql-parser/src/Statements/SetStatement.php b/libraries/sql-parser/src/Statements/SetStatement.php index a5cffa2609..a9ff498315 100644 --- a/libraries/sql-parser/src/Statements/SetStatement.php +++ b/libraries/sql-parser/src/Statements/SetStatement.php @@ -18,8 +18,7 @@ use SqlParser\Components\OptionsArray; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class SetStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/ShowStatement.php b/libraries/sql-parser/src/Statements/ShowStatement.php index ae8cb3f55c..ecca348960 100644 --- a/libraries/sql-parser/src/Statements/ShowStatement.php +++ b/libraries/sql-parser/src/Statements/ShowStatement.php @@ -14,8 +14,7 @@ namespace SqlParser\Statements; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class ShowStatement extends NotImplementedStatement { diff --git a/libraries/sql-parser/src/Statements/TransactionStatement.php b/libraries/sql-parser/src/Statements/TransactionStatement.php index 0ae83fec3f..2d355eab99 100644 --- a/libraries/sql-parser/src/Statements/TransactionStatement.php +++ b/libraries/sql-parser/src/Statements/TransactionStatement.php @@ -19,8 +19,7 @@ use SqlParser\Components\OptionsArray; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class TransactionStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/TruncateStatement.php b/libraries/sql-parser/src/Statements/TruncateStatement.php index c0cb5fd2c1..6f9d303a9c 100644 --- a/libraries/sql-parser/src/Statements/TruncateStatement.php +++ b/libraries/sql-parser/src/Statements/TruncateStatement.php @@ -17,8 +17,7 @@ use SqlParser\Components\Expression; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class TruncateStatement extends Statement { diff --git a/libraries/sql-parser/src/Statements/UpdateStatement.php b/libraries/sql-parser/src/Statements/UpdateStatement.php index 59b2ff72a3..011b955520 100644 --- a/libraries/sql-parser/src/Statements/UpdateStatement.php +++ b/libraries/sql-parser/src/Statements/UpdateStatement.php @@ -33,8 +33,7 @@ use SqlParser\Components\Condition; * @category Statements * @package SqlParser * @subpackage Statements - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class UpdateStatement extends Statement { diff --git a/libraries/sql-parser/src/Token.php b/libraries/sql-parser/src/Token.php index 18ffec76a7..3181a446ab 100644 --- a/libraries/sql-parser/src/Token.php +++ b/libraries/sql-parser/src/Token.php @@ -15,8 +15,7 @@ namespace SqlParser; * * @category Tokens * @package SqlParser - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Token { diff --git a/libraries/sql-parser/src/TokensList.php b/libraries/sql-parser/src/TokensList.php index 10ff56e717..c0c2c89e71 100644 --- a/libraries/sql-parser/src/TokensList.php +++ b/libraries/sql-parser/src/TokensList.php @@ -12,8 +12,7 @@ namespace SqlParser; * * @category Tokens * @package SqlParser - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class TokensList implements \ArrayAccess { diff --git a/libraries/sql-parser/src/UtfString.php b/libraries/sql-parser/src/UtfString.php index 5f4ba12f9d..c7b08d8e18 100644 --- a/libraries/sql-parser/src/UtfString.php +++ b/libraries/sql-parser/src/UtfString.php @@ -21,8 +21,7 @@ namespace SqlParser; * * @category Misc * @package SqlParser - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class UtfString implements \ArrayAccess { diff --git a/libraries/sql-parser/src/Utils/BufferedQuery.php b/libraries/sql-parser/src/Utils/BufferedQuery.php index 8aad59f543..b1ef46d4a1 100644 --- a/libraries/sql-parser/src/Utils/BufferedQuery.php +++ b/libraries/sql-parser/src/Utils/BufferedQuery.php @@ -22,8 +22,7 @@ use SqlParser\Context; * @category Lexer * @package SqlParser * @subpackage Utils - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class BufferedQuery { diff --git a/libraries/sql-parser/src/Utils/CLI.php b/libraries/sql-parser/src/Utils/CLI.php index b6ce35e687..9ec7b85357 100644 --- a/libraries/sql-parser/src/Utils/CLI.php +++ b/libraries/sql-parser/src/Utils/CLI.php @@ -17,8 +17,7 @@ use SqlParser\Lexer; * @category Exceptions * @package SqlParser * @subpackage Utils - * @author Michal Čihař - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class CLI { diff --git a/libraries/sql-parser/src/Utils/Error.php b/libraries/sql-parser/src/Utils/Error.php index f0ad5afbb2..2e942c4434 100644 --- a/libraries/sql-parser/src/Utils/Error.php +++ b/libraries/sql-parser/src/Utils/Error.php @@ -17,8 +17,7 @@ use SqlParser\Parser; * @category Exceptions * @package SqlParser * @subpackage Utils - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Error { diff --git a/libraries/sql-parser/src/Utils/Formatter.php b/libraries/sql-parser/src/Utils/Formatter.php index 41b50945b5..bcf5486263 100644 --- a/libraries/sql-parser/src/Utils/Formatter.php +++ b/libraries/sql-parser/src/Utils/Formatter.php @@ -19,8 +19,7 @@ use SqlParser\TokensList; * @category Misc * @package SqlParser * @subpackage Utils - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Formatter { diff --git a/libraries/sql-parser/src/Utils/Misc.php b/libraries/sql-parser/src/Utils/Misc.php index cec5653688..8166c458d2 100644 --- a/libraries/sql-parser/src/Utils/Misc.php +++ b/libraries/sql-parser/src/Utils/Misc.php @@ -17,8 +17,7 @@ use SqlParser\Statements\SelectStatement; * @category Misc * @package SqlParser * @subpackage Utils - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Misc { diff --git a/libraries/sql-parser/src/Utils/Query.php b/libraries/sql-parser/src/Utils/Query.php index 239cd6f41b..2e0982a018 100644 --- a/libraries/sql-parser/src/Utils/Query.php +++ b/libraries/sql-parser/src/Utils/Query.php @@ -39,8 +39,7 @@ use SqlParser\Statements\UpdateStatement; * @category Statement * @package SqlParser * @subpackage Utils - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Query { diff --git a/libraries/sql-parser/src/Utils/Routine.php b/libraries/sql-parser/src/Utils/Routine.php index 5450cac178..d5a7891d17 100644 --- a/libraries/sql-parser/src/Utils/Routine.php +++ b/libraries/sql-parser/src/Utils/Routine.php @@ -20,8 +20,7 @@ use SqlParser\Statements\CreateStatement; * @category Routines * @package SqlParser * @subpackage Utils - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Routine { diff --git a/libraries/sql-parser/src/Utils/Table.php b/libraries/sql-parser/src/Utils/Table.php index b88f2345d1..a31ddf2703 100644 --- a/libraries/sql-parser/src/Utils/Table.php +++ b/libraries/sql-parser/src/Utils/Table.php @@ -16,8 +16,7 @@ use SqlParser\Statements\CreateStatement; * @category Statement * @package SqlParser * @subpackage Utils - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Table { diff --git a/libraries/sql-parser/src/Utils/Tokens.php b/libraries/sql-parser/src/Utils/Tokens.php index eb76df2a73..acec369c40 100644 --- a/libraries/sql-parser/src/Utils/Tokens.php +++ b/libraries/sql-parser/src/Utils/Tokens.php @@ -18,8 +18,7 @@ use SqlParser\TokensList; * @category Token * @package SqlParser * @subpackage Utils - * @author Dan Ungureanu - * @license http://opensource.org/licenses/GPL-2.0 GNU Public License + * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+ */ class Tokens { diff --git a/libraries/sql.lib.php b/libraries/sql.lib.php index d7c164f719..f51adf43dc 100644 --- a/libraries/sql.lib.php +++ b/libraries/sql.lib.php @@ -662,6 +662,7 @@ function PMA_isJustBrowsing($analyzed_sql_results, $find_real_end) && empty($analyzed_sql_results['group']) && ! isset($find_real_end) && ! $analyzed_sql_results['is_subquery'] + && ! $analyzed_sql_results['join'] && empty($analyzed_sql_results['having']); } @@ -1122,7 +1123,7 @@ function PMA_countQueryResults( ) { // c o u n t q u e r y - // If we are "just browsing", there is only one table, + // If we are "just browsing", there is only one table (and no join), // and no WHERE clause (or just 'WHERE 1 '), // we do a quick count (which uses MaxExactCount) because // SQL_CALC_FOUND_ROWS is not quick on large InnoDB tables @@ -1433,6 +1434,10 @@ function PMA_getQueryResponseForNoResultsReturned($analyzed_sql_results, $db, } $html_output = ''; + $html_message = PMA\libraries\Util::getMessage( + $message, $GLOBALS['sql_query'], 'success' + ); + $html_output .= $html_message; if (!isset($GLOBALS['show_as_php'])) { if (! empty($GLOBALS['reload'])) { @@ -1440,11 +1445,6 @@ function PMA_getQueryResponseForNoResultsReturned($analyzed_sql_results, $db, $extra_data['db'] = $GLOBALS['db']; } - $html_message = PMA\libraries\Util::getMessage( - $message, $GLOBALS['sql_query'], 'success' - ); - $html_output .= $html_message; - // For ajax requests add message and sql_query as JSON if (empty($_REQUEST['ajax_page_request'])) { $extra_data['message'] = $message; diff --git a/po/id.po b/po/id.po index e3a68ab22f..306791a5ff 100644 --- a/po/id.po +++ b/po/id.po @@ -4,7 +4,7 @@ msgstr "" "Project-Id-Version: phpMyAdmin 4.6.5-dev\n" "Report-Msgid-Bugs-To: translators@phpmyadmin.net\n" "POT-Creation-Date: 2016-08-17 11:29+0200\n" -"PO-Revision-Date: 2016-09-16 00:03+0000\n" +"PO-Revision-Date: 2016-10-02 21:37+0000\n" "Last-Translator: Dadan Setia \n" "Language-Team: Indonesian " "\n" @@ -689,7 +689,7 @@ msgstr "Kumpulan karakter server:" #: index.php:322 msgid "Web server" -msgstr "Server web" +msgstr "web server" #: index.php:333 msgid "Database client version:" @@ -1870,7 +1870,7 @@ msgstr "Definisi fungsi disimpan harus mengandung pernyataan RETURN!" #: setup/frames/menu.inc.php:27 #: templates/database/structure/check_all_tables.phtml:12 msgid "Export" -msgstr "Ekspor" +msgstr "" #: js/messages.php:395 libraries/rte/rte_routines.lib.php:740 msgid "ENUM/SET editor" diff --git a/po/mk.po b/po/mk.po index e63b5dfabd..249017abf3 100644 --- a/po/mk.po +++ b/po/mk.po @@ -4,16 +4,16 @@ msgstr "" "Project-Id-Version: phpMyAdmin 4.6.5-dev\n" "Report-Msgid-Bugs-To: translators@phpmyadmin.net\n" "POT-Creation-Date: 2016-08-17 11:29+0200\n" -"PO-Revision-Date: 2015-10-15 11:23+0200\n" -"Last-Translator: Michal Čihař \n" -"Language-Team: Macedonian \n" +"PO-Revision-Date: 2016-09-30 14:17+0000\n" +"Last-Translator: Dragan Zlatkovski \n" +"Language-Team: Macedonian " +"\n" "Language: mk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n==1 || n%10==1 ? 0 : 1;\n" -"X-Generator: Weblate 2.5-dev\n" +"X-Generator: Weblate 2.9-dev\n" #: changelog.php:38 license.php:33 #, php-format @@ -21,20 +21,21 @@ msgid "" "The %s file is not available on this system, please visit www.phpmyadmin.net " "for more information." msgstr "" +"%s датотеката не е достапна во системот, за повеќе информации видете на " +"www.phpmyadmin.net ." #: db_central_columns.php:105 msgid "The central list of columns for the current database is empty." -msgstr "" +msgstr "Главната листа на колони за тековната база на податоци е празна." #: db_central_columns.php:130 msgid "Click to sort." -msgstr "" +msgstr "Сортирај" #: db_central_columns.php:149 -#, fuzzy, php-format -#| msgid "Showing rows" +#, php-format msgid "Showing rows %1$s - %2$s." -msgstr "Приказ на записи од" +msgstr "Приказ на записи %1$s - %2$s." #: db_datadict.php:57 libraries/operations.lib.php:34 msgid "Database comment" @@ -70,10 +71,8 @@ msgstr "Коментар на табелата:" #: templates/table/relation/internal_relational_row.phtml:73 #: templates/table/search/table_header.phtml:6 #: templates/table/search/zoom_result_form.phtml:33 -#, fuzzy -#| msgid "Column names" msgid "Column" -msgstr "Имиња на колони" +msgstr "Колона" #: db_datadict.php:114 libraries/Index.php:694 #: libraries/central_columns.lib.php:694 libraries/central_columns.lib.php:1380 @@ -99,7 +98,7 @@ msgstr "Имиња на колони" #: templates/table/search/table_header.phtml:7 #: templates/table/structure/table_structure_header.phtml:8 msgid "Type" -msgstr "Тип" +msgstr "Вид" #: db_datadict.php:115 libraries/Index.php:700 #: libraries/central_columns.lib.php:705 libraries/central_columns.lib.php:1381 @@ -286,14 +285,12 @@ msgstr "Податоци" #: db_export.php:70 libraries/DbSearch.php:442 #: libraries/display_export.lib.php:42 libraries/replication_gui.lib.php:377 -#, fuzzy -#| msgid "Select All" msgid "Select all" -msgstr "избери се" +msgstr "Избери се" #: db_operations.php:52 tbl_create.php:21 msgid "The database name is empty!" -msgstr "Името на базата на податоци не е зададено!" +msgstr "Името на базата на податоци е празно!" #: db_operations.php:140 #, fuzzy, php-format @@ -319,10 +316,8 @@ msgstr "" "дознаете зошто, кликнете %sовде%s." #: db_qbe.php:125 -#, fuzzy -#| msgid "You have to choose at least one column to display" msgid "You have to choose at least one column to display!" -msgstr "Морате да изберете барем една колона за приказ" +msgstr "Изберете барем една колона за приказ!" #: db_qbe.php:143 #, fuzzy, php-format @@ -350,10 +345,8 @@ msgid "" msgstr "" #: db_tracking.php:92 -#, fuzzy -#| msgid "No databases selected." msgid "No tables selected." -msgstr "Не е избрана ни една база на податоци." +msgstr "Не е избрана ниту една табела." #: db_tracking.php:149 #, fuzzy @@ -365,10 +358,12 @@ msgid "" "An error has been detected and an error report has been automatically " "submitted based on your settings." msgstr "" +"Откриена е грешка и извештајот за грешка е автоматски доставени врз основа " +"на вашите подесувања." #: error_report.php:72 msgid "Thank you for submitting this report." -msgstr "" +msgstr "Ви благодариме за поднесување на овој извештај." #: error_report.php:76 msgid "" @@ -382,24 +377,20 @@ msgstr "" #: error_report.php:85 msgid "You may want to refresh the page." -msgstr "" +msgstr "Можеби сакате да се освежи страница." #: export.php:190 schema_export.php:64 -#, fuzzy -#| msgid "Bar type" msgid "Bad type!" -msgstr "Вид на упит" +msgstr "Лош тип!" #: export.php:277 -#, fuzzy -#| msgid "Add new field" msgid "Bad parameters!" -msgstr "Додади ново поле" +msgstr "Неправилни параметри!" #: gis_data_editor.php:117 #, php-format msgid "Value for the column \"%s\"" -msgstr "" +msgstr "Вредност за колоната \"%s\"" #: gis_data_editor.php:145 #: templates/table/gis_visualization/gis_visualization.phtml:38 @@ -418,30 +409,28 @@ msgstr "" #: gis_data_editor.php:215 msgid "Point:" -msgstr "" +msgstr "Точка:" #: gis_data_editor.php:216 gis_data_editor.php:243 gis_data_editor.php:299 #: gis_data_editor.php:372 js/messages.php:508 msgid "X" -msgstr "" +msgstr "X" #: gis_data_editor.php:219 gis_data_editor.php:247 gis_data_editor.php:303 #: gis_data_editor.php:378 js/messages.php:509 msgid "Y" -msgstr "" +msgstr "Y" #: gis_data_editor.php:241 gis_data_editor.php:297 gis_data_editor.php:370 #: js/messages.php:511 #, php-format msgid "Point %d" -msgstr "" +msgstr "Точка %d" #: gis_data_editor.php:254 gis_data_editor.php:310 gis_data_editor.php:388 #: js/messages.php:517 -#, fuzzy -#| msgid "Add new field" msgid "Add a point" -msgstr "Додади ново поле" +msgstr "Додади точка" #: gis_data_editor.php:271 #, fuzzy, php-format @@ -471,16 +460,13 @@ msgid "Add an inner ring" msgstr "Додади нов корисник" #: gis_data_editor.php:335 -#, fuzzy, php-format -#| msgid "Add %s field(s)" +#, php-format msgid "Polygon %d:" -msgstr "Додади %s полиња" +msgstr "Полигон %d:" #: gis_data_editor.php:399 -#, fuzzy -#| msgid "Add %s field(s)" msgid "Add a polygon" -msgstr "Додади %s полиња" +msgstr "Додади полигон" #: gis_data_editor.php:405 #, fuzzy @@ -576,10 +562,8 @@ msgid "" msgstr "" #: import.php:506 import.php:583 libraries/File.php:429 libraries/File.php:522 -#, fuzzy -#| msgid "File could not be read" msgid "File could not be read!" -msgstr "Податотеката не е можно да се прочита" +msgstr "Датотеката не е можно да се прочита" #: import.php:517 import.php:532 import.php:557 import.php:572 #: libraries/File.php:589 @@ -601,9 +585,9 @@ msgid "Could not load import plugins, please check your installation!" msgstr "" #: import.php:684 libraries/sql.lib.php:779 libraries/sql.lib.php:1559 -#, fuzzy, php-format +#, php-format msgid "Bookmark %s has been created." -msgstr "Табелата %s е избришана" +msgstr "Маркерот %s е креиран." #: import.php:694 #, php-format @@ -649,10 +633,8 @@ msgid "" msgstr "" #: index.php:161 -#, fuzzy -#| msgid "General relation features" msgid "General settings" -msgstr "Општи особини на релациите" +msgstr "Општи поставувања" #: index.php:191 js/messages.php:625 #: libraries/display_change_password.lib.php:50 @@ -673,10 +655,8 @@ msgid "Appearance settings" msgstr "Општи особини на релациите" #: index.php:262 prefs_manage.php:284 -#, fuzzy -#| msgid "General relation features" msgid "More settings" -msgstr "Општи особини на релациите" +msgstr "Повеќе поставки" #: index.php:284 #, fuzzy @@ -689,28 +669,22 @@ msgid "Server:" msgstr "Сервер:" #: index.php:291 -#, fuzzy msgid "Server type:" -msgstr "ID на серверот" +msgstr "Вид сервер:" #: index.php:295 libraries/plugins/export/ExportLatex.php:220 #: libraries/plugins/export/ExportSql.php:701 #: libraries/plugins/export/ExportXml.php:242 -#, fuzzy -#| msgid "Server version" msgid "Server version:" -msgstr "Верзија на серверот" +msgstr "Верзија на серверот:" #: index.php:301 -#, fuzzy msgid "Protocol version:" -msgstr "Верзија на серверот" +msgstr "Верзија на протокол:" #: index.php:305 -#, fuzzy -#| msgid "User" msgid "User:" -msgstr "Корисник" +msgstr "Корисник:" #: index.php:310 #, fuzzy @@ -719,7 +693,7 @@ msgstr "Избор на сервер" #: index.php:322 msgid "Web server" -msgstr "" +msgstr "Веб сервер" #: index.php:333 #, fuzzy @@ -728,21 +702,16 @@ msgid "Database client version:" msgstr "Коментар на базата на податоци:" #: index.php:337 -#, fuzzy msgid "PHP extension:" -msgstr "PHP верзија" +msgstr "PHP проширувања:" #: index.php:351 -#, fuzzy -#| msgid "PHP Version" msgid "PHP version:" -msgstr "PHP верзија" +msgstr "PHP верзија:" #: index.php:372 -#, fuzzy -#| msgid "Version information" msgid "Version information:" -msgstr "Информации за верзијата" +msgstr "Информации за верзијата:" #: index.php:381 libraries/Util.php:451 libraries/Util.php:518 #: libraries/config/FormDisplay.tpl.php:163 @@ -755,27 +724,23 @@ msgstr "Документација" #: index.php:390 msgid "Official Homepage" -msgstr "официјален веб сајт на phpMyAdmin" +msgstr "Официјален веб сајт" #: index.php:397 -#, fuzzy -#| msgid "Attributes" msgid "Contribute" -msgstr "Атрибути" +msgstr "Учество" #: index.php:404 msgid "Get support" -msgstr "" +msgstr "Поддршка" #: index.php:411 -#, fuzzy -#| msgid "No change" msgid "List of changes" -msgstr "Нема измени" +msgstr "Листа на промени" #: index.php:418 templates/server/plugins/section.phtml:12 msgid "License" -msgstr "" +msgstr "Лиценца" #: index.php:438 msgid "" @@ -870,13 +835,12 @@ msgstr "\"DROP DATABASE\" командата е оневозможена." #: js/messages.php:45 msgid "Confirm" -msgstr "" +msgstr "Потврди" #: js/messages.php:46 -#, fuzzy, php-format -#| msgid "Do you really want to " +#, php-format msgid "Do you really want to execute \"%s\"?" -msgstr "Дали навистина сакате да " +msgstr "Дали навистина сакате да извршите \"%s\"?" #: js/messages.php:48 libraries/mult_submits.lib.php:443 msgid "You are about to DESTROY a complete database!" diff --git a/po/sk.po b/po/sk.po index a0f4908228..452a90a4be 100644 --- a/po/sk.po +++ b/po/sk.po @@ -4,8 +4,8 @@ msgstr "" "Project-Id-Version: phpMyAdmin 4.6.5-dev\n" "Report-Msgid-Bugs-To: translators@phpmyadmin.net\n" "POT-Creation-Date: 2016-08-17 11:29+0200\n" -"PO-Revision-Date: 2016-09-07 11:45+0000\n" -"Last-Translator: Martin Lacina \n" +"PO-Revision-Date: 2016-09-26 18:21+0000\n" +"Last-Translator: Jozef Pistej \n" "Language-Team: Slovak " "\n" "Language: sk\n" @@ -13,7 +13,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 2.8\n" +"X-Generator: Weblate 2.9-dev\n" #: changelog.php:38 license.php:33 #, php-format @@ -3632,7 +3632,7 @@ msgstr "Neznáma chyba pri nahrávaní súboru." #: libraries/File.php:424 msgid "File is a symbolic link" -msgstr "" +msgstr "Súbor je symbolická linka" #: libraries/File.php:470 msgid "Error moving the uploaded file, see [doc@faq1-11]FAQ 1.11[/doc]." @@ -4589,7 +4589,7 @@ msgstr "Statická analýza:" #: libraries/Util.php:691 #, php-format msgid "%d errors were found during analysis." -msgstr "" +msgstr "Počas analýzy bolo nájdených %d chýb." #: libraries/Util.php:754 libraries/rte/rte_events.lib.php:113 #: libraries/rte/rte_events.lib.php:122 libraries/rte/rte_events.lib.php:153 diff --git a/po/zh_CN.po b/po/zh_CN.po index acc410fd54..a8fd0abf5b 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -4,8 +4,8 @@ msgstr "" "Project-Id-Version: phpMyAdmin 4.6.5-dev\n" "Report-Msgid-Bugs-To: translators@phpmyadmin.net\n" "POT-Creation-Date: 2016-08-17 11:29+0200\n" -"PO-Revision-Date: 2016-09-09 03:15+0000\n" -"Last-Translator: jin123456bat <326550324@qq.com>\n" +"PO-Revision-Date: 2016-10-02 09:16+0000\n" +"Last-Translator: an wei \n" "Language-Team: Chinese (China) " "\n" "Language: zh_CN\n" @@ -13,7 +13,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2.8\n" +"X-Generator: Weblate 2.9-dev\n" #: changelog.php:38 license.php:33 #, php-format @@ -8977,7 +8977,7 @@ msgstr[0] "找到 %s 条结果" #: libraries/navigation/NavigationTree.php:1364 #: libraries/navigation/NavigationTree.php:1401 msgid "Type to filter these, Enter to search all" -msgstr "" +msgstr "过滤器" #: libraries/navigation/NavigationTree.php:1366 #: libraries/navigation/NavigationTree.php:1402 @@ -9282,7 +9282,7 @@ msgstr "" #: libraries/normalization.lib.php:444 #, php-format msgid "The second step of normalization is complete for table '%1$s'." -msgstr "" +msgstr "标准化第二步请完成表“%1$s”。" #: libraries/normalization.lib.php:484 libraries/normalization.lib.php:629 #: libraries/normalization.lib.php:694 @@ -15434,14 +15434,12 @@ msgid "The profile has been updated." msgstr "配置文件己更新。" #: user_password.php:124 -#, fuzzy -#| msgid "Password Hashing:" msgid "Password is too long!" -msgstr "密码加密方式:" +msgstr "密码太长!" #: view_create.php:44 msgid "View name can not be empty" -msgstr "" +msgstr "请勿使用空白视图名" #: view_create.php:247 msgid "VIEW name" @@ -15661,6 +15659,8 @@ msgid "" "Percona documentation is at https://www.percona.com/software/documentation/" msgstr "" +"有关Percona的文档,请访问访问https://www.percona.com/software/documentation/" #: libraries/advisory_rules.txt:133 msgid "'percona' found in version_comment" diff --git a/scripts/remove_control_m.sh b/scripts/remove_control_m.sh deleted file mode 100755 index 4f5b213c1b..0000000000 --- a/scripts/remove_control_m.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -# -# -# Script to remove ^M from files for DOS <-> UNIX conversions -# - -if [ $# != 1 ] -then - echo "Usage: remove_control_m.sh " - echo "" - echo "Example: remove_control_m.sh php3" - exit -fi - -for i in `find . -name "*.$1"` - do - echo $i - tr -d '\015' < $i > ${i}.new - rm $i - mv ${i}.new $i -done diff --git a/scripts/revision-info b/scripts/revision-info deleted file mode 100755 index d81a5a30b2..0000000000 --- a/scripts/revision-info +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -# -# Generates revision-info.php file which is used by demo server -# - -set -e - -remote_url=`git remote show -n origin | grep 'Fetch' | sed 's/.*URL: //'` -ref=$(git symbolic-ref -q HEAD || git name-rev --name-only HEAD 2>/dev/null) -ref=${ref#refs/heads/} -rev=`git describe --always` -fullrev=`git log -1 | head -n 1 | awk '{print $2}'` -if [ "$remote_url" = "git://github.com/phpmyadmin/phpmyadmin.git" ] \ - || [ "$remote_url" = "https://github.com/phpmyadmin/phpmyadmin" ]; then - repobase="https://github.com/phpmyadmin/phpmyadmin/commit/" - repobranchbase="https://github.com/phpmyadmin/phpmyadmin/tree/" - reponame='' -elif echo "$remote_url" | grep -q "git://github.com/" ; then - repobase=`echo $remote_url | sed 's@git://github.com/\(.*\)/\(.*\).git@https://github.com/\1/\2/commit/@'` - repobranchbase=`echo $remote_url | sed 's@git://github.com/\(.*\)/\(.*\).git@https://github.com/\1/\2/tree/@'` - reponame=`echo $remote_url | sed 's@git://github.com/\(.*\)/\(.*\).git@\1@'` -else - repobase=`echo $remote_url | sed 's@git://repo.or.cz@https://repo.or.cz/w@'`/commitdiff/ - repobranchbase=`echo $remote_url | sed 's@git://repo.or.cz@https://repo.or.cz/w@'`/shortlog/refs/heads/ - reponame='' -fi -cat > revision-info.php.tmp < -EOT -mv revision-info.php.tmp revision-info.php diff --git a/server_privileges.php b/server_privileges.php index 34dd8933b8..c7b1c4f71e 100644 --- a/server_privileges.php +++ b/server_privileges.php @@ -68,8 +68,9 @@ $strPrivDescDropTbl = __('Allows dropping tables.'); $strPrivDescEvent = __('Allows to set up events for the event scheduler.'); $strPrivDescExecute = __('Allows executing stored routines.'); $strPrivDescFile = __('Allows importing data from and exporting data into files.'); -$strPrivDescGrant = __( - 'Allows adding users and privileges without reloading the privilege tables.' +$strPrivDescGrantTbl = __( + 'Allows user to give to other users or remove from other users the privileges ' + . 'that user possess yourself.' ); $strPrivDescIndex = __('Allows creating and dropping indexes.'); $strPrivDescInsert = __('Allows inserting and replacing data.'); diff --git a/tbl_export.php b/tbl_export.php index 8c703f0197..542dfd9c84 100644 --- a/tbl_export.php +++ b/tbl_export.php @@ -67,13 +67,15 @@ if (! empty($sql_query)) { } // Rebuilding the SELECT and FROM clauses. - $replaces = array( - array( - 'FROM', 'FROM ' . SqlParser\Components\ExpressionArray::build( - $parser->statements[0]->from + if (count($parser->statements[0]->from) > 0) { + $replaces = array( + array( + 'FROM', 'FROM ' . SqlParser\Components\ExpressionArray::build( + $parser->statements[0]->from + ), ), - ), - ); + ); + } // Checking if the WHERE clause has to be replaced. if ((!empty($where_clause)) && (is_array($where_clause))) { diff --git a/themes/original/css/common.css.php b/themes/original/css/common.css.php index 13b4b3debc..05b374e773 100644 --- a/themes/original/css/common.css.php +++ b/themes/original/css/common.css.php @@ -1355,6 +1355,16 @@ label.desc sup { position: absolute; } +code.php { + display: block; + padding-left: 0.3em; + margin-top: 0; + margin-bottom: 0; + max-height: 10em; + overflow: auto; + direction: ltr; +} + code.sql, div.sqlvalidate { display: block; diff --git a/themes/pmahomme/css/common.css.php b/themes/pmahomme/css/common.css.php index a4177400f3..e19395c056 100644 --- a/themes/pmahomme/css/common.css.php +++ b/themes/pmahomme/css/common.css.php @@ -1786,6 +1786,16 @@ label.desc sup { position: absolute; } +code.php { + display: block; + padding-left: 1em; + margin-top: 0; + margin-bottom: 0; + max-height: 10em; + overflow: auto; + direction: ltr; +} + code.sql, div.sqlvalidate { display: block;