summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDan Ungureanu <udan1107@gmail.com>2015-07-02 01:22:45 +0300
committerDan Ungureanu <udan1107@gmail.com>2015-07-02 01:22:45 +0300
commitfe199733111d7fa2eef929df39c39ee50bb55d89 (patch)
tree2094d7d916d3e27634a4bdcbb927f726830f8463 /src
parent532ada6c8ed9eade76341dc39c99f209192d77e5 (diff)
downloadsql-parser-fe199733111d7fa2eef929df39c39ee50bb55d89.zip
sql-parser-fe199733111d7fa2eef929df39c39ee50bb55d89.tar.gz
sql-parser-fe199733111d7fa2eef929df39c39ee50bb55d89.tar.bz2
Improved WHERE keyword parser and query's utilities.
Diffstat (limited to 'src')
-rw-r--r--src/Fragments/WhereKeyword.php51
-rw-r--r--src/Utils/Query.php83
2 files changed, 76 insertions, 58 deletions
diff --git a/src/Fragments/WhereKeyword.php b/src/Fragments/WhereKeyword.php
index 0710738..f5bec24 100644
--- a/src/Fragments/WhereKeyword.php
+++ b/src/Fragments/WhereKeyword.php
@@ -30,7 +30,14 @@ class WhereKeyword extends Fragment
*
* @var array
*/
- public static $OPERATORS = array('&&', '(', ')', 'AND', 'OR', 'XOR', '||');
+ public static $OPERATORS = array('&&', 'AND', 'OR', 'XOR', '||');
+
+ /**
+ * Identifiers recognized.
+ *
+ * @var array
+ */
+ public $identifiers = array();
/**
* Whether this fragment is an operator.
@@ -67,11 +74,13 @@ class WhereKeyword extends Fragment
{
$ret = array();
+ $expr = new WhereKeyword();
+
/**
- * The condition that was parsed so far.
- * @var string
+ * Counts brackets.
+ * @var int
*/
- $tmp = '';
+ $brackets = 0;
for (; $list->idx < $list->count; ++$list->idx) {
@@ -93,10 +102,10 @@ class WhereKeyword extends Fragment
// Conditions are delimited by logical operators.
if (in_array($token->value, static::$OPERATORS, true)) {
- if (!empty(trim($tmp))) {
+ $expr->expr = trim($expr->expr);
+ if (!empty($expr->expr)) {
// Adding the condition that is delimited by this operator.
- $ret[] = new WhereKeyword($tmp);
- $tmp = '';
+ $ret[] = $expr;
}
// Adding the operator.
@@ -104,21 +113,39 @@ class WhereKeyword extends Fragment
$expr->isOperator = true;
$ret[] = $expr;
+ $expr = new WhereKeyword();
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)) {
- break;
+ if ($brackets == 0) {
+ break;
+ }
}
- $tmp .= $token->token;
-
+ $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_STRING)
+ || ($token->type === Token::TYPE_SYMBOL)
+ ) {
+ $expr->identifiers[] = $token->value;
+ }
}
// Last iteration was not processed.
- if (!empty(trim($tmp))) {
- $ret[] = new WhereKeyword($tmp);
+ $expr->expr = trim($expr->expr);
+ if (!empty($expr->expr)) {
+ $ret[] = $expr;
}
--$list->idx;
diff --git a/src/Utils/Query.php b/src/Utils/Query.php
index f973744..11a08d0 100644
--- a/src/Utils/Query.php
+++ b/src/Utils/Query.php
@@ -8,6 +8,7 @@
*/
namespace SqlParser\Utils;
+use SqlParser\Lexer;
use SqlParser\Parser;
use SqlParser\Statement;
use SqlParser\Token;
@@ -407,32 +408,6 @@ class Query
}
/**
- * Gets the type of clause.
- *
- * @param string $clause The clause.
- *
- * @return string
- */
- public static function getClauseType($clause)
- {
- $type = '';
- for ($i = 0, $len = strlen($clause); $i < $len; ++$i) {
- if ((empty($type)) && (ctype_space($clause[$i]))) {
- // Skipping whitespaces if we haven't started determining the
- // type.
- continue;
- }
- if (!ctype_alnum($clause[$i])) {
- // The type contains only alphanumeric characters.
- break;
- }
- // Adding character.
- $type .= $clause[$i];
- }
- return $type;
- }
-
- /**
* Gets a specific clause.
*
* @param Statement $statement The parsed query that has to be modified.
@@ -475,10 +450,22 @@ class Query
$clauses = array_flip(array_keys($statement::$CLAUSES));
/**
+ * Lexer used for lexing the clause.
+ * @var Lexer
+ */
+ $lexer = new Lexer($clause);
+
+ /**
+ * The type of this clause.
+ * @var string
+ */
+ $clauseType = $lexer->list->getNextOfType(Token::TYPE_KEYWORD)->value;
+
+ /**
* The index of this clause.
* @var int
*/
- $clauseIdx = $clauses[static::getClauseType($clause)];
+ $clauseIdx = $clauses[$clauseType];
for ($i = $statement->first; $i <= $statement->last; ++$i) {
$token = $list->tokens[$i];
@@ -493,16 +480,15 @@ class Query
if ($brackets == 0) {
// Checking if we changed sections.
- if ($token->type === Token::TYPE_KEYWORD) {
- if (isset($clauses[$token->value])) {
- if ($clauses[$token->value] >= $currIdx) {
- $currIdx = $clauses[$token->value];
- if (($skipFirst) && ($currIdx == $clauseIdx)) {
- // This token is skipped (not added to the old
- // clause) because it will be replaced.
- continue;
- }
- }
+ if (($token->type === Token::TYPE_KEYWORD)
+ && (isset($clauses[$token->value]))
+ && ($clauses[$token->value] >= $currIdx)
+ ) {
+ $currIdx = $clauses[$token->value];
+ if (($skipFirst) && ($currIdx == $clauseIdx)) {
+ // This token is skipped (not added to the old
+ // clause) because it will be replaced.
+ continue;
}
}
}
@@ -526,25 +512,30 @@ class Query
*
* @param Statement $statement The parsed query that has to be modified.
* @param TokensList $list The list of tokens.
- * @param string $clause The clause to be replaced.
+ * @param string $old The type of the clause that should be
+ * replaced. This can be an entire clause.
+ * @param string $new The new clause. If this parameter is omitted
+ * it is considered to be equal with `$old`.
* @param bool $onlyType Whether only the type of the clause should
* be replaced or the entire clause.
*
* @return string
*/
- public static function replaceClause($statement, $list, $clause, $onlyType = false)
+ public static function replaceClause($statement, $list, $old, $new = null, $onlyType = false)
{
// TODO: Update the tokens list and the statement.
+ if ($new === null) {
+ $new = $old;
+ }
+
if ($onlyType) {
- return static::getClause($statement, $list, $clause, -1, false) . ' ' .
- $clause . ' ' .
- static::getCLause($statement, $list, $clause, 0) . ' ' .
- static::getClause($statement, $list, $clause, 1, false);
+ return static::getClause($statement, $list, $old, -1, false) . ' ' .
+ $new . ' ' . static::getCLause($statement, $list, $old, 0) . ' ' .
+ static::getClause($statement, $list, $old, 1, false);
}
- return static::getClause($statement, $list, $clause, -1, false) . ' ' .
- $clause . ' ' .
- static::getClause($statement, $list, $clause, 1, false);
+ return static::getClause($statement, $list, $old, -1, false) . ' ' .
+ $new . ' ' . static::getClause($statement, $list, $old, 1, false);
}
}