Skip to content

Commit

Permalink
Expression: Refactored parsing options.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Ungureanu committed Feb 12, 2016
1 parent de8b3ef commit 8383942
Show file tree
Hide file tree
Showing 15 changed files with 93 additions and 62 deletions.
4 changes: 2 additions & 2 deletions src/Components/AlterOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ public static function parse(Parser $parser, TokensList $list, array $options =
$parser,
$list,
array(
'noAlias' => true,
'noBrackets' => true,
'breakOnAlias' => true,
'parseField' => 'column',
)
);
if ($ret->field === null) {
Expand Down
2 changes: 1 addition & 1 deletion src/Components/CreateDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class CreateDefinition extends Component

// Generated columns options.
'GENERATED ALWAYS' => 8,
'AS' => array(9, 'expr', array('bracketsDelimited' => true)),
'AS' => array(9, 'expr', array('parenthesesDelimited' => true)),
'VIRTUAL' => 10,
'PERSISTENT' => 11,
'STORED' => 11,
Expand Down
75 changes: 56 additions & 19 deletions src/Components/Expression.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,31 @@ public function __construct($database = null, $table = null, $column = null, $al
}

/**
* Possible options:
*
* `field`
*
* First field to be filled.
* If this is not specified, it takes the value of `parseField`.
*
* `parseField`
*
* Specifies the type of the field parsed. It may be `database`,
* `table` or `column`. These expressions may not include
* parentheses.
*
* `breakOnAlias`
*
* If not empty, breaks when the alias occurs (it is not included).
*
* `breakOnParentheses`
*
* If not empty, breaks when the first parentheses occurs.
*
* `parenthesesDelimited`
*
* If not empty, breaks after last parentheses occurred.
*
* @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.
Expand Down Expand Up @@ -164,6 +189,12 @@ public static function parse(Parser $parser, TokensList $list, array $options =
*/
$prev = array(null, null);

// When a field is parsed, no parentheses are expected.
if (!empty($options['parseField'])) {
$options['breakOnParentheses'] = true;
$options['field'] = $options['parseField'];
}

for (; $list->idx < $list->count; ++$list->idx) {

/**
Expand Down Expand Up @@ -195,7 +226,9 @@ public static function parse(Parser $parser, TokensList $list, array $options =
// A `(` was previously found and this keyword is the
// beginning of a statement, so this is a subquery.
$ret->subquery = $token->value;
} elseif ($token->flags & Token::FLAG_KEYWORD_FUNCTION) {
} elseif (($token->flags & Token::FLAG_KEYWORD_FUNCTION)
&& (empty($options['parseField']))
) {
$isExpr = true;
} elseif (($token->flags & Token::FLAG_KEYWORD_RESERVED)
&& ($brackets === 0)
Expand All @@ -207,7 +240,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =
break;
}
if ($token->value === 'AS') {
if (!empty($options['noAlias'])) {
if (!empty($options['breakOnAlias'])) {
break;
}
if (!empty($ret->alias)) {
Expand All @@ -224,8 +257,24 @@ public static function parse(Parser $parser, TokensList $list, array $options =
}
}

if (($token->type === Token::TYPE_NUMBER)
|| ($token->type === Token::TYPE_BOOL)
|| (($token->type === Token::TYPE_SYMBOL)
&& ($token->flags & Token::FLAG_SYMBOL_VARIABLE))
|| (($token->type === Token::TYPE_OPERATOR)
&& ($token->value !== '.'))
) {
if (!empty($options['parseField'])) {
break;
}

// Numbers, booleans and operators (except dot) are usually part
// of expressions.
$isExpr = true;
}

if ($token->type === Token::TYPE_OPERATOR) {
if ((!empty($options['noBrackets']))
if ((!empty($options['breakOnParentheses']))
&& (($token->value === '(') || ($token->value === ')'))
) {
// No brackets were expected.
Expand All @@ -244,7 +293,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =
} elseif ($token->value === ')') {
--$brackets;
if ($brackets === 0) {
if (!empty($options['bracketsDelimited'])) {
if (!empty($options['parenthesesDelimited'])) {
// The current token is the last bracket, the next
// one will be outside the expression.
$ret->expr .= $token->token;
Expand All @@ -264,19 +313,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =
}
}

if (($token->type === Token::TYPE_NUMBER)
|| ($token->type === Token::TYPE_BOOL)
|| (($token->type === Token::TYPE_SYMBOL)
&& ($token->flags & Token::FLAG_SYMBOL_VARIABLE))
|| (($token->type === Token::TYPE_OPERATOR)
&& ($token->value !== '.'))
) {
// Numbers, booleans and operators (except dot) are usually part
// of expressions.
$isExpr = true;
}

// Saving the previous token.
// Saving the previous tokens.
$prev[0] = $prev[1];
$prev[1] = $token;

Expand Down Expand Up @@ -323,14 +360,14 @@ public static function parse(Parser $parser, TokensList $list, array $options =
$dot = true;
$ret->expr .= $token->token;
} else {
$field = (!empty($options['skipColumn'])) ? 'table' : 'column';
$field = empty($options['field']) ? 'column' : $options['field'];
if (empty($ret->$field)) {
$ret->$field = $token->value;
$ret->expr .= $token->token;
$dot = false;
} else {
// No alias is expected.
if (!empty($options['noAlias'])) {
if (!empty($options['breakOnAlias'])) {
break;
}
if (!empty($ret->alias)) {
Expand Down
5 changes: 2 additions & 3 deletions src/Components/IntoKeyword.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,8 @@ public static function parse(Parser $parser, TokensList $list, array $options =
$parser,
$list,
array(
'noAlias' => true,
'noBrackets' => true,
'skipColumn' => true,
'parseField' => 'table',
'breakOnAlias' => true,
)
);
$state = 1;
Expand Down
2 changes: 1 addition & 1 deletion src/Components/JoinKeyword.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =
break;
}
} elseif ($state === 1) {
$expr->expr = Expression::parse($parser, $list, array('skipColumn' => true));
$expr->expr = Expression::parse($parser, $list, array('field' => 'table'));
$state = 2;
} elseif ($state === 2) {
if (($token->type === Token::TYPE_KEYWORD) && ($token->value === 'ON')) {
Expand Down
4 changes: 2 additions & 2 deletions src/Components/PartitionDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ public static function parse(Parser $parser, TokensList $list, array $options =
$parser,
$list,
array(
'bracketsDelimited' => true,
'noAlias' => true,
'parenthesesDelimited' => true,
'breakOnAlias' => true,
)
);
}
Expand Down
5 changes: 2 additions & 3 deletions src/Components/Reference.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,8 @@ public static function parse(Parser $parser, TokensList $list, array $options =
$parser,
$list,
array(
'noAlias' => true,
'skipColumn' => true,
'noBrackets' => true,
'parseField' => 'table',
'breakOnAlias' => true,
)
);
$state = 1;
Expand Down
10 changes: 4 additions & 6 deletions src/Components/RenameOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@ public static function parse(Parser $parser, TokensList $list, array $options =
$parser,
$list,
array(
'noAlias' => true,
'noBrackets' => true,
'skipColumn' => true,
'breakOnAlias' => true,
'parseField' => 'table',
)
);
if (empty($expr->old)) {
Expand All @@ -120,9 +119,8 @@ public static function parse(Parser $parser, TokensList $list, array $options =
$parser,
$list,
array(
'noBrackets' => true,
'skipColumn' => true,
'noAlias' => true,
'breakOnAlias' => true,
'parseField' => 'table',
)
);
if (empty($expr->new)) {
Expand Down
2 changes: 1 addition & 1 deletion src/Components/SetOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =
$parser,
$list,
array(
'noAlias' => true,
'breakOnAlias' => true,
)
);
if ($tmp == null) {
Expand Down
24 changes: 12 additions & 12 deletions src/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,17 @@ class Parser
'ALTER' => array(
'class' => 'SqlParser\\Components\\Expression',
'field' => 'table',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'ANALYZE' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'tables',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'BACKUP' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'tables',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'CALL' => array(
'class' => 'SqlParser\\Components\\FunctionCall',
Expand All @@ -144,22 +144,22 @@ class Parser
'CHECK' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'tables',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'CHECKSUM' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'tables',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'DROP' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'fields',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'FROM' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'from',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'GROUP BY' => array(
'class' => 'SqlParser\\Components\\OrderKeyword',
Expand Down Expand Up @@ -212,7 +212,7 @@ class Parser
'OPTIMIZE' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'tables',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'ORDER BY' => array(
'class' => 'SqlParser\\Components\\OrderKeyword',
Expand All @@ -233,12 +233,12 @@ class Parser
'REPAIR' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'tables',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'RESTORE' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'tables',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'SET' => array(
'class' => 'SqlParser\\Components\\SetOperation',
Expand All @@ -251,12 +251,12 @@ class Parser
'TRUNCATE' => array(
'class' => 'SqlParser\\Components\\Expression',
'field' => 'table',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'UPDATE' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'tables',
'options' => array('skipColumn' => true),
'options' => array('parseField' => 'table'),
),
'VALUE' => array(
'class' => 'SqlParser\\Components\\Array2d',
Expand Down
4 changes: 2 additions & 2 deletions src/Statements/AlterStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ public function parse(Parser $parser, TokensList $list)
$parser,
$list,
array(
'noAlias' => true,
'noBrackets' => true,
'parseField' => 'column',
'breakOnAlias' => true,
)
);
++$list->idx; // Skipping field.
Expand Down
10 changes: 4 additions & 6 deletions src/Statements/CreateStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,8 @@ public function parse(Parser $parser, TokensList $list)
$parser,
$list,
array(
'noAlias' => true,
'noBrackets' => true,
'skipColumn' => true,
'parseField' => 'table',
'breakOnAlias' => true,
)
);

Expand Down Expand Up @@ -538,9 +537,8 @@ public function parse(Parser $parser, TokensList $list)
$parser,
$list,
array(
'noAlias' => true,
'noBrackets' => true,
'skipColumn' => true,
'parseField' => 'table',
'breakOnAlias' => true,
)
);
++$list->idx;
Expand Down
2 changes: 1 addition & 1 deletion tests/Components/ArrayObjTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function testParseType()
array(
'type' => 'SqlParser\\Components\\Expression',
'typeOptions' => array(
'noBrackets' => true,
'breakOnParentheses' => true,
),
)
);
Expand Down
4 changes: 2 additions & 2 deletions tests/Components/ExpressionArrayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function testParse()
new Parser(),
$this->getTokensList('(expr)'),
array(
'noBrackets' => true,
'breakOnParentheses' => true,
)
);
$this->assertEquals(array(), $component);
Expand All @@ -28,7 +28,7 @@ public function testParse2()
new Parser(),
$this->getTokensList('(expr) +'),
array(
'bracketsDelimited' => true,
'parenthesesDelimited' => true,
)
);
$this->assertEquals(1, count($component));
Expand Down
2 changes: 1 addition & 1 deletion tests/Components/OptionsArrayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function testParseExpr()
new Parser(),
$this->getTokensList('SUM = (3 + 5) RESULT = 8'),
array(
'SUM' => array(1, 'expr', array('bracketsDelimited' => true)),
'SUM' => array(1, 'expr', array('parenthesesDelimited' => true)),
'RESULT' => array(2, 'var'),
)
);
Expand Down

0 comments on commit 8383942

Please sign in to comment.