Server IP : 85.214.239.14 / Your IP : 3.17.166.87 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /var/www/wordpress/phpMyAdmin/vendor/phpmyadmin/sql-parser/src/Statements/ |
Upload File : |
<?php /** * `LOAD` statement. */ declare(strict_types=1); namespace PhpMyAdmin\SqlParser\Statements; use PhpMyAdmin\SqlParser\Components\ArrayObj; use PhpMyAdmin\SqlParser\Components\Expression; use PhpMyAdmin\SqlParser\Components\ExpressionArray; use PhpMyAdmin\SqlParser\Components\OptionsArray; use PhpMyAdmin\SqlParser\Components\SetOperation; use PhpMyAdmin\SqlParser\Parser; use PhpMyAdmin\SqlParser\Statement; use PhpMyAdmin\SqlParser\Token; use PhpMyAdmin\SqlParser\TokensList; use function count; use function strlen; use function trim; /** * `LOAD` statement. * * LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name' * [REPLACE | IGNORE] * INTO TABLE tbl_name * [PARTITION (partition_name,...)] * [CHARACTER SET charset_name] * [{FIELDS | COLUMNS} * [TERMINATED BY 'string'] * [[OPTIONALLY] ENCLOSED BY 'char'] * [ESCAPED BY 'char'] * ] * [LINES * [STARTING BY 'string'] * [TERMINATED BY 'string'] * ] * [IGNORE number {LINES | ROWS}] * [(col_name_or_user_var,...)] * [SET col_name = expr,...] */ class LoadStatement extends Statement { /** * Options for `LOAD` statements and their slot ID. * * @var array */ public static $OPTIONS = [ 'LOW_PRIORITY' => 1, 'CONCURRENT' => 1, 'LOCAL' => 2, ]; /** * FIELDS/COLUMNS Options for `LOAD DATA...INFILE` statements. * * @var array */ public static $FIELDS_OPTIONS = [ 'TERMINATED BY' => [ 1, 'expr', ], 'OPTIONALLY' => 2, 'ENCLOSED BY' => [ 3, 'expr', ], 'ESCAPED BY' => [ 4, 'expr', ], ]; /** * LINES Options for `LOAD DATA...INFILE` statements. * * @var array */ public static $LINES_OPTIONS = [ 'STARTING BY' => [ 1, 'expr', ], 'TERMINATED BY' => [ 2, 'expr', ], ]; /** * File name being used to load data. * * @var Expression */ public $file_name; /** * Table used as destination for this statement. * * @var Expression */ public $table; /** * Partitions used as source for this statement. * * @var ArrayObj */ public $partition; /** * Character set used in this statement. * * @var Expression */ public $charset_name; /** * Options for FIELDS/COLUMNS keyword. * * @see static::$FIELDS_OPTIONS * * @var OptionsArray */ public $fields_options; /** * Whether to use `FIELDS` or `COLUMNS` while building. * * @var string */ public $fields_keyword; /** * Options for OPTIONS keyword. * * @see static::$LINES_OPTIONS * * @var OptionsArray */ public $lines_options; /** * Column names or user variables. * * @var Expression[] */ public $col_name_or_user_var; /** * SET clause's updated values(optional). * * @var SetOperation[] */ public $set; /** * Ignore 'number' LINES/ROWS. * * @var Expression */ public $ignore_number; /** * REPLACE/IGNORE Keyword. * * @var string */ public $replace_ignore; /** * LINES/ROWS Keyword. * * @var string */ public $lines_rows; /** * @return string */ public function build() { $ret = 'LOAD DATA ' . $this->options . ' INFILE ' . $this->file_name; if ($this->replace_ignore !== null) { $ret .= ' ' . trim($this->replace_ignore); } $ret .= ' INTO TABLE ' . $this->table; if ($this->partition !== null && strlen((string) $this->partition) > 0) { $ret .= ' PARTITION ' . ArrayObj::build($this->partition); } if ($this->charset_name !== null) { $ret .= ' CHARACTER SET ' . $this->charset_name; } if ($this->fields_keyword !== null) { $ret .= ' ' . $this->fields_keyword . ' ' . $this->fields_options; } if ($this->lines_options !== null && strlen((string) $this->lines_options) > 0) { $ret .= ' LINES ' . $this->lines_options; } if ($this->ignore_number !== null) { $ret .= ' IGNORE ' . $this->ignore_number . ' ' . $this->lines_rows; } if ($this->col_name_or_user_var !== null && count($this->col_name_or_user_var) > 0) { $ret .= ' ' . ExpressionArray::build($this->col_name_or_user_var); } if ($this->set !== null && count($this->set) > 0) { $ret .= ' SET ' . SetOperation::build($this->set); } return $ret; } /** * @param Parser $parser the instance that requests parsing * @param TokensList $list the list of tokens to be parsed */ public function parse(Parser $parser, TokensList $list) { ++$list->idx; // Skipping `LOAD DATA`. // parse any options if provided $this->options = OptionsArray::parse( $parser, $list, static::$OPTIONS ); ++$list->idx; /** * The state of the parser. * * @var int */ $state = 0; for (; $list->idx < $list->count; ++$list->idx) { /** * Token parsed at this moment. * * @var Token */ $token = $list->tokens[$list->idx]; // End of statement. if ($token->type === Token::TYPE_DELIMITER) { break; } // Skipping whitespaces and comments. if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) { continue; } if ($state === 0) { if ($token->type === Token::TYPE_KEYWORD && $token->keyword !== 'INFILE' ) { $parser->error('Unexpected keyword.', $token); break; } elseif ($token->type !== Token::TYPE_KEYWORD) { $parser->error('Unexpected token.', $token); break; } ++$list->idx; $this->file_name = Expression::parse( $parser, $list, ['parseField' => 'file'] ); $state = 1; } elseif ($state === 1) { if ($token->type === Token::TYPE_KEYWORD) { if ($token->keyword === 'REPLACE' || $token->keyword === 'IGNORE') { $this->replace_ignore = trim($token->keyword); } elseif ($token->keyword === 'INTO') { $state = 2; } } } elseif ($state === 2) { if ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'TABLE' ) { ++$list->idx; $this->table = Expression::parse($parser, $list, ['parseField' => 'table']); $state = 3; } else { $parser->error('Unexpected token.', $token); break; } } elseif ($state >= 3 && $state <= 7) { if ($token->type === Token::TYPE_KEYWORD) { $newState = $this->parseKeywordsAccordingToState( $parser, $list, $state ); if ($newState === $state) { // Avoid infinite loop break; } } elseif ($token->type === Token::TYPE_OPERATOR && $token->token === '(' ) { $this->col_name_or_user_var = ExpressionArray::parse($parser, $list); $state = 7; } else { $parser->error('Unexpected token.', $token); break; } } } --$list->idx; } public function parseFileOptions(Parser $parser, TokensList $list, $keyword = 'FIELDS') { ++$list->idx; if ($keyword === 'FIELDS' || $keyword === 'COLUMNS') { // parse field options $this->fields_options = OptionsArray::parse( $parser, $list, static::$FIELDS_OPTIONS ); $this->fields_keyword = $keyword; } else { // parse line options $this->lines_options = OptionsArray::parse( $parser, $list, static::$LINES_OPTIONS ); } } public function parseKeywordsAccordingToState($parser, $list, $state) { $token = $list->tokens[$list->idx]; switch ($state) { case 3: if ($token->keyword === 'PARTITION') { ++$list->idx; $this->partition = ArrayObj::parse($parser, $list); $state = 4; return $state; } // no break case 4: if ($token->keyword === 'CHARACTER SET') { ++$list->idx; $this->charset_name = Expression::parse($parser, $list); $state = 5; return $state; } // no break case 5: if ($token->keyword === 'FIELDS' || $token->keyword === 'COLUMNS' || $token->keyword === 'LINES' ) { $this->parseFileOptions($parser, $list, $token->value); $state = 6; return $state; } // no break case 6: if ($token->keyword === 'IGNORE') { ++$list->idx; $this->ignore_number = Expression::parse($parser, $list); $nextToken = $list->getNextOfType(Token::TYPE_KEYWORD); if ($nextToken->type === Token::TYPE_KEYWORD && (($nextToken->keyword === 'LINES') || ($nextToken->keyword === 'ROWS')) ) { $this->lines_rows = $nextToken->token; } $state = 7; return $state; } // no break case 7: if ($token->keyword === 'SET') { ++$list->idx; $this->set = SetOperation::parse($parser, $list); $state = 8; return $state; } // no break default: } return $state; } }