Merge branch 'rfe1517'
This commit is contained in:
commit
ee1b179fcb
@ -2308,6 +2308,29 @@ class PMA_Table
|
||||
}
|
||||
$columns = $this->_dbi->fetchResult($sql, 'Field', 'Expression');
|
||||
return $columns;
|
||||
} else {
|
||||
$createTable = $this->showCreate();
|
||||
if ($createTable) {
|
||||
$parser = new SqlParser\Parser($createTable);
|
||||
/**
|
||||
* @var CreateStatement $stmt
|
||||
*/
|
||||
$stmt = $parser->statements[0];
|
||||
$fields = SqlParser\Utils\Table::getFields($stmt);
|
||||
if ($column != null) {
|
||||
$expression = isset($fields[$column]['expr']) ?
|
||||
substr($fields[$column]['expr'], 1, -1) : '';
|
||||
return array($column => $expression);
|
||||
}
|
||||
|
||||
$ret = array();
|
||||
foreach ($fields as $field => $options) {
|
||||
if (isset($options['expr'])) {
|
||||
$ret[$field] = substr($options['expr'], 1, -1);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2316,7 +2339,7 @@ class PMA_Table
|
||||
*/
|
||||
public function showCreate()
|
||||
{
|
||||
return $GLOBALS['dbi']->fetchValue(
|
||||
return $this->_dbi->fetchValue(
|
||||
'SHOW CREATE TABLE ' . PMA_Util::backquote($this->_db_name) . '.'
|
||||
. PMA_Util::backquote($this->_name),
|
||||
0, 1
|
||||
|
||||
@ -4839,7 +4839,8 @@ class PMA_Util
|
||||
public static function isVirtualColumnsSupported()
|
||||
{
|
||||
$serverType = self::getServerType();
|
||||
return $serverType == 'MySQL' && PMA_MYSQL_INT_VERSION > 50705;
|
||||
return $serverType == 'MySQL' && PMA_MYSQL_INT_VERSION >= 50705
|
||||
|| ($serverType == 'MariaDB' && PMA_MYSQL_INT_VERSION >= 50200);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -57,4 +57,16 @@ abstract class Component
|
||||
// abstract.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the string representation of a component of this type.
|
||||
*
|
||||
* @see static::build
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return static::build($this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,7 +205,7 @@ class Expression extends Component
|
||||
// We don't check to see if `$prev` is `true` (open bracket
|
||||
// was found before) because the brackets count is one (the
|
||||
// only bracket we found is this one).
|
||||
if (($brackets === 1) && (empty($ret->function)) && ($prev !== null) && ($prev !== true)) {
|
||||
if ((empty($ret->function)) && ($prev !== null) && ($prev !== true)) {
|
||||
// A function name was previously found and now an open
|
||||
// bracket, so this is a function call.
|
||||
$ret->function = $prev;
|
||||
@ -213,7 +213,15 @@ class Expression extends Component
|
||||
$isExpr = true;
|
||||
} elseif ($token->value === ')') {
|
||||
--$brackets;
|
||||
if ($brackets < 0) {
|
||||
if ($brackets === 0) {
|
||||
if (!empty($options['bracketsDelimited'])) {
|
||||
// The current token is the last brackets, the next
|
||||
// one will be outside.
|
||||
$ret->expr .= $token->token;
|
||||
++$list->idx;
|
||||
break;
|
||||
}
|
||||
} elseif ($brackets < 0) {
|
||||
$parser->error('Unexpected bracket.', $token);
|
||||
$brackets = 0;
|
||||
}
|
||||
@ -268,11 +276,12 @@ class Expression extends Component
|
||||
} else {
|
||||
// Parsing aliases without `AS` keyword.
|
||||
// Example: SELECT 'foo' `bar`
|
||||
if ($brackets === 0) {
|
||||
if (($brackets === 0) && (empty($options['noAlias']))) {
|
||||
if (($token->type === Token::TYPE_NONE) || ($token->type === Token::TYPE_STRING)
|
||||
|| (($token->type === Token::TYPE_SYMBOL) && ($token->flags & Token::FLAG_SYMBOL_BACKTICK))
|
||||
) {
|
||||
$ret->alias = $token->value;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +47,14 @@ class FieldDefinition extends Component
|
||||
'COMMENT' => array(5, 'var'),
|
||||
'COLUMN_FORMAT' => array(6, 'var'),
|
||||
'ON UPDATE' => array(7, 'var'),
|
||||
|
||||
// MariaDB options.
|
||||
'GENERATED ALWAYS' => 1,
|
||||
'AS' => array(2, 'expr', array('bracketsDelimited' => true)),
|
||||
'VIRTUAL' => 3,
|
||||
'PERSISTENT' => 3,
|
||||
// 'UNIQUE' => 4, // common
|
||||
// 'UNIQUE KEY' => 4, // common
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@ -72,8 +72,27 @@ class OptionsArray extends Component
|
||||
*/
|
||||
$lastOptionId = 0;
|
||||
|
||||
/**
|
||||
* Counts brackets.
|
||||
* @var int $brackets
|
||||
*/
|
||||
$brackets = 0;
|
||||
|
||||
/**
|
||||
* The state of the parser.
|
||||
*
|
||||
* Below are the states of the parser.
|
||||
*
|
||||
* 0 ---------------------[ option ]----------------------> 1
|
||||
*
|
||||
* 1 -------------------[ = (optional) ]------------------> 2
|
||||
*
|
||||
* 2 ----------------------[ value ]----------------------> 0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
$state = 0;
|
||||
|
||||
for (; $list->idx < $list->count; ++$list->idx) {
|
||||
/**
|
||||
* Token parsed at this moment.
|
||||
@ -86,23 +105,36 @@ class OptionsArray extends Component
|
||||
break;
|
||||
}
|
||||
|
||||
// Skipping whitespaces and comments.
|
||||
if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
|
||||
// Skipping comments.
|
||||
if ($token->type === Token::TYPE_COMMENT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skipping whitespace if not parsing value.
|
||||
if (($token->type === Token::TYPE_WHITESPACE) && ($brackets === 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($lastOption === null) {
|
||||
if (isset($options[strtoupper($token->token)])) {
|
||||
$lastOption = $options[strtoupper($token->token)];
|
||||
$lastOptionId = is_array($lastOption) ? $lastOption[0] : $lastOption;
|
||||
$upper = strtoupper($token->token);
|
||||
if (isset($options[$upper])) {
|
||||
$lastOption = $options[$upper];
|
||||
$lastOptionId = is_array($lastOption) ?
|
||||
$lastOption[0] : $lastOption;
|
||||
$state = 0;
|
||||
|
||||
// Checking for option conflicts.
|
||||
// For example, in `SELECT` statements the keywords `ALL` and `DISTINCT`
|
||||
// conflict and if used together, they produce an invalid query.
|
||||
// Usually, tokens can be identified in the array by the option ID,
|
||||
// but if conflicts occur, a generated option ID is used.
|
||||
// The first pseudo duplicate ID is the maximum value of the real
|
||||
// options (e.g. if there are 5 options, the first fake ID is 6).
|
||||
// For example, in `SELECT` statements the keywords `ALL`
|
||||
// and `DISTINCT` conflict and if used together, they
|
||||
// produce an invalid query.
|
||||
//
|
||||
// Usually, tokens can be identified in the array by the
|
||||
// option ID, but if conflicts occur, a generated option ID
|
||||
// is used.
|
||||
//
|
||||
// The first pseudo duplicate ID is the maximum value of the
|
||||
// real options (e.g. if there are 5 options, the first
|
||||
// fake ID is 6).
|
||||
if (isset($ret->options[$lastOptionId])) {
|
||||
$parser->error('This option conflicts with \'' . $ret->options[$lastOptionId] . '\'.', $token);
|
||||
$lastOptionId = $lastAssignedId++;
|
||||
@ -113,33 +145,81 @@ class OptionsArray extends Component
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($lastOption)) {
|
||||
if (empty($ret->options[$lastOptionId])) {
|
||||
if ($state === 0) {
|
||||
if (!is_array($lastOption)) {
|
||||
// This is a just keyword option without any value.
|
||||
// This is the beginning and the end of it.
|
||||
$ret->options[$lastOptionId] = $token->value;
|
||||
$lastOption = null;
|
||||
$state = 0;
|
||||
} elseif (($lastOption[1] === 'var') || ($lastOption[1] === 'var=')) {
|
||||
// This is a keyword that is followed by a value.
|
||||
// This is only the beginning. The value is parsed in state
|
||||
// 1 and 2. State 1 is used to skip the first equals sign
|
||||
// and state 2 to parse the actual value.
|
||||
$ret->options[$lastOptionId] = array(
|
||||
// @var string The name of the option.
|
||||
'name' => $token->value,
|
||||
// @var bool Whether it contains an equal sign.
|
||||
// This is used by the builder to rebuild it.
|
||||
'equal' => $lastOption[1] === 'var=',
|
||||
// @var string Raw value.
|
||||
'value' => '',
|
||||
// @var string Processed value.
|
||||
'value_' => '',
|
||||
);
|
||||
$state = 1;
|
||||
} elseif ($lastOption[1] === 'expr') {
|
||||
// This is a keyword that is followed by an expression.
|
||||
// The expression is used by the specialized parser.
|
||||
|
||||
// Skipping this option in order to parse the expression.
|
||||
++$list->idx;
|
||||
$ret->options[$lastOptionId] = array(
|
||||
// @var string The name of the option.
|
||||
'name' => $token->value,
|
||||
// @var Expression The parsed expression.
|
||||
'value' => null,
|
||||
);
|
||||
$state = 1;
|
||||
}
|
||||
} elseif ($state === 1) {
|
||||
$state = 2;
|
||||
if ($token->value === '=') {
|
||||
$ret->options[$lastOptionId]['equal'] = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// This is outside the `elseif` group above because the change might
|
||||
// change this iteration.
|
||||
if ($state === 2) {
|
||||
if ($lastOption[1] === 'expr') {
|
||||
$ret->options[$lastOptionId]['value'] = Expression::parse(
|
||||
$parser,
|
||||
$list,
|
||||
empty($lastOption[2]) ? array() : $lastOption[2]
|
||||
);
|
||||
$lastOption = null;
|
||||
$state = 0;
|
||||
} else {
|
||||
if ($token->value !== '=') {
|
||||
if ($token->value === '(') {
|
||||
++$brackets;
|
||||
} elseif ($token->value === ')') {
|
||||
--$brackets;
|
||||
} else {
|
||||
// Raw and processed value.
|
||||
$ret->options[$lastOptionId]['value'] .= $token->token;
|
||||
$ret->options[$lastOptionId]['value_'] .= $token->value;
|
||||
}
|
||||
if ($brackets === 0) {
|
||||
$lastOption = null;
|
||||
}
|
||||
if ($token->token === '(') {
|
||||
++$brackets;
|
||||
} elseif ($token->token === ')') {
|
||||
--$brackets;
|
||||
}
|
||||
|
||||
// Raw value.
|
||||
$ret->options[$lastOptionId]['value'] .= $token->token;
|
||||
|
||||
// Processed value.
|
||||
$ret->options[$lastOptionId]['value_'] .= $token->value;
|
||||
|
||||
// Checking if we finished parsing.
|
||||
if ($brackets === 0) {
|
||||
$lastOption = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ret->options[$lastOptionId] = $token->value;
|
||||
$lastOption = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,12 +241,14 @@ class OptionsArray extends Component
|
||||
}
|
||||
$options = array();
|
||||
foreach ($component->options as $option) {
|
||||
if (is_array($option)) {
|
||||
if (!is_array($option)) {
|
||||
$options[] = $option;
|
||||
} else {
|
||||
$options[] = $option['name']
|
||||
. (!empty($option['equal']) ? '=' : ' ')
|
||||
. $option['value'];
|
||||
} else {
|
||||
$options[] = $option;
|
||||
. ((string) $option['value']);
|
||||
// If `$option['value']` happens to be a component, the magic
|
||||
// method will build it automatically.
|
||||
}
|
||||
}
|
||||
return implode(' ', $options);
|
||||
|
||||
@ -63,7 +63,7 @@ class ContextMySql50000 extends Context
|
||||
'MIGRATE' => 1, 'PARTIAL' => 1, 'PREPARE' => 1, 'PROFILE' => 1, 'RECOVER' => 1,
|
||||
'RESTORE' => 1, 'RETURNS' => 1, 'ROUTINE' => 1, 'SESSION' => 1, 'STORAGE' => 1,
|
||||
'STRIPED' => 1, 'SUBJECT' => 1, 'SUSPEND' => 1, 'UNICODE' => 1, 'UNKNOWN' => 1,
|
||||
'UPGRADE' => 1, 'USE_FRM' => 1,
|
||||
'UPGRADE' => 1, 'USE_FRM' => 1, 'VIRTUAL' => 1,
|
||||
'CASCADED' => 1, 'CHECKSUM' => 1, 'DUMPFILE' => 1, 'EXTENDED' => 1,
|
||||
'FUNCTION' => 1, 'GEOMETRY' => 1, 'INNOBASE' => 1, 'LANGUAGE' => 1,
|
||||
'MAX_ROWS' => 1, 'MIN_ROWS' => 1, 'NATIONAL' => 1, 'NVARCHAR' => 1,
|
||||
@ -77,8 +77,8 @@ class ContextMySql50000 extends Context
|
||||
'VARIABLES' => 1,
|
||||
'BERKELEYDB' => 1, 'COMPRESSED' => 1, 'CONCURRENT' => 1, 'CONNECTION' => 1,
|
||||
'CONSISTENT' => 1, 'DEALLOCATE' => 1, 'IDENTIFIED' => 1, 'MASTER_SSL' => 1,
|
||||
'NDBCLUSTER' => 1, 'PRIVILEGES' => 1, 'REPEATABLE' => 1, 'ROW_FORMAT' => 1,
|
||||
'SQL_THREAD' => 1, 'TABLESPACE' => 1,
|
||||
'NDBCLUSTER' => 1, 'PERSISTENT' => 1, 'PRIVILEGES' => 1, 'REPEATABLE' => 1,
|
||||
'ROW_FORMAT' => 1, 'SQL_THREAD' => 1, 'TABLESPACE' => 1,
|
||||
'FRAC_SECOND' => 1, 'MASTER_HOST' => 1, 'MASTER_PORT' => 1, 'MASTER_USER' => 1,
|
||||
'PROCESSLIST' => 1, 'RAID_CHUNKS' => 1, 'REPLICATION' => 1, 'SQL_TSI_DAY' => 1,
|
||||
'TRANSACTION' => 1, 'UNCOMMITTED' => 1,
|
||||
@ -151,6 +151,7 @@ class ContextMySql50000 extends Context
|
||||
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
|
||||
'DATA DIRECTORY' => 7,
|
||||
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
|
||||
'GENERATED ALWAYS' => 7,
|
||||
'DEFAULT CHARACTER SET' => 7,
|
||||
|
||||
'XML' => 9,
|
||||
|
||||
@ -67,7 +67,8 @@ class ContextMySql50100 extends Context
|
||||
'OPTIONS' => 1, 'PARTIAL' => 1, 'PLUGINS' => 1, 'PREPARE' => 1, 'PROFILE' => 1,
|
||||
'REBUILD' => 1, 'RECOVER' => 1, 'RESTORE' => 1, 'RETURNS' => 1, 'ROUTINE' => 1,
|
||||
'SESSION' => 1, 'STORAGE' => 1, 'STRIPED' => 1, 'SUBJECT' => 1, 'SUSPEND' => 1,
|
||||
'UNICODE' => 1, 'UNKNOWN' => 1, 'UPGRADE' => 1, 'USE_FRM' => 1, 'WRAPPER' => 1,
|
||||
'UNICODE' => 1, 'UNKNOWN' => 1, 'UPGRADE' => 1, 'USE_FRM' => 1, 'VIRTUAL' => 1,
|
||||
'WRAPPER' => 1,
|
||||
'CASCADED' => 1, 'CHECKSUM' => 1, 'DATAFILE' => 1, 'DUMPFILE' => 1,
|
||||
'EXTENDED' => 1, 'FUNCTION' => 1, 'GEOMETRY' => 1, 'INNOBASE' => 1,
|
||||
'LANGUAGE' => 1, 'MAXVALUE' => 1, 'MAX_ROWS' => 1, 'MAX_SIZE' => 1,
|
||||
@ -83,9 +84,9 @@ class ContextMySql50100 extends Context
|
||||
'UNINSTALL' => 1, 'VARIABLES' => 1,
|
||||
'BERKELEYDB' => 1, 'COMPLETION' => 1, 'COMPRESSED' => 1, 'CONCURRENT' => 1,
|
||||
'CONNECTION' => 1, 'CONSISTENT' => 1, 'DEALLOCATE' => 1, 'IDENTIFIED' => 1,
|
||||
'MASTER_SSL' => 1, 'NDBCLUSTER' => 1, 'PARTITIONS' => 1, 'PRIVILEGES' => 1,
|
||||
'REORGANISE' => 1, 'REORGANIZE' => 1, 'REPEATABLE' => 1, 'ROW_FORMAT' => 1,
|
||||
'SQL_THREAD' => 1, 'TABLESPACE' => 1,
|
||||
'MASTER_SSL' => 1, 'NDBCLUSTER' => 1, 'PARTITIONS' => 1, 'PERSISTENT' => 1,
|
||||
'PRIVILEGES' => 1, 'REORGANISE' => 1, 'REORGANIZE' => 1, 'REPEATABLE' => 1,
|
||||
'ROW_FORMAT' => 1, 'SQL_THREAD' => 1, 'TABLESPACE' => 1,
|
||||
'EXTENT_SIZE' => 1, 'FRAC_SECOND' => 1, 'MASTER_HOST' => 1, 'MASTER_PORT' => 1,
|
||||
'MASTER_USER' => 1, 'PROCESSLIST' => 1, 'RAID_CHUNKS' => 1, 'REPLICATION' => 1,
|
||||
'SQL_TSI_DAY' => 1, 'TRANSACTION' => 1, 'UNCOMMITTED' => 1,
|
||||
@ -162,6 +163,7 @@ class ContextMySql50100 extends Context
|
||||
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
|
||||
'DATA DIRECTORY' => 7,
|
||||
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
|
||||
'GENERATED ALWAYS' => 7,
|
||||
'DEFAULT CHARACTER SET' => 7,
|
||||
|
||||
'XML' => 9,
|
||||
|
||||
@ -67,7 +67,8 @@ class ContextMySql50500 extends Context
|
||||
'NO_WAIT' => 1, 'OPTIONS' => 1, 'PARTIAL' => 1, 'PLUGINS' => 1, 'PREPARE' => 1,
|
||||
'PROFILE' => 1, 'REBUILD' => 1, 'RECOVER' => 1, 'RESTORE' => 1, 'RETURNS' => 1,
|
||||
'ROUTINE' => 1, 'SESSION' => 1, 'STORAGE' => 1, 'SUBJECT' => 1, 'SUSPEND' => 1,
|
||||
'UNICODE' => 1, 'UNKNOWN' => 1, 'UPGRADE' => 1, 'USE_FRM' => 1, 'WRAPPER' => 1,
|
||||
'UNICODE' => 1, 'UNKNOWN' => 1, 'UPGRADE' => 1, 'USE_FRM' => 1, 'VIRTUAL' => 1,
|
||||
'WRAPPER' => 1,
|
||||
'CASCADED' => 1, 'CHECKSUM' => 1, 'DATAFILE' => 1, 'DUMPFILE' => 1,
|
||||
'EXTENDED' => 1, 'FUNCTION' => 1, 'GEOMETRY' => 1, 'INNOBASE' => 1,
|
||||
'LANGUAGE' => 1, 'MAX_ROWS' => 1, 'MAX_SIZE' => 1, 'MIN_ROWS' => 1,
|
||||
@ -82,9 +83,9 @@ class ContextMySql50500 extends Context
|
||||
'TEMPTABLE' => 1, 'UNDEFINED' => 1, 'UNINSTALL' => 1, 'VARIABLES' => 1,
|
||||
'COMPLETION' => 1, 'COMPRESSED' => 1, 'CONCURRENT' => 1, 'CONNECTION' => 1,
|
||||
'CONSISTENT' => 1, 'DEALLOCATE' => 1, 'IDENTIFIED' => 1, 'MASTER_SSL' => 1,
|
||||
'NDBCLUSTER' => 1, 'PARTITIONS' => 1, 'PRIVILEGES' => 1, 'REORGANIZE' => 1,
|
||||
'REPEATABLE' => 1, 'ROW_FORMAT' => 1, 'SQL_THREAD' => 1, 'TABLESPACE' => 1,
|
||||
'TABLE_NAME' => 1,
|
||||
'NDBCLUSTER' => 1, 'PARTITIONS' => 1, 'PERSISTENT' => 1, 'PRIVILEGES' => 1,
|
||||
'REORGANIZE' => 1, 'REPEATABLE' => 1, 'ROW_FORMAT' => 1, 'SQL_THREAD' => 1,
|
||||
'TABLESPACE' => 1, 'TABLE_NAME' => 1,
|
||||
'COLUMN_NAME' => 1, 'CURSOR_NAME' => 1, 'EXTENT_SIZE' => 1, 'FRAC_SECOND' => 1,
|
||||
'MASTER_HOST' => 1, 'MASTER_PORT' => 1, 'MASTER_USER' => 1, 'MYSQL_ERRNO' => 1,
|
||||
'PROCESSLIST' => 1, 'REPLICATION' => 1, 'SCHEMA_NAME' => 1, 'SQL_TSI_DAY' => 1,
|
||||
@ -167,6 +168,7 @@ class ContextMySql50500 extends Context
|
||||
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
|
||||
'DATA DIRECTORY' => 7,
|
||||
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
|
||||
'GENERATED ALWAYS' => 7,
|
||||
'DEFAULT CHARACTER SET' => 7,
|
||||
|
||||
'XML' => 9,
|
||||
|
||||
@ -68,7 +68,7 @@ class ContextMySql50600 extends Context
|
||||
'PLUGINS' => 1, 'PREPARE' => 1, 'PROFILE' => 1, 'REBUILD' => 1, 'RECOVER' => 1,
|
||||
'RESTORE' => 1, 'RETURNS' => 1, 'ROUTINE' => 1, 'SESSION' => 1, 'STORAGE' => 1,
|
||||
'SUBJECT' => 1, 'SUSPEND' => 1, 'UNICODE' => 1, 'UNKNOWN' => 1, 'UPGRADE' => 1,
|
||||
'USE_FRM' => 1, 'WRAPPER' => 1,
|
||||
'USE_FRM' => 1, 'VIRTUAL' => 1, 'WRAPPER' => 1,
|
||||
'CASCADED' => 1, 'CHECKSUM' => 1, 'DATAFILE' => 1, 'DUMPFILE' => 1,
|
||||
'EXCHANGE' => 1, 'EXTENDED' => 1, 'FUNCTION' => 1, 'GEOMETRY' => 1,
|
||||
'LANGUAGE' => 1, 'MAX_ROWS' => 1, 'MAX_SIZE' => 1, 'MIN_ROWS' => 1,
|
||||
@ -83,9 +83,9 @@ class ContextMySql50600 extends Context
|
||||
'UNDEFINED' => 1, 'UNINSTALL' => 1, 'VARIABLES' => 1,
|
||||
'COMPLETION' => 1, 'COMPRESSED' => 1, 'CONCURRENT' => 1, 'CONNECTION' => 1,
|
||||
'CONSISTENT' => 1, 'DEALLOCATE' => 1, 'IDENTIFIED' => 1, 'MASTER_SSL' => 1,
|
||||
'NDBCLUSTER' => 1, 'PARTITIONS' => 1, 'PLUGIN_DIR' => 1, 'PRIVILEGES' => 1,
|
||||
'REORGANIZE' => 1, 'REPEATABLE' => 1, 'ROW_FORMAT' => 1, 'SQL_THREAD' => 1,
|
||||
'TABLESPACE' => 1, 'TABLE_NAME' => 1,
|
||||
'NDBCLUSTER' => 1, 'PARTITIONS' => 1, 'PERSISTENT' => 1, 'PLUGIN_DIR' => 1,
|
||||
'PRIVILEGES' => 1, 'REORGANIZE' => 1, 'REPEATABLE' => 1, 'ROW_FORMAT' => 1,
|
||||
'SQL_THREAD' => 1, 'TABLESPACE' => 1, 'TABLE_NAME' => 1,
|
||||
'COLUMN_NAME' => 1, 'CURSOR_NAME' => 1, 'DIAGNOSTICS' => 1, 'EXTENT_SIZE' => 1,
|
||||
'MASTER_HOST' => 1, 'MASTER_PORT' => 1, 'MASTER_USER' => 1, 'MYSQL_ERRNO' => 1,
|
||||
'PROCESSLIST' => 1, 'REPLICATION' => 1, 'SCHEMA_NAME' => 1, 'SQL_TSI_DAY' => 1,
|
||||
@ -173,6 +173,7 @@ class ContextMySql50600 extends Context
|
||||
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
|
||||
'DATA DIRECTORY' => 7,
|
||||
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
|
||||
'GENERATED ALWAYS' => 7,
|
||||
'DEFAULT CHARACTER SET' => 7,
|
||||
|
||||
'XML' => 9,
|
||||
|
||||
@ -85,9 +85,9 @@ class ContextMySql50700 extends Context
|
||||
'UNDEFINED' => 1, 'UNINSTALL' => 1, 'VARIABLES' => 1,
|
||||
'COMPLETION' => 1, 'COMPRESSED' => 1, 'CONCURRENT' => 1, 'CONNECTION' => 1,
|
||||
'CONSISTENT' => 1, 'DEALLOCATE' => 1, 'IDENTIFIED' => 1, 'MASTER_SSL' => 1,
|
||||
'NDBCLUSTER' => 1, 'PARTITIONS' => 1, 'PLUGIN_DIR' => 1, 'PRIVILEGES' => 1,
|
||||
'REORGANIZE' => 1, 'REPEATABLE' => 1, 'ROW_FORMAT' => 1, 'SQL_THREAD' => 1,
|
||||
'TABLESPACE' => 1, 'TABLE_NAME' => 1, 'VALIDATION' => 1,
|
||||
'NDBCLUSTER' => 1, 'PARTITIONS' => 1, 'PERSISTENT' => 1, 'PLUGIN_DIR' => 1,
|
||||
'PRIVILEGES' => 1, 'REORGANIZE' => 1, 'REPEATABLE' => 1, 'ROW_FORMAT' => 1,
|
||||
'SQL_THREAD' => 1, 'TABLESPACE' => 1, 'TABLE_NAME' => 1, 'VALIDATION' => 1,
|
||||
'COLUMN_NAME' => 1, 'COMPRESSION' => 1, 'CURSOR_NAME' => 1, 'DIAGNOSTICS' => 1,
|
||||
'EXTENT_SIZE' => 1, 'MASTER_HOST' => 1, 'MASTER_PORT' => 1, 'MASTER_USER' => 1,
|
||||
'MYSQL_ERRNO' => 1, 'NONBLOCKING' => 1, 'PROCESSLIST' => 1, 'REPLICATION' => 1,
|
||||
@ -181,6 +181,7 @@ class ContextMySql50700 extends Context
|
||||
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
|
||||
'DATA DIRECTORY' => 7,
|
||||
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
|
||||
'GENERATED ALWAYS' => 7,
|
||||
'DEFAULT CHARACTER SET' => 7,
|
||||
|
||||
'XML' => 9,
|
||||
|
||||
@ -95,7 +95,7 @@ abstract class Statement
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the statement.
|
||||
* Builds the string representation of this statement.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -292,4 +292,16 @@ abstract class Statement
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the string representation of this statement.
|
||||
*
|
||||
* @see static::build
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return static::build($this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,6 +122,11 @@ class Table
|
||||
$ret[$field->name]['on_update_current_timestamp'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (($option = $field->options->has('AS'))) {
|
||||
$ret[$field->name]['generated'] = true;
|
||||
$ret[$field->name]['expr'] = $option->expr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user