__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

www-data@216.73.216.10: ~ $
<?php

declare(strict_types=1);

namespace PhpMyAdmin\SqlParser\Statements;

use PhpMyAdmin\SqlParser\Components\Array2d;
use PhpMyAdmin\SqlParser\Components\OptionsArray;
use PhpMyAdmin\SqlParser\Components\WithKeyword;
use PhpMyAdmin\SqlParser\Exceptions\ParserException;
use PhpMyAdmin\SqlParser\Parser;
use PhpMyAdmin\SqlParser\Statement;
use PhpMyAdmin\SqlParser\Token;
use PhpMyAdmin\SqlParser\TokensList;
use PhpMyAdmin\SqlParser\Translator;

use function array_slice;
use function count;

/**
 * `WITH` statement.

 *  WITH [RECURSIVE] query_name [ (column_name [,...]) ] AS (SELECT ...) [, ...]
 */
final class WithStatement extends Statement
{
    /**
     * Options for `WITH` statements and their slot ID.
     *
     * @var array<string, int|array<int, int|string>>
     * @psalm-var array<string, (positive-int|array{positive-int, ('var'|'var='|'expr'|'expr=')})>
     */
    public static $OPTIONS = ['RECURSIVE' => 1];

    /**
     * The clauses of this statement, in order.
     *
     * @see Statement::$CLAUSES
     *
     * @var array<string, array<int, int|string>>
     * @psalm-var array<string, array{non-empty-string, (1|2|3)}>
     */
    public static $CLAUSES = [
        'WITH' => [
            'WITH',
            2,
        ],
        // Used for options.
        '_OPTIONS' => [
            '_OPTIONS',
            1,
        ],
        'AS' => [
            'AS',
            2,
        ],
    ];

    /** @var WithKeyword[] */
    public $withers = [];

    /**
     * holds the CTE parser.
     *
     * @var Parser|null
     */
    public $cteStatementParser;

    /**
     * @param Parser     $parser the instance that requests parsing
     * @param TokensList $list   the list of tokens to be parsed
     *
     * @return void
     */
    public function parse(Parser $parser, TokensList $list)
    {
        /**
         * The state of the parser.
         *
         * Below are the states of the parser.
         *
         *      0 ---------------- [ name ] -----------------> 1
         *
         *      1 ------------------ [ ( ] ------------------> 2
         *
         *      2 ------------------ [ AS ] -----------------> 3
         *
         *      3 ------------------ [ ( ] ------------------> 4
         *
         *      4 ------------------ [ , ] ------------------> 1
         *
         *      4 ----- [ SELECT/UPDATE/DELETE/INSERT ] -----> 5
         *
         * @var int
         */
        $state = 0;
        $wither = null;

        ++$list->idx; // Skipping `WITH`.

        // parse any options if provided
        $this->options = OptionsArray::parse($parser, $list, static::$OPTIONS);
        ++$list->idx;

        for (; $list->idx < $list->count; ++$list->idx) {
            /**
             * Token parsed at this moment.
             */
            $token = $list->tokens[$list->idx];

            // Skipping whitespaces and comments.
            if ($token->type === Token::TYPE_WHITESPACE || $token->type === Token::TYPE_COMMENT) {
                continue;
            }

            if ($state === 0) {
                if ($token->type !== Token::TYPE_NONE) {
                    $parser->error('The name of the CTE was expected.', $token);
                    break;
                }

                $wither = $token->value;
                $this->withers[$wither] = new WithKeyword($wither);
                $state = 1;
            } elseif ($state === 1) {
                if ($token->type === Token::TYPE_OPERATOR && $token->value === '(') {
                    $this->withers[$wither]->columns = Array2d::parse($parser, $list);
                    $state = 2;
                } elseif ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'AS') {
                    $state = 3;
                } else {
                    $parser->error('Unexpected token.', $token);
                    break;
                }
            } elseif ($state === 2) {
                if (! ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'AS')) {
                    $parser->error('AS keyword was expected.', $token);
                    break;
                }

                $state = 3;
            } elseif ($state === 3) {
                $idxBeforeGetNext = $list->idx;

                $list->idx++; // Ignore the current token
                $nextKeyword = $list->getNext();

                if (! ($token->value === '(' && ($nextKeyword && $nextKeyword->value === 'SELECT'))) {
                    $parser->error('Subquery of the CTE was expected.', $token);
                    $list->idx = $idxBeforeGetNext;
                    break;
                }

                // Restore the index
                $list->idx = $idxBeforeGetNext;

                ++$list->idx;
                $subList = $this->getSubTokenList($list);
                if ($subList instanceof ParserException) {
                    $parser->errors[] = $subList;
                    break;
                }

                $subParser = new Parser($subList);

                if (count($subParser->errors)) {
                    foreach ($subParser->errors as $error) {
                        $parser->errors[] = $error;
                    }

                    break;
                }

                $this->withers[$wither]->statement = $subParser;

                $state = 4;
            } elseif ($state === 4) {
                if ($token->value === ',') {
                    // There's another WITH expression to parse, go back to state=0
                    $state = 0;
                    continue;
                }

                if (
                    $token->type === Token::TYPE_KEYWORD && (
                    $token->value === 'SELECT'
                    || $token->value === 'INSERT'
                    || $token->value === 'UPDATE'
                    || $token->value === 'DELETE'
                    )
                ) {
                    $state = 5;
                    --$list->idx;
                    continue;
                }

                $parser->error('An expression was expected.', $token);
                break;
            } elseif ($state === 5) {
                /**
                 * We need to parse all of the remaining tokens becuase mostly, they are only the CTE expression
                 * which's mostly is SELECT, or INSERT, UPDATE, or delete statement.
                 * e.g: INSERT .. ( SELECT 1 ) SELECT col1 FROM cte ON DUPLICATE KEY UPDATE col_name = 3.
                 * The issue is that, `ON DUPLICATE KEY UPDATE col_name = 3` is related to the main INSERT query
                 * not the cte expression (SELECT col1 FROM cte) we need to determine the end of the expression
                 * to parse `ON DUPLICATE KEY UPDATE` from the InsertStatement parser instead.
                 */

                // Index of the last parsed token by default would be the last token in the $list, because we're
                // assuming that all remaining tokens at state 4, are related to the expression.
                $idxOfLastParsedToken = $list->count - 1;
                // Index before search to be able to restore the index.
                $idxBeforeSearch = $list->idx;
                // Length of expression tokens is null by default, in order for the $subList to start
                // from $list->idx to the end of the $list.
                $lengthOfExpressionTokens = null;

                if ($list->getNextOfTypeAndValue(Token::TYPE_KEYWORD, 'ON')) {
                    // (-1) because getNextOfTypeAndValue returned ON and increased the index.
                    $idxOfOn = $list->idx - 1;
                    // We want to make sure that it's `ON DUPLICATE KEY UPDATE`
                    $dubplicateToken = $list->getNext();
                    $keyToken = $list->getNext();
                    $updateToken = $list->getNext();
                    if (
                        $dubplicateToken && $dubplicateToken->keyword === 'DUPLICATE'
                        && ($keyToken && $keyToken->keyword === 'KEY')
                        && ($updateToken && $updateToken->keyword === 'UPDATE')
                    ) {
                        // Index of the last parsed token will be the token before the ON Keyword
                        $idxOfLastParsedToken = $idxOfOn - 1;
                        // The length of the expression tokens would be the difference
                        // between the first unrelated token `ON` and the idx
                        // before skipping the CTE tokens.
                        $lengthOfExpressionTokens = $idxOfOn - $idxBeforeSearch;
                    }
                }

                // Restore the index
                $list->idx = $idxBeforeSearch;

                $subList = new TokensList(array_slice($list->tokens, $list->idx, $lengthOfExpressionTokens));
                $subParser = new Parser($subList);
                if (count($subParser->errors)) {
                    foreach ($subParser->errors as $error) {
                        $parser->errors[] = $error;
                    }

                    break;
                }

                $this->cteStatementParser = $subParser;

                $list->idx = $idxOfLastParsedToken;
                break;
            }
        }

        // 5 is the only valid end state
        if ($state !== 5) {
             /**
             * Token parsed at this moment.
             */
            $token = $list->tokens[$list->idx];

            $parser->error('Unexpected end of the WITH CTE.', $token);
        }

        --$list->idx;
    }

    /**
     * {@inheritdoc}
     */
    public function build()
    {
        $str = 'WITH ';

        foreach ($this->withers as $wither) {
            $str .= $str === 'WITH ' ? '' : ', ';
            $str .= WithKeyword::build($wither);
        }

        $str .= ' ';

        if ($this->cteStatementParser) {
            foreach ($this->cteStatementParser->statements as $statement) {
                    $str .= $statement->build();
            }
        }

        return $str;
    }

    /**
     * Get tokens within the WITH expression to use them in another parser
     *
     * @return ParserException|TokensList
     */
    private function getSubTokenList(TokensList $list)
    {
        $idx = $list->idx;
        $token = $list->tokens[$list->idx];
        $openParenthesis = 0;

        while ($list->idx < $list->count) {
            if ($token->value === '(') {
                ++$openParenthesis;
            } elseif ($token->value === ')') {
                if (--$openParenthesis === -1) {
                    break;
                }
            }

            ++$list->idx;
            if (! isset($list->tokens[$list->idx])) {
                break;
            }

            $token = $list->tokens[$list->idx];
        }

        // performance improvement: return the error to avoid a try/catch in the loop
        if ($list->idx === $list->count) {
            --$list->idx;

            return new ParserException(
                Translator::gettext('A closing bracket was expected.'),
                $token
            );
        }

        $length = $list->idx - $idx;

        return new TokensList(array_slice($list->tokens, $idx, $length), $length);
    }
}

Filemanager

Name Type Size Permission Actions
AlterStatement.php File 4.13 KB 0644
AnalyzeStatement.php File 744 B 0644
BackupStatement.php File 631 B 0644
CallStatement.php File 716 B 0644
CheckStatement.php File 632 B 0644
ChecksumStatement.php File 553 B 0644
CreateStatement.php File 24.22 KB 0644
DeleteStatement.php File 11.19 KB 0644
DropStatement.php File 1.61 KB 0644
ExplainStatement.php File 9.07 KB 0644
InsertStatement.php File 7.2 KB 0644
LoadStatement.php File 11.05 KB 0644
LockStatement.php File 3.36 KB 0644
MaintenanceStatement.php File 1.47 KB 0644
NotImplementedStatement.php File 1.3 KB 0644
OptimizeStatement.php File 748 B 0644
PurgeStatement.php File 3.74 KB 0644
RenameStatement.php File 1.36 KB 0644
RepairStatement.php File 674 B 0644
ReplaceStatement.php File 4.97 KB 0644
RestoreStatement.php File 580 B 0644
SelectStatement.php File 8.27 KB 0644
SetStatement.php File 2.36 KB 0644
ShowStatement.php File 1.35 KB 0644
TransactionStatement.php File 2.47 KB 0644
TruncateStatement.php File 854 B 0644
UpdateStatement.php File 2.91 KB 0644
WithStatement.php File 11.07 KB 0644
Filemanager