Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2015-07-19 14:29:27 +02:00
commit a5ff4c47c7
7 changed files with 79 additions and 44 deletions

View File

@ -553,7 +553,12 @@ var PMA_consoleInput = {
mode: 'text/x-sql',
lineWrapping: true,
extraKeys: {"Ctrl-Space": "autocomplete"},
hintOptions: {"completeSingle": false, "completeOnSingleClick": true}
hintOptions: {"completeSingle": false, "completeOnSingleClick": true},
gutters: ["CodeMirror-lint-markers"],
lint: {
"getAnnotations": CodeMirror.sqlLint,
"async": true,
}
});
PMA_consoleInput._inputs.console.on("inputRead", codemirrorAutocompleteOnInputRead);
PMA_consoleInput._inputs.console.on("keydown", function(instance, event) {
@ -565,7 +570,12 @@ var PMA_consoleInput = {
mode: 'text/x-sql',
lineWrapping: true,
extraKeys: {"Ctrl-Space": "autocomplete"},
hintOptions: {"completeSingle": false, "completeOnSingleClick": true}
hintOptions: {"completeSingle": false, "completeOnSingleClick": true},
gutters: ["CodeMirror-lint-markers"],
lint: {
"getAnnotations": CodeMirror.sqlLint,
"async": true,
}
});
PMA_consoleInput._inputs.bookmark.on("inputRead", codemirrorAutocompleteOnInputRead);
}

View File

@ -36,13 +36,6 @@ class Array2d extends Component
{
$ret = array();
/**
* Whether an array was parsed or not. To be a valid parsing, at least
* one array must be parsed after each comma.
* @var bool $parsed
*/
$parsed = false;
/**
* The number of values in each set.
* @var int
@ -95,14 +88,12 @@ class Array2d extends Component
$parser->error("{$count} values were expected, but found {$arrCount}.", $token);
}
$ret[] = $arr;
$parsed = true;
$state = 1;
} else {
break;
}
} elseif ($state === 1) {
if ($token->value === ',') {
$parsed = false;
$state = 0;
} else {
break;
@ -110,7 +101,7 @@ class Array2d extends Component
}
}
if (!$parsed) {
if ($state === 0) {
$parser->error(
'An opening bracket followed by a set of values was expected.',
$list->tokens[$list->idx]

View File

@ -239,6 +239,9 @@ class Expression extends Component
if ($alias) {
// An alias is expected (the keyword `AS` was previously found).
if (!empty($ret->alias)) {
$parser->error('An alias was previously found.', $token);
}
$ret->alias = $token->value;
$alias = 0;
} else {
@ -265,12 +268,18 @@ class Expression extends Component
break;
}
// Parsing aliases without `AS` keyword and any whitespace.
// Parsing aliases without `AS` keyword and any
// whitespace.
// Example: SELECT 1`foo`
if (($token->type === Token::TYPE_STRING)
|| (($token->type === Token::TYPE_SYMBOL)
&& ($token->flags & Token::FLAG_SYMBOL_BACKTICK))
) {
if (!empty($ret->alias)) {
$parser->error(
'An alias was previously found.', $token
);
}
$ret->alias = $token->value;
}
} else {
@ -285,6 +294,11 @@ class Expression extends Component
if (($token->type === Token::TYPE_NONE) || ($token->type === Token::TYPE_STRING)
|| (($token->type === Token::TYPE_SYMBOL) && ($token->flags & Token::FLAG_SYMBOL_BACKTICK))
) {
if (!empty($ret->alias)) {
$parser->error(
'An alias was previously found.', $token
);
}
$ret->alias = $token->value;
continue;
}
@ -301,8 +315,8 @@ class Expression extends Component
} else {
$prev = null;
}
}
if ($alias === 2) {
$parser->error('An alias was expected.', $list->tokens[$list->idx - 1]);
}

View File

@ -38,6 +38,20 @@ class ExpressionArray extends Component
$expr = null;
/**
* The state of the parser.
*
* Below are the states of the parser.
*
* 0 ----------------------[ array ]---------------------> 1
*
* 1 ------------------------[ , ]------------------------> 0
* 1 -----------------------[ else ]----------------------> -1
*
* @var int
*/
$state = 0;
for (; $list->idx < $list->count; ++$list->idx) {
/**
* Token parsed at this moment.
@ -60,20 +74,27 @@ class ExpressionArray extends Component
break;
}
if (($token->type === Token::TYPE_OPERATOR) && ($token->value === ',')) {
$ret[] = $expr;
} else {
if ($state === 0) {
$expr = Expression::parse($parser, $list, $options);
if ($expr === null) {
break;
}
$ret[] = $expr;
$state = 1;
} elseif ($state === 1) {
if ($token->value === ',') {
$state = 0;
} else {
break;
}
}
}
// Last iteration was not processed.
if ($expr !== null) {
$ret[] = $expr;
if ($state === 0) {
$parser->error(
'An expression was expected.',
$list->tokens[$list->idx]
);
}
--$list->idx;

View File

@ -52,13 +52,6 @@ class RenameOperation extends Component
$expr = new RenameOperation();
/**
* Whether an operation was parsed or not. To be a valid parsing, at
* least one operation must be parsed after each comma.
* @var bool $parsed
*/
$parsed = false;
/**
* The state of the parser.
*
@ -129,21 +122,18 @@ class RenameOperation extends Component
$parser->error('The new name of the table was expected.', $token);
}
$state = 3;
$parsed = true;
} elseif ($state === 3) {
if (($token->type === Token::TYPE_OPERATOR) && ($token->value === ',')) {
$ret[] = $expr;
$expr = new RenameOperation();
$state = 0;
// Found a comma, looking for another operation.
$parsed = false;
} else {
break;
}
}
}
if (!$parsed) {
if ($state !== 3) {
$parser->error('A rename operation was expected.', $list->tokens[$list->idx - 1]);
}

View File

@ -327,6 +327,13 @@ class Parser
// Statements can start with keywords only.
// Comments, whitespaces, etc. are ignored.
if ($token->type !== Token::TYPE_KEYWORD) {
if (($token->type !== TOKEN::TYPE_COMMENT)
&& ($token->type !== Token::TYPE_WHITESPACE)
&& ($token->type !== Token::TYPE_OPERATOR) // `(` and `)`
&& ($token->type !== Token::TYPE_DELIMITER)
) {
$this->error('Unexpected beginning of statement.', $token);
}
continue;
}
@ -337,10 +344,7 @@ class Parser
// Checking if it is a known statement that can be parsed.
if (empty(static::$STATEMENT_PARSERS[$token->value])) {
$this->error(
'Unrecognized statement type.',
$token
);
$this->error('Unrecognized statement type.', $token);
// Skipping to the end of this statement.
$list->getNextOfType(Token::TYPE_DELIMITER);
//
@ -356,35 +360,35 @@ class Parser
/**
* Processed statement.
* @var Statement $stmt
* @var Statement $statement
*/
$stmt = new $class($this, $this->list);
$statement = new $class($this, $this->list);
// The first token that is a part of this token is the next token
// unprocessed by the previous statement.
// There might be brackets around statements and this shouldn't
// affect the parser
$stmt->first = $prevLastIdx + 1;
$statement->first = $prevLastIdx + 1;
// Storing the index of the last token parsed and updating the old
// index.
$stmt->last = $list->idx;
$statement->last = $list->idx;
$prevLastIdx = $list->idx;
// Finally, storing the statement.
if (($inUnion)
&& ($lastStatement instanceof SelectStatement)
&& ($stmt instanceof SelectStatement)
&& ($statement instanceof SelectStatement)
) {
/**
* Last SELECT statement.
* @var SelectStatement $lastStatement
*/
$lastStatement->union[] = $stmt;
$lastStatement->union[] = $statement;
$inUnion = false;
} else {
$this->statements[] = $stmt;
$lastStatement = $stmt;
$this->statements[] = $statement;
$lastStatement = $statement;
}
}

View File

@ -195,6 +195,11 @@ abstract class Statement
// Only keywords are relevant here. Other parts of the query are
// processed in the functions below.
if ($token->type !== Token::TYPE_KEYWORD) {
if (($token->type !== TOKEN::TYPE_COMMENT)
&& ($token->type !== Token::TYPE_WHITESPACE)
) {
$parser->error('Unexpected token.', $token);
}
continue;
}