Merge remote-tracking branch 'origin/master' into useNamespaces_master

This commit is contained in:
Hugues Peccatte 2015-10-01 18:19:18 +02:00
commit bd0d2b79db
129 changed files with 45721 additions and 42869 deletions

View File

@ -23,6 +23,11 @@ phpMyAdmin - ChangeLog
- issue Notice in Structure page of views
- issue #11510 AUTO_INCREMENT always exported when IF NOT EXISTS is on
- issue #11516 Some partitions are missing in copied table
- issue #11521 Notice of undefined variable when performing SHOW CREATE
- issue #11509 Error exporting sql query results with table alias
- issue #11512 SQL editing window does not recognise 'OUTER' keyword in 'LEFT OUTER JOIN'
- issue #11518 "NOT IN" clause not recognized (MySQL 5.6 and 5.7)
- issue #11524 Yellow star does not change in database Structure after add/remove from favorites
4.5.0.2 (2015-09-25)
- issue #11497 Incorrect indexes when exporting

View File

@ -442,11 +442,6 @@ class TypesMySQL extends Types
'MPolyFromWKB',
);
case 'JSON':
return array(
'JSON_ARRAY',
'JSON_OBJECT',
);
}
return array();
}

View File

@ -694,6 +694,7 @@ class DatabaseStructureController extends DatabaseController
if ($already_favorite) {
// If already in favorite list, remove it.
$fav_instance->remove($this->db, $favorite_table);
$already_favorite = false; // for favorite_anchor template
}
} elseif (isset($_REQUEST['add_favorite'])) {
if (!$already_favorite) {
@ -703,6 +704,7 @@ class DatabaseStructureController extends DatabaseController
} else {
// Otherwise add to favorite list.
$fav_instance->add($this->db, $favorite_table);
$already_favorite = true; // for favorite_anchor template
}
}
}
@ -733,7 +735,8 @@ class DatabaseStructureController extends DatabaseController
'current_table' => array(
'TABLE_NAME' => $favorite_table
),
'titles' => $titles
'titles' => $titles,
'already_favorite' => $already_favorite
)
)
)

View File

@ -621,6 +621,11 @@ class TableStructureController extends TableController
&& ($partitionDetails['partition_by'] == 'RANGE'
|| $partitionDetails['partition_by'] == 'LIST');
// Values are specified only for LIST and RANGE type partitions
$partitionDetails['value_enabled'] = isset($partitionDetails['partition_by'])
&& ($partitionDetails['partition_by'] == 'RANGE'
|| $partitionDetails['partition_by'] == 'LIST');
$partitionDetails['partitions'] = array();
for ($i = 0; $i < intval($partitionDetails['partition_count']); $i++) {
@ -664,15 +669,6 @@ class TableStructureController extends TableController
$partition['name'] = 'p' . $i;
$partition['prefix'] = 'partitions[' . $i . ']';
// Values are specified only for LIST and RANGE type partitions
$partition['value_enabled'] = isset($partitionDetails['partition_by'])
&& ($partitionDetails['partition_by'] == 'RANGE'
|| $partitionDetails['partition_by'] == 'LIST');
if (! $partition['value_enabled']) {
$partition['value_type'] = '';
$partition['value'] = '';
}
if ($partitionDetails['subpartition_count'] > 1) {
$partition['subpartition_count'] = $partitionDetails['subpartition_count'];
$partition['subpartitions'] = array();

View File

@ -10,89 +10,73 @@
*
* @package SqlParser
*/
namespace SqlParser;
namespace {
require_once 'common.php';
if (!function_exists('__')) {
/**
* Translates the given string.
*
* @param string $str String to be translated.
*
* @return string
*/
function __($str)
{
return $str;
}
}
}
namespace SqlParser {
/**
* A component (of a statement) is a part of a statement that is common to
* multiple query types.
*
* @category Components
* @package SqlParser
* @author Dan Ungureanu <udan1107@gmail.com>
* @license http://opensource.org/licenses/GPL-2.0 GNU Public License
*/
abstract class Component
{
/**
* A component (of a statement) is a part of a statement that is common to
* multiple query types.
* Parses the tokens contained in the given list in the context of the given
* parser.
*
* @category Components
* @package SqlParser
* @author Dan Ungureanu <udan1107@gmail.com>
* @license http://opensource.org/licenses/GPL-2.0 GNU Public License
* @param Parser $parser The parser that serves as context.
* @param TokensList $list The list of tokens that are being parsed.
* @param array $options Parameters for parsing.
*
* @throws \Exception Not implemented yet.
*
* @return mixed
*/
abstract class Component
public static function parse(
Parser $parser,
TokensList $list,
array $options = array()
) {
// This method should be abstract, but it can't be both static and
// abstract.
throw new \Exception(\__('Not implemented yet.'));
}
/**
* Builds the string representation of a component of this type.
*
* In other words, this function represents the inverse function of
* `static::parse`.
*
* @param mixed $component The component to be built.
* @param array $options Parameters for building.
*
* @throws \Exception Not implemented yet.
*
* @return string
*/
public static function build($component, array $options = array())
{
// This method should be abstract, but it can't be both static and
// abstract.
throw new \Exception(\__('Not implemented yet.'));
}
/**
* Parses the tokens contained in the given list in the context of the given
* parser.
*
* @param Parser $parser The parser that serves as context.
* @param TokensList $list The list of tokens that are being parsed.
* @param array $options Parameters for parsing.
*
* @throws \Exception Not implemented yet.
*
* @return mixed
*/
public static function parse(
Parser $parser, TokensList $list, array $options = array()
) {
// This method should be abstract, but it can't be both static and
// abstract.
throw new \Exception(\__('Not implemented yet.'));
}
/**
* Builds the string representation of a component of this type.
*
* In other words, this function represents the inverse function of
* `static::parse`.
*
* @param mixed $component The component to be built.
* @param array $options Parameters for building.
*
* @throws \Exception Not implemented yet.
*
* @return string
*/
public static function build($component, array $options = array())
{
// This method should be abstract, but it can't be both static and
// abstract.
throw new \Exception(\__('Not implemented yet.'));
}
/**
* Builds the string representation of a component of this type.
*
* @see static::build
*
* @return string
*/
public function __toString()
{
return static::build($this);
}
/**
* Builds the string representation of a component of this type.
*
* @see static::build
*
* @return string
*/
public function __toString()
{
return static::build($this);
}
}

View File

@ -137,7 +137,6 @@ class AlterOperation extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -58,7 +58,6 @@ class Array2d extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -56,7 +56,7 @@ class ArrayObj extends Component
* @param TokensList $list The list of tokens that are being parsed.
* @param array $options Parameters for parsing.
*
* @return mixed
* @return ArrayObj|Component[]
*/
public static function parse(Parser $parser, TokensList $list, array $options = array())
{
@ -79,7 +79,6 @@ class ArrayObj extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -43,6 +43,7 @@ class Condition extends Component
'IN' => 1,
'IS' => 1,
'LIKE' => 1,
'NOT IN' => 1,
'NOT NULL' => 1,
'NULL' => 1,
'OR' => 1,
@ -111,7 +112,6 @@ class Condition extends Component
$betweenBefore = false;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -126,8 +126,12 @@ class CreateDefinition extends Component
* @param bool $isConstraint Whether this field is a constraint or not.
* @param Reference $references References.
*/
public function __construct($name = null, $options = null, $type = null,
$isConstraint = false, $references = null
public function __construct(
$name = null,
$options = null,
$type = null,
$isConstraint = false,
$references = null
) {
$this->name = $name;
$this->options = $options;
@ -178,7 +182,6 @@ class CreateDefinition extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -75,7 +75,9 @@ class DataType extends Component
* @param array $parameters The parameters (size or possible values).
* @param OptionsArray $options The options of this data type.
*/
public function __construct($name = null, array $parameters = array(),
public function __construct(
$name = null,
array $parameters = array(),
$options = null
) {
$this->name = $name;
@ -108,7 +110,6 @@ class DataType extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -160,7 +160,6 @@ class Expression extends Component
$prev = null;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*
@ -274,7 +273,6 @@ class Expression extends Component
// field should be skipped; used to parse table names).
$field = (!empty($options['skipColumn'])) ? 'table' : 'column';
if (!empty($ret->$field)) {
// No alias is expected.
if (!empty($options['noAlias'])) {
break;

View File

@ -51,7 +51,6 @@ class ExpressionArray extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -80,7 +80,6 @@ class FunctionCall extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -74,7 +74,6 @@ class IntoKeyword extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -35,7 +35,9 @@ class JoinKeyword extends Component
'INNER JOIN' => 'INNER',
'JOIN' => 'JOIN',
'LEFT JOIN' => 'LEFT',
'LEFT OUTER JOIN' => 'LEFT',
'RIGHT JOIN' => 'RIGHT',
'RIGHT OUTER JOIN' => 'RIGHT',
);
/**
@ -98,7 +100,6 @@ class JoinKeyword extends Component
}
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*
@ -132,7 +133,7 @@ class JoinKeyword extends Component
if (($token->type === Token::TYPE_KEYWORD) && ($token->value === 'ON')) {
$state = 3;
}
} else if ($state === 3) {
} elseif ($state === 3) {
$expr->on = Condition::parse($parser, $list);
$ret[] = $expr;
$expr = new JoinKeyword();
@ -160,7 +161,7 @@ class JoinKeyword extends Component
$ret = array();
foreach ($component as $c) {
$ret[] = (($c->type === 'JOIN') ? 'JOIN ' : ($c->type . ' JOIN '))
. $c->expr . ' ON ' . Condition::build($c->on);
. $c->expr . ' ON ' . Condition::build($c->on);
}
return implode(' ', $ret);
}

View File

@ -75,8 +75,11 @@ class Key extends Component
* @param string $type The type of this key.
* @param OptionsArray $options The options of this key.
*/
public function __construct($name = null, array $columns = array(),
$type = null, $options = null
public function __construct(
$name = null,
array $columns = array(),
$type = null,
$options = null
) {
$this->name = $name;
$this->columns = $columns;
@ -119,7 +122,6 @@ class Key extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -65,7 +65,6 @@ class Limit extends Component
$offset = false;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -99,7 +99,6 @@ class OptionsArray extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -79,7 +79,6 @@ class OrderKeyword extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -80,7 +80,6 @@ class ParameterDefinition extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -36,8 +36,8 @@ class PartitionDefinition extends Component
* @var array
*/
public static $OPTIONS = array(
'ENGINE' => array(1, 'var'),
'STORAGE ENGINE' => array(1, 'var'),
'ENGINE' => array(1, 'var'),
'COMMENT' => array(2, 'var'),
'DATA DIRECTORY' => array(3, 'var'),
'INDEX DIRECTORY' => array(4, 'var'),
@ -108,7 +108,6 @@ class PartitionDefinition extends Component
* 0 -------------[ PARTITION | SUBPARTITION ]------------> 1
*
* 1 -----------------------[ name ]----------------------> 2
* 1 -----------------------[ name ]----------------------> 5
*
* 2 ----------------------[ VALUES ]---------------------> 3
*
@ -126,7 +125,6 @@ class PartitionDefinition extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*
@ -149,12 +147,16 @@ class PartitionDefinition extends Component
$state = 1;
} elseif ($state === 1) {
$ret->name = $token->value;
// Get next token
// Looking ahead for a 'VALUES' keyword.
$idx = $list->idx;
$list->getNext();
$nextToken = $list->getNext();
$nextToken = $list->getNext();
--$list->idx; --$list->idx; // Reset index
$isValue = ($nextToken->type === Token::TYPE_KEYWORD) && ($nextToken->value === 'VALUES');
$state = $isValue ? 2 : 5;
$list->idx = $idx;
$state = ($nextToken->type === Token::TYPE_KEYWORD)
&& ($nextToken->value === 'VALUES')
? 2 : 5;
} elseif ($state === 2) {
$state = 3;
} elseif ($state === 3) {
@ -208,14 +210,15 @@ class PartitionDefinition extends Component
return "(\n" . implode(",\n", $component) . "\n)";
} else {
if ($component->isSubpartition) {
return 'SUBPARTITION ' . $component->name . ' ' . $component->options;
return trim('SUBPARTITION ' . $component->name . ' ' . $component->options);
} else {
$subpartitions = empty($component->subpartitions)
? '' : ' ' . PartitionDefinition::build($component->subpartitions);
return 'PARTITION ' . $component->name
. (empty($component->type)
? '' : ' VALUES ' . $component->type . ' ' . $component->expr)
. ' ' .$component->options . $subpartitions;
return trim(
'PARTITION ' . $component->name
. (empty($component->type) ? '' : ' VALUES ' . $component->type . ' ' . $component->expr)
. $component->options . $subpartitions
);
}
}
}

View File

@ -99,7 +99,6 @@ class Reference extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -71,7 +71,6 @@ class RenameOperation extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -67,7 +67,6 @@ class SetOperation extends Component
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*

View File

@ -464,7 +464,11 @@ abstract class Context
// If it didn't work, we are looking for a new one and skipping
// over to the next generation that will try the new context.
$context = preg_replace(
'/[1-9](0*)$/', '0$1', $context, -1, $count
'/[1-9](0*)$/',
'0$1',
$context,
-1,
$count
);
continue;
}

View File

@ -155,15 +155,15 @@ class ContextMySql50000 extends Context
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7,
'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
'START TRANSACTION' => 7,
'SELECT TRANSACTION' => 7,
'DEFAULT CHARACTER SET' => 7,
'WITH CONSISTENT SNAPSHOT' => 7,
'XML' => 9,
'ENUM' => 9, 'TEXT' => 9,
'ENUM' => 9, 'JSON' => 9, 'TEXT' => 9,
'ARRAY' => 9,
'SERIAL' => 9,
'BOOLEAN' => 9,

View File

@ -168,15 +168,15 @@ class ContextMySql50100 extends Context
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7,
'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
'START TRANSACTION' => 7,
'SELECT TRANSACTION' => 7,
'DEFAULT CHARACTER SET' => 7,
'WITH CONSISTENT SNAPSHOT' => 7,
'XML' => 9,
'ENUM' => 9, 'TEXT' => 9,
'ENUM' => 9, 'JSON' => 9, 'TEXT' => 9,
'ARRAY' => 9,
'SERIAL' => 9,
'BOOLEAN' => 9,

View File

@ -173,15 +173,15 @@ class ContextMySql50500 extends Context
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7,
'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
'START TRANSACTION' => 7,
'SELECT TRANSACTION' => 7,
'DEFAULT CHARACTER SET' => 7,
'WITH CONSISTENT SNAPSHOT' => 7,
'XML' => 9,
'ENUM' => 9, 'TEXT' => 9,
'ENUM' => 9, 'JSON' => 9, 'TEXT' => 9,
'ARRAY' => 9,
'SERIAL' => 9,
'BOOLEAN' => 9,

View File

@ -178,15 +178,15 @@ class ContextMySql50600 extends Context
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7,
'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
'START TRANSACTION' => 7,
'SELECT TRANSACTION' => 7,
'DEFAULT CHARACTER SET' => 7,
'WITH CONSISTENT SNAPSHOT' => 7,
'XML' => 9,
'ENUM' => 9, 'TEXT' => 9,
'ENUM' => 9, 'JSON' => 9, 'TEXT' => 9,
'ARRAY' => 9,
'SERIAL' => 9,
'BOOLEAN' => 9,

View File

@ -186,15 +186,15 @@ class ContextMySql50700 extends Context
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7,
'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
'START TRANSACTION' => 7,
'SELECT TRANSACTION' => 7,
'DEFAULT CHARACTER SET' => 7,
'WITH CONSISTENT SNAPSHOT' => 7,
'XML' => 9,
'ENUM' => 9, 'TEXT' => 9,
'ENUM' => 9, 'JSON' => 9, 'TEXT' => 9,
'ARRAY' => 9,
'SERIAL' => 9,
'BOOLEAN' => 9,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -109,7 +109,6 @@ abstract class Statement
$query = '';
foreach (static::$CLAUSES as $clause) {
/**
* The name of the clause.
*
@ -190,7 +189,6 @@ abstract class Statement
$parsedOptions = empty(static::$OPTIONS);
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*
@ -247,7 +245,8 @@ abstract class Statement
) {
if (!empty($parsedClauses[$token->value])) {
$parser->error(
__('This type of clause was previously parsed.'), $token
__('This type of clause was previously parsed.'),
$token
);
break;
}

View File

@ -73,7 +73,9 @@ class AlterStatement extends Statement
// Parsing affected table.
$this->table = Expression::parse(
$parser, $list, array(
$parser,
$list,
array(
'noAlias' => true,
'noBrackets' => true,
)
@ -94,7 +96,6 @@ class AlterStatement extends Statement
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*
@ -115,7 +116,7 @@ class AlterStatement extends Statement
if ($state === 0) {
$this->altered[] = AlterOperation::parse($parser, $list);
$state = 1;
} else if ($state === 1) {
} elseif ($state === 1) {
if (($token->type === Token::TYPE_OPERATOR) && ($token->value === ',')) {
$state = 0;
}

View File

@ -395,7 +395,6 @@ class CreateStatement extends Statement
* Handles partitions.
*/
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*
@ -428,7 +427,6 @@ class CreateStatement extends Statement
--$list->idx; // `getNextOfType` also advances one position.
$this->subpartitionsNum = $token->value;
} elseif (!empty($field)) {
/*
* Handling the content of `PARTITION BY` and `SUBPARTITION BY`.
*/
@ -499,7 +497,7 @@ class CreateStatement extends Statement
$token = $list->tokens[$list->idx];
$this->body[] = $token;
}
} else if ($this->options->has('VIEW')) {
} elseif ($this->options->has('VIEW')) {
$token = $list->getNext(); // Skipping whitespaces and comments.
// Parsing columns list.
@ -518,7 +516,7 @@ class CreateStatement extends Statement
}
$this->body[] = $token;
}
} else if ($this->options->has('TRIGGER')) {
} elseif ($this->options->has('TRIGGER')) {
// Parsing the time and the event.
$this->entityOptions = OptionsArray::parse(
$parser,

View File

@ -219,59 +219,59 @@ class Token
public function extract()
{
switch ($this->type) {
case Token::TYPE_KEYWORD:
if (!($this->flags & Token::FLAG_KEYWORD_RESERVED)) {
// Unreserved keywords should stay the way they are because they
// might represent field names.
return $this->token;
}
return strtoupper($this->token);
case Token::TYPE_WHITESPACE:
return ' ';
case Token::TYPE_BOOL:
return strtoupper($this->token) === 'TRUE';
case Token::TYPE_NUMBER:
$ret = str_replace('--', '', $this->token); // e.g. ---42 === -42
if ($this->flags & Token::FLAG_NUMBER_HEX) {
if ($this->flags & Token::FLAG_NUMBER_NEGATIVE) {
$ret = str_replace('-', '', $this->token);
sscanf($ret, "%x", $ret);
$ret = -$ret;
} else {
sscanf($ret, "%x", $ret);
case Token::TYPE_KEYWORD:
if (!($this->flags & Token::FLAG_KEYWORD_RESERVED)) {
// Unreserved keywords should stay the way they are because they
// might represent field names.
return $this->token;
}
} elseif (($this->flags & Token::FLAG_NUMBER_APPROXIMATE)
return strtoupper($this->token);
case Token::TYPE_WHITESPACE:
return ' ';
case Token::TYPE_BOOL:
return strtoupper($this->token) === 'TRUE';
case Token::TYPE_NUMBER:
$ret = str_replace('--', '', $this->token); // e.g. ---42 === -42
if ($this->flags & Token::FLAG_NUMBER_HEX) {
if ($this->flags & Token::FLAG_NUMBER_NEGATIVE) {
$ret = str_replace('-', '', $this->token);
sscanf($ret, "%x", $ret);
$ret = -$ret;
} else {
sscanf($ret, "%x", $ret);
}
} elseif (($this->flags & Token::FLAG_NUMBER_APPROXIMATE)
|| ($this->flags & Token::FLAG_NUMBER_FLOAT)
) {
sscanf($ret, "%f", $ret);
} else {
sscanf($ret, "%d", $ret);
}
return $ret;
case Token::TYPE_STRING:
$quote = $this->token[0];
$str = str_replace($quote . $quote, $quote, $this->token);
return mb_substr($str, 1, -1, 'UTF-8'); // trims quotes
case Token::TYPE_SYMBOL:
$str = $this->token;
if ((isset($str[0])) && ($str[0] === '@')) {
// `mb_strlen($str)` must be used instead of `null` because
// in PHP 5.3- the `null` parameter isn't handled correctly.
$str = mb_substr(
$str,
((!empty($str[1])) && ($str[1] === '@')) ? 2 : 1,
mb_strlen($str),
'UTF-8'
);
}
if ((isset($str[0])) && (($str[0] === '`')
) {
sscanf($ret, "%f", $ret);
} else {
sscanf($ret, "%d", $ret);
}
return $ret;
case Token::TYPE_STRING:
$quote = $this->token[0];
$str = str_replace($quote . $quote, $quote, $this->token);
return mb_substr($str, 1, -1, 'UTF-8'); // trims quotes
case Token::TYPE_SYMBOL:
$str = $this->token;
if ((isset($str[0])) && ($str[0] === '@')) {
// `mb_strlen($str)` must be used instead of `null` because
// in PHP 5.3- the `null` parameter isn't handled correctly.
$str = mb_substr(
$str,
((!empty($str[1])) && ($str[1] === '@')) ? 2 : 1,
mb_strlen($str),
'UTF-8'
);
}
if ((isset($str[0])) && (($str[0] === '`')
|| ($str[0] === '"') || ($str[0] === '\''))
) {
$quote = $str[0];
$str = str_replace($quote . $quote, $quote, $str);
$str = mb_substr($str, 1, -1, 'UTF-8');
}
return $str;
) {
$quote = $str[0];
$str = str_replace($quote . $quote, $quote, $str);
$str = mb_substr($str, 1, -1, 'UTF-8');
}
return $str;
}
return $this->token;
}

View File

@ -186,7 +186,6 @@ class BufferedQuery
$loopLen = $end ? $len : $len - 16;
for (; $i < $loopLen; ++$i) {
/*
* Handling special parses statuses.
*/
@ -285,7 +284,6 @@ class BufferedQuery
&& (($this->query[$i + 8] === 'R') || ($this->query[$i + 8] === 'r'))
&& (Context::isWhitespace($this->query[$i + 9]))
) {
// Saving the current index to be able to revert any parsing
// done in this block.
$iBak = $i;
@ -307,14 +305,12 @@ class BufferedQuery
&& ((($i < $len) && (Context::isWhitespace($this->query[$i])))
|| (($i === $len) && ($end)))
) {
// Saving the delimiter.
$this->setDelimiter($delimiter);
// Whether this statement should be returned or not.
$ret = '';
if (!empty($this->options['parse_delimiter'])) {
// Appending the `DELIMITER` statement that was just
// found to the current statement.
$ret = trim(
@ -351,7 +347,6 @@ class BufferedQuery
&& (($this->delimiterLen === 1)
|| (substr($this->query, $i, $this->delimiterLen) === $this->delimiter))
) {
// Saving the statement that just ended.
$ret = $this->current;

View File

@ -78,14 +78,20 @@ class Error
* @return array
*/
public static function format(
$errors, $format = '#%1$d: %2$s (near "%4$s" at position %5$d)'
$errors,
$format = '#%1$d: %2$s (near "%4$s" at position %5$d)'
) {
$ret = array();
$i = 0;
foreach ($errors as $key => $err) {
$ret[$key] = sprintf(
$format, ++$i, $err[0], $err[1], $err[2], $err[3]
$format,
++$i,
$err[0],
$err[1],
$err[2],
$err[3]
);
}

View File

@ -257,7 +257,6 @@ class Formatter
// `$prev` and `$curr` which store two consecutive tokens.
// Actually, at every iteration the previous token is being used.
for ($list->idx = 0; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
*
@ -266,11 +265,9 @@ class Formatter
$curr = $list->tokens[$list->idx];
if ($curr->type === Token::TYPE_WHITESPACE) {
// Whitespaces are skipped because the formatter adds its own.
continue;
} elseif ($curr->type === Token::TYPE_COMMENT) {
// Whether the comments should be parsed.
if (!empty($this->options['remove_comments'])) {
continue;
@ -297,7 +294,6 @@ class Formatter
// Checking if pointers were initialized.
if ($prev !== null) {
// Checking if a new clause started.
if (static::isClause($prev) !== false) {
$lastClause = $prev->value;
@ -428,7 +424,6 @@ class Formatter
if (($token->type === $format['type'])
&& (($token->flags & $format['flags']) === $format['flags'])
) {
// Running transformation function.
if (!empty($format['function'])) {
$func = $format['function'];

View File

@ -0,0 +1,175 @@
<?php
/**
* Token utilities.
*
* @package SqlParser
* @subpackage Utils
*/
namespace SqlParser\Utils;
use SqlParser\Lexer;
use SqlParser\Token;
use SqlParser\TokensList;
/**
* Token utilities.
*
* @category Token
* @package SqlParser
* @subpackage Utils
* @author Dan Ungureanu <udan1107@gmail.com>
* @license http://opensource.org/licenses/GPL-2.0 GNU Public License
*/
class Tokens
{
/**
* Checks if a pattern is a match for the specified token.
*
* @param Token $token The token to be matched.
* @param array $pattern The pattern to be matches.
*
* @return bool
*/
public static function match(Token $token, array $pattern)
{
// Token.
if ((isset($pattern['token']))
&& ($pattern['token'] !== $token->token)
) {
return false;
}
// Value.
if ((isset($pattern['value']))
&& ($pattern['value'] !== $token->value)
) {
return false;
}
if ((isset($pattern['value_str']))
&& (strcasecmp($pattern['value_str'], $token->value))
) {
return false;
}
// Type.
if ((isset($pattern['type']))
&& ($pattern['type'] !== $token->type)
) {
return false;
}
// Flags.
if ((isset($pattern['flags']))
&& (($pattern['flags'] & $token->flags) === 0)
) {
return false;
}
return true;
}
public static function replaceTokens($list, array $find, array $replace)
{
/**
* Whether the first parameter is a list.
*
* @var bool
*/
$isList = $list instanceof TokensList;
// Parsing the tokens.
if (!$isList) {
$list = Lexer::getTokens($list);
}
/**
* The list to be returned.
*
* @var array
*/
$newList = array();
/**
* The length of the find pattern is calculated only once.
*
* @var int
*/
$findCount = count($find);
/**
* The starting index of the pattern.
*
* @var int
*/
$i = 0;
while ($i < $list->count) {
// A sequence may not start with a comment.
if ($list->tokens[$i]->type === Token::TYPE_COMMENT) {
$newList[] = $list->tokens[$i];
++$i;
continue;
}
/**
* The index used to parse `$list->tokens`.
*
* This index might be running faster than `$k` because some tokens
* are skipped.
*
* @var int
*/
$j = $i;
/**
* The index used to parse `$find`.
*
* This index might be running slower than `$j` because some tokens
* are skipped.
*
* @var int
*/
$k = 0;
// Checking if the next tokens match the pattern described.
while (($j < $list->count) && ($k < $findCount)) {
// Comments are being skipped.
if ($list->tokens[$j]->type === Token::TYPE_COMMENT) {
++$j;
}
if (!static::match($list->tokens[$j], $find[$k])) {
// This token does not match the pattern.
break;
}
// Going to next token and segment of find pattern.
++$j;
++$k;
}
// Checking if the sequence was found.
if ($k === $findCount) {
// Inserting new tokens.
foreach ($replace as $token) {
$newList[] = $token;
}
// Skipping next `$findCount` tokens.
$i = $j;
} else {
// Adding the same token.
$newList[] = $list->tokens[$i];
++$i;
}
}
return $isList ?
new TokensList($newList) : TokensList::build($newList);
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* Defines common elements used by the library.
*
* @package SqlParser
*/
if (!function_exists('__')) {
/**
* Translates the given string.
*
* @param string $str String to be translated.
*
* @return string
*/
function __($str)
{
return $str;
}
}

View File

@ -22,6 +22,11 @@ if (!isset($partitionDetails)) {
&& isset($_REQUEST['partition_by'])
&& ($_REQUEST['partition_by'] == 'RANGE' || $_REQUEST['partition_by'] == 'LIST');
// Values are specified only for LIST and RANGE type partitions
$partitionDetails['value_enabled'] = isset($_REQUEST['partition_by'])
&& ($_REQUEST['partition_by'] == 'RANGE'
|| $_REQUEST['partition_by'] == 'LIST');
if (PMA_isValid($_REQUEST['partition_count'], 'numeric')
&& $_REQUEST['partition_count'] > 1
) { // Has partitions
@ -51,14 +56,20 @@ if (!isset($partitionDetails)) {
$partition['name'] = 'p' . $i;
$partition['prefix'] = 'partitions[' . $i . ']';
// Values are specified only for LIST and RANGE type partitions
$partition['value_enabled'] = isset($_REQUEST['partition_by'])
&& ($_REQUEST['partition_by'] == 'RANGE'
|| $_REQUEST['partition_by'] == 'LIST');
if (! $partition['value_enabled']) {
if (! isset($partition['value_type'])) { // Changing from HASH/KEY to RANGE/LIST
$partition['value_type'] = '';
$partition['value'] = '';
}
if (! isset($partition['engine'])) { // When removing subpartitioning
$partition['engine'] = '';
$partition['comment'] = '';
$partition['data_directory'] = '';
$partition['index_directory'] = '';
$partition['max_rows'] = '';
$partition['min_rows'] = '';
$partition['tablespace'] = '';
$partition['node_group'] = '';
}
if (PMA_isValid($_REQUEST['subpartition_count'], 'numeric')
&& $_REQUEST['subpartition_count'] > 1

1050
po/af.po

File diff suppressed because it is too large Load Diff

1035
po/ar.po

File diff suppressed because it is too large Load Diff

1041
po/az.po

File diff suppressed because it is too large Load Diff

1039
po/be.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1035
po/bg.po

File diff suppressed because it is too large Load Diff

1035
po/bn.po

File diff suppressed because it is too large Load Diff

1041
po/br.po

File diff suppressed because it is too large Load Diff

1045
po/brx.po

File diff suppressed because it is too large Load Diff

1037
po/bs.po

File diff suppressed because it is too large Load Diff

1035
po/ca.po

File diff suppressed because it is too large Load Diff

1041
po/ckb.po

File diff suppressed because it is too large Load Diff

1035
po/cs.po

File diff suppressed because it is too large Load Diff

1039
po/cy.po

File diff suppressed because it is too large Load Diff

1035
po/da.po

File diff suppressed because it is too large Load Diff

1036
po/de.po

File diff suppressed because it is too large Load Diff

1062
po/el.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1045
po/eo.po

File diff suppressed because it is too large Load Diff

1035
po/es.po

File diff suppressed because it is too large Load Diff

1060
po/et.po

File diff suppressed because it is too large Load Diff

1037
po/eu.po

File diff suppressed because it is too large Load Diff

1045
po/fa.po

File diff suppressed because it is too large Load Diff

1039
po/fi.po

File diff suppressed because it is too large Load Diff

1038
po/fr.po

File diff suppressed because it is too large Load Diff

1043
po/fy.po

File diff suppressed because it is too large Load Diff

1035
po/gl.po

File diff suppressed because it is too large Load Diff

1039
po/he.po

File diff suppressed because it is too large Load Diff

1045
po/hi.po

File diff suppressed because it is too large Load Diff

1039
po/hr.po

File diff suppressed because it is too large Load Diff

1035
po/hu.po

File diff suppressed because it is too large Load Diff

1040
po/hy.po

File diff suppressed because it is too large Load Diff

1060
po/ia.po

File diff suppressed because it is too large Load Diff

1035
po/id.po

File diff suppressed because it is too large Load Diff

1040
po/it.po

File diff suppressed because it is too large Load Diff

1035
po/ja.po

File diff suppressed because it is too large Load Diff

1045
po/ka.po

File diff suppressed because it is too large Load Diff

1047
po/kk.po

File diff suppressed because it is too large Load Diff

1045
po/km.po

File diff suppressed because it is too large Load Diff

1047
po/kn.po

File diff suppressed because it is too large Load Diff

1041
po/ko.po

File diff suppressed because it is too large Load Diff

1046
po/ksh.po

File diff suppressed because it is too large Load Diff

1041
po/ky.po

File diff suppressed because it is too large Load Diff

1045
po/li.po

File diff suppressed because it is too large Load Diff

1035
po/lt.po

File diff suppressed because it is too large Load Diff

1037
po/lv.po

File diff suppressed because it is too large Load Diff

1037
po/mk.po

File diff suppressed because it is too large Load Diff

1049
po/ml.po

File diff suppressed because it is too large Load Diff

1039
po/mn.po

File diff suppressed because it is too large Load Diff

1044
po/ms.po

File diff suppressed because it is too large Load Diff

1045
po/nb.po

File diff suppressed because it is too large Load Diff

1047
po/ne.po

File diff suppressed because it is too large Load Diff

1035
po/nl.po

File diff suppressed because it is too large Load Diff

1047
po/pa.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1035
po/pl.po

File diff suppressed because it is too large Load Diff

1043
po/pt.po

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More