public function validateClauseOrder($parser, $list)
    {
        $clauses = array_flip(array_keys($this->getClauses()));

        if (empty($clauses) || count($clauses) === 0) {
            return true;
        }

        $minIdx = -1;

        /**
         * For tracking JOIN clauses in a query
         *   = 0 - JOIN not found till now
         *   > 0 - Index of first JOIN clause in the statement.
         *
         * @var int
         */
        $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,
                $list,
                $clauseType
            );

            if ($clauseStartIdx !== -1
                && $this instanceof Statements\SelectStatement
                && ($clauseType === 'FORCE'
                || $clauseType === 'IGNORE'
                || $clauseType === 'USE')
            ) {
                // TODO: ordering of clauses in a SELECT statement with
                // Index hints is not supported
                return true;
            }

            // Handle ordering of Multiple Joins in a query
            if ($clauseStartIdx !== -1) {
                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 ($minJoin === 0 || $error === 1) {
                    $token = $list->tokens[$clauseStartIdx];
                    $parser->error(
                        'Unexpected ordering of clauses.',
                        $token
                    );

                    return false;
                }
                $minIdx = $clauseStartIdx;
            } elseif ($clauseStartIdx !== -1) {
                $minIdx = $clauseStartIdx;
            }

            $lastIdx = ($clauseStartIdx !== -1) ? $clauseStartIdx : $lastIdx;
        }

        return true;
    }
public function validateClauseOrder($parser, $list)
    {
        $clauses = array_flip(array_keys($this->getClauses()));

        if (empty($clauses) || count($clauses) === 0) {
            return true;
        }

        $minIdx = -1;

        /**
         * For tracking JOIN clauses in a query
         *   = 0 - JOIN not found till now
         *   > 0 - Index of first JOIN clause in the statement.
         *
         * @var int
         */
        $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,
                $list,
                $clauseType
            );

            if ($clauseStartIdx !== -1
                && $this instanceof Statements\SelectStatement
                && ($clauseType === 'FORCE'
                || $clauseType === 'IGNORE'
                || $clauseType === 'USE')
            ) {
                // TODO: ordering of clauses in a SELECT statement with
                // Index hints is not supported
                return true;
            }

            // Handle ordering of Multiple Joins in a query
            if ($clauseStartIdx !== -1) {
                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 ($minJoin === 0 || $error === 1) {
                    $token = $list->tokens[$clauseStartIdx];
                    $parser->error(
                        'Unexpected ordering of clauses.',
                        $token
                    );

                    return false;
                }
                $minIdx = $clauseStartIdx;
            } elseif ($clauseStartIdx !== -1) {
                $minIdx = $clauseStartIdx;
            }

            $lastIdx = ($clauseStartIdx !== -1) ? $clauseStartIdx : $lastIdx;
        }

        return true;
    }
public function validateClauseOrder ( $ parser , $ list ) { $ clauses = array_flip ( array_keys ( $ this -> getClauses ( ) ) ) ; if ( empty ( $ clauses ) || count ( $ clauses ) === 0 ) { return true ; } $ minIdx = - 1 ; /**
         * For tracking JOIN clauses in a query
         *   = 0 - JOIN not found till now
         *   > 0 - Index of first JOIN clause in the statement.
         *
         * @var int
         */ $ 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 , $ list , $ clauseType ) ; if ( $ clauseStartIdx !== - 1 && $ this instanceof Statements \ SelectStatement && ( $ clauseType === 'FORCE' || $ clauseType === 'IGNORE' || $ clauseType === 'USE' ) ) { // TODO: ordering of clauses in a SELECT statement with // Index hints is not supported return true ; } // Handle ordering of Multiple Joins in a query if ( $ clauseStartIdx !== - 1 ) { 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 ( $ minJoin === 0 || $ error === 1 ) { $ token = $ list -> tokens [ $ clauseStartIdx ] ; $ parser -> error ( 'Unexpected ordering of clauses.' , $ token ) ; return false ; } $ minIdx = $ clauseStartIdx ; } elseif ( $ clauseStartIdx !== - 1 ) { $ minIdx = $ clauseStartIdx ; } $ lastIdx = ( $ clauseStartIdx !== - 1 ) ? $ clauseStartIdx : $ lastIdx ; } return true ; }
Validates the order of the clauses in parsed statement
Ideally this should be called after successfully
completing the parsing of each statement.

@param Parser     $parser the instance that requests parsing
@param TokensList $list   the list of tokens to be parsed

@return bool
Validates the order of the clauses in parsed statement Ideally this should be called after successfully completing the parsing of each statement .