Merge remote-tracking branch 'origin/master' into useNamespaces_master
This commit is contained in:
commit
bd0d2b79db
@ -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
|
||||
|
||||
@ -442,11 +442,6 @@ class TypesMySQL extends Types
|
||||
'MPolyFromWKB',
|
||||
);
|
||||
|
||||
case 'JSON':
|
||||
return array(
|
||||
'JSON_ARRAY',
|
||||
'JSON_OBJECT',
|
||||
);
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
@ -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
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,7 +137,6 @@ class AlterOperation extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -58,7 +58,6 @@ class Array2d extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -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.
|
||||
*
|
||||
|
||||
@ -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.
|
||||
*
|
||||
|
||||
@ -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.
|
||||
*
|
||||
|
||||
@ -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.
|
||||
*
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -51,7 +51,6 @@ class ExpressionArray extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -80,7 +80,6 @@ class FunctionCall extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -74,7 +74,6 @@ class IntoKeyword extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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.
|
||||
*
|
||||
|
||||
@ -65,7 +65,6 @@ class Limit extends Component
|
||||
$offset = false;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -99,7 +99,6 @@ class OptionsArray extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -79,7 +79,6 @@ class OrderKeyword extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -80,7 +80,6 @@ class ParameterDefinition extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,7 +99,6 @@ class Reference extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -71,7 +71,6 @@ class RenameOperation extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -67,7 +67,6 @@ class SetOperation extends Component
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
*
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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'];
|
||||
|
||||
175
libraries/sql-parser/src/Utils/Tokens.php
Normal file
175
libraries/sql-parser/src/Utils/Tokens.php
Normal 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);
|
||||
}
|
||||
}
|
||||
21
libraries/sql-parser/src/common.php
Normal file
21
libraries/sql-parser/src/common.php
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
1039
po/be@latin.po
1039
po/be@latin.po
File diff suppressed because it is too large
Load Diff
1035
po/en_GB.po
1035
po/en_GB.po
File diff suppressed because it is too large
Load Diff
1045
po/phpmyadmin.pot
1045
po/phpmyadmin.pot
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
Loading…
Reference in New Issue
Block a user