summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Components/Condition.php39
1 files changed, 23 insertions, 16 deletions
diff --git a/src/Components/Condition.php b/src/Components/Condition.php
index 9d7d586..80c40f5 100644
--- a/src/Components/Condition.php
+++ b/src/Components/Condition.php
@@ -30,17 +30,18 @@ class Condition extends Component
*
* @var array
*/
- public static $DELIMITERS = array('&&', 'AND', 'OR', 'XOR', '||');
+ public static $DELIMITERS = array('&&', '||', 'AND', 'OR', 'XOR');
/**
- * Hash map containing reserved keywords that are also operators.
+ * List of allowed reserved keywords in conditions.
*
* @var array
*/
- public static $OPERATORS = array(
+ public static $ALLOWED_KEYWORDS = array(
'AND' => 1,
'BETWEEN' => 1,
'EXISTS' => 1,
+ 'IF' => 1,
'IN' => 1,
'IS' => 1,
'LIKE' => 1,
@@ -106,6 +107,7 @@ class Condition extends Component
/**
* Whether there was a `BETWEEN` keyword before or not.
+ *
* It is required to keep track of them because their structure contains
* the keyword `AND`, which is also an operator that delimits
* expressions.
@@ -115,6 +117,7 @@ class Condition extends Component
$betweenBefore = false;
for (; $list->idx < $list->count; ++$list->idx) {
+
/**
* Token parsed at this moment.
*
@@ -142,11 +145,12 @@ class Condition extends Component
// Conditions are delimited by logical operators.
if (in_array($token->value, static::$DELIMITERS, true)) {
if (($betweenBefore) && ($token->value === 'AND')) {
+ // The syntax of keyword `BETWEEN` is hard-coded.
$betweenBefore = false;
} else {
+ // The expression ended.
$expr->expr = trim($expr->expr);
if (!empty($expr->expr)) {
- // Adding the condition that is delimited by this operator.
$ret[] = $expr;
}
@@ -155,36 +159,39 @@ class Condition extends Component
$expr->isOperator = true;
$ret[] = $expr;
+ // Preparing to parse another condition.
$expr = new Condition();
continue;
}
}
- if ($token->type === Token::TYPE_OPERATOR) {
- if ($token->value === '(') {
- ++$brackets;
- } elseif ($token->value === ')') {
- --$brackets;
- }
- }
-
- // No keyword is expected.
if (($token->type === Token::TYPE_KEYWORD) && ($token->flags & Token::FLAG_KEYWORD_RESERVED)) {
if ($token->value === 'BETWEEN') {
$betweenBefore = true;
}
- if (($brackets === 0) && (empty(static::$OPERATORS[$token->value]))) {
+ if (($brackets === 0) && (empty(static::$ALLOWED_KEYWORDS[$token->value]))) {
break;
}
}
+ if ($token->type === Token::TYPE_OPERATOR) {
+ if ($token->value === '(') {
+ ++$brackets;
+ } elseif ($token->value === ')') {
+ --$brackets;
+ }
+ }
+
$expr->expr .= $token->token;
if (($token->type === Token::TYPE_NONE)
- || (($token->type === Token::TYPE_KEYWORD) && (!($token->flags & Token::FLAG_KEYWORD_RESERVED)))
+ || (($token->type === Token::TYPE_KEYWORD)
+ && (!($token->flags & Token::FLAG_KEYWORD_RESERVED)))
|| ($token->type === Token::TYPE_STRING)
|| ($token->type === Token::TYPE_SYMBOL)
) {
- $expr->identifiers[] = $token->value;
+ if (!in_array($token->value, $expr->identifiers)) {
+ $expr->identifiers[] = $token->value;
+ }
}
}