summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDeven Bansod <devenbansod.bits@gmail.com>2017-02-17 20:26:09 +0530
committerDeven Bansod <devenbansod.bits@gmail.com>2017-02-17 20:26:09 +0530
commit71aa13cd6fb46987093059161202bd68c30f9fa9 (patch)
tree51f21869cedf176862872ba16e5f76276d73d3fd /src
parent4cd61e0a0528039ce56a5111880ae9f86a9662cf (diff)
downloadsql-parser-71aa13cd6fb46987093059161202bd68c30f9fa9.zip
sql-parser-71aa13cd6fb46987093059161202bd68c30f9fa9.tar.gz
sql-parser-71aa13cd6fb46987093059161202bd68c30f9fa9.tar.bz2
Fix broken clause order validation
Fix #113 Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/Statement.php36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/Statement.php b/src/Statement.php
index dc5f945..50b1285 100644
--- a/src/Statement.php
+++ b/src/Statement.php
@@ -451,16 +451,26 @@ abstract class Statement
/**
* For tracking JOIN clauses in a query
- * 0 - JOIN not found till now
- * 1 - JOIN has been found
- * 2 - A Non-JOIN clause has been found
- * after a previously found JOIN clause.
+ * = 0 - JOIN not found till now
+ * > 0 - Index of first JOIN clause in the statement
*
* @var int
*/
- $joinStart = 0;
+ $minJoin = 0;
+
+ /**
+ * For tracking JOIN clauses in a query
+ * = 0 - JOIN not found till now
+ * > 0 - Index of last JOIN clause
+ * (which appears together with other JOINs)
+ * in the statement
+ *
+ * @var int
+ */
+ $maxJoin = 0;
$error = 0;
+ $lastIdx = 0;
foreach ($clauses as $clauseType => $index) {
$clauseStartIdx = Utils\Query::getClauseStartOffset(
$this,
@@ -470,17 +480,19 @@ abstract class Statement
// Handle ordering of Multiple Joins in a query
if ($clauseStartIdx != -1) {
- if ($joinStart == 0 && stripos($clauseType, 'JOIN') !== false) {
- $joinStart = 1;
- } elseif ($joinStart == 1 && stripos($clauseType, 'JOIN') === false) {
- $joinStart = 2;
- } elseif ($joinStart == 2 && stripos($clauseType, 'JOIN') !== false) {
+ if ($minJoin === 0 && stripos($clauseType, 'JOIN')) {
+ // First JOIN clause is detected
+ $minJoin = $maxJoin = $clauseStartIdx;
+ } elseif ($minJoin !== 0 && ! stripos($clauseType, 'JOIN')) {
+ // After a previous JOIN clause, a non-JOIN clause has been detected
+ $maxJoin = $lastIdx;
+ } elseif ($maxJoin < $clauseStartIdx && stripos($clauseType, 'JOIN')) {
$error = 1;
}
}
if ($clauseStartIdx != -1 && $clauseStartIdx < $minIdx) {
- if ($joinStart == 0 || ($joinStart == 2 && $error = 1)) {
+ if ($minJoin === 0 || $error === 1) {
$token = $list->tokens[$clauseStartIdx];
$parser->error(
'Unexpected ordering of clauses.',
@@ -493,6 +505,8 @@ abstract class Statement
} elseif ($clauseStartIdx != -1) {
$minIdx = $clauseStartIdx;
}
+
+ $lastIdx = ($clauseStartIdx !== -1) ? $clauseStartIdx : $lastIdx;
}
return true;