Skip to content

Commit 0a603aa

Browse files
committed
Condition: Allow IF in conditions.
1 parent 5cb3993 commit 0a603aa

1 file changed

Lines changed: 23 additions & 16 deletions

File tree

src/Components/Condition.php

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,18 @@ class Condition extends Component
3030
*
3131
* @var array
3232
*/
33-
public static $DELIMITERS = array('&&', 'AND', 'OR', 'XOR', '||');
33+
public static $DELIMITERS = array('&&', '||', 'AND', 'OR', 'XOR');
3434

3535
/**
36-
* Hash map containing reserved keywords that are also operators.
36+
* List of allowed reserved keywords in conditions.
3737
*
3838
* @var array
3939
*/
40-
public static $OPERATORS = array(
40+
public static $ALLOWED_KEYWORDS = array(
4141
'AND' => 1,
4242
'BETWEEN' => 1,
4343
'EXISTS' => 1,
44+
'IF' => 1,
4445
'IN' => 1,
4546
'IS' => 1,
4647
'LIKE' => 1,
@@ -106,6 +107,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =
106107

107108
/**
108109
* Whether there was a `BETWEEN` keyword before or not.
110+
*
109111
* It is required to keep track of them because their structure contains
110112
* the keyword `AND`, which is also an operator that delimits
111113
* expressions.
@@ -115,6 +117,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =
115117
$betweenBefore = false;
116118

117119
for (; $list->idx < $list->count; ++$list->idx) {
120+
118121
/**
119122
* Token parsed at this moment.
120123
*
@@ -142,11 +145,12 @@ public static function parse(Parser $parser, TokensList $list, array $options =
142145
// Conditions are delimited by logical operators.
143146
if (in_array($token->value, static::$DELIMITERS, true)) {
144147
if (($betweenBefore) && ($token->value === 'AND')) {
148+
// The syntax of keyword `BETWEEN` is hard-coded.
145149
$betweenBefore = false;
146150
} else {
151+
// The expression ended.
147152
$expr->expr = trim($expr->expr);
148153
if (!empty($expr->expr)) {
149-
// Adding the condition that is delimited by this operator.
150154
$ret[] = $expr;
151155
}
152156

@@ -155,36 +159,39 @@ public static function parse(Parser $parser, TokensList $list, array $options =
155159
$expr->isOperator = true;
156160
$ret[] = $expr;
157161

162+
// Preparing to parse another condition.
158163
$expr = new Condition();
159164
continue;
160165
}
161166
}
162167

163-
if ($token->type === Token::TYPE_OPERATOR) {
164-
if ($token->value === '(') {
165-
++$brackets;
166-
} elseif ($token->value === ')') {
167-
--$brackets;
168-
}
169-
}
170-
171-
// No keyword is expected.
172168
if (($token->type === Token::TYPE_KEYWORD) && ($token->flags & Token::FLAG_KEYWORD_RESERVED)) {
173169
if ($token->value === 'BETWEEN') {
174170
$betweenBefore = true;
175171
}
176-
if (($brackets === 0) && (empty(static::$OPERATORS[$token->value]))) {
172+
if (($brackets === 0) && (empty(static::$ALLOWED_KEYWORDS[$token->value]))) {
177173
break;
178174
}
179175
}
180176

177+
if ($token->type === Token::TYPE_OPERATOR) {
178+
if ($token->value === '(') {
179+
++$brackets;
180+
} elseif ($token->value === ')') {
181+
--$brackets;
182+
}
183+
}
184+
181185
$expr->expr .= $token->token;
182186
if (($token->type === Token::TYPE_NONE)
183-
|| (($token->type === Token::TYPE_KEYWORD) && (!($token->flags & Token::FLAG_KEYWORD_RESERVED)))
187+
|| (($token->type === Token::TYPE_KEYWORD)
188+
&& (!($token->flags & Token::FLAG_KEYWORD_RESERVED)))
184189
|| ($token->type === Token::TYPE_STRING)
185190
|| ($token->type === Token::TYPE_SYMBOL)
186191
) {
187-
$expr->identifiers[] = $token->value;
192+
if (!in_array($token->value, $expr->identifiers)) {
193+
$expr->identifiers[] = $token->value;
194+
}
188195
}
189196
}
190197

0 commit comments

Comments
 (0)