summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Statement.php40
1 files changed, 34 insertions, 6 deletions
diff --git a/src/Statement.php b/src/Statement.php
index fd169df..e3e5968 100644
--- a/src/Statement.php
+++ b/src/Statement.php
@@ -457,6 +457,19 @@ abstract class Statement
}
$minIdx = -1;
+
+ /**
+ * 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
+ *
+ * @var int $joinStart
+ */
+ $joinStart = 0;
+
+ $error = 0;
foreach ($clauses as $clauseType => $index) {
$clauseStartIdx = Utils\Query::getClauseStartOffset(
$this,
@@ -464,13 +477,28 @@ abstract class Statement
$clauseType
);
+ // Handle ordering of Multiple Joins in a query
+ if ($clauseStartIdx != -1) {
+ if ($joinStart == 0 && stripos($clauseType, 'JOIN')) {
+ $joinStart = 1;
+ } elseif ($joinStart == 1 && ! stripos($clauseType, 'JOIN')) {
+ $joinStart = 2;
+ } elseif ($joinStart == 2 && stripos($clauseType, 'JOIN')) {
+ $error = 1;
+ }
+ }
+
if ($clauseStartIdx != -1 && $clauseStartIdx < $minIdx) {
- $token = $list->tokens[$clauseStartIdx];
- $parser->error(
- __('Unexpected ordering of clauses.'),
- $token
- );
- return false;
+ if ($joinStart == 0 || ($joinStart == 2 && $error = 1)) {
+ $token = $list->tokens[$clauseStartIdx];
+ $parser->error(
+ __('Unexpected ordering of clauses.'),
+ $token
+ );
+ return false;
+ } else {
+ $minIdx = $clauseStartIdx;
+ }
} elseif ($clauseStartIdx != -1) {
$minIdx = $clauseStartIdx;
}