packages/ztd-query-mysql/src/Sql/OptionalInsertIntoNormalizer.php
1<?php
2
3declare(strict_types=1);
4
5namespace ZtdQuery\Platform\MySql\Sql;
6
7use PhpMyAdmin\SqlParser\Lexer;
8use PhpMyAdmin\SqlParser\Token;
9
10/**
11 * Optional Insert Into Normalizer.
12 *
13 * @visibility ZtdQuery\Platform\MySql
14 */
15final class OptionalInsertIntoNormalizer
16{
17 /**
18 * Normalize Optional Insert Into for the supplied MySQL input.
19 */
20 public function normalizeOptionalInsertInto(string $sql): string
21 {
22 $tokens = [];
23 foreach (Lexer::getTokens($sql)->tokens as $token) {
24 if (in_array($token->type, [Token::TYPE_WHITESPACE, Token::TYPE_COMMENT, Token::TYPE_DELIMITER], true)) {
25 continue;
26 }
27 $tokens[] = $token;
28 }
29
30 $insert = $tokens[0] ?? null;
31 if ($insert === null || $insert->keyword !== 'INSERT') {
32 return $sql;
33 }
34
35 $targetIndex = 1;
36 while (isset($tokens[$targetIndex]) && in_array(
37 $tokens[$targetIndex]->keyword,
38 ['LOW_PRIORITY', 'DELAYED', 'HIGH_PRIORITY', 'IGNORE'],
39 true,
40 )) {
41 $targetIndex++;
42 }
43
44 $target = $tokens[$targetIndex] ?? $insert;
45 if (!in_array($target->type, [Token::TYPE_NONE, Token::TYPE_SYMBOL], true)) {
46 return $sql;
47 }
48 if (!is_int($target->position)) {
49 return $sql;
50 }
51
52 return substr($sql, 0, $target->position) . 'INTO ' . substr($sql, $target->position);
53 }
54}
55