|
6 | 6 |
|
7 | 7 | use PhpMyAdmin\SqlParser\Component; |
8 | 8 | use PhpMyAdmin\SqlParser\Context; |
9 | | -use PhpMyAdmin\SqlParser\Parser; |
10 | | -use PhpMyAdmin\SqlParser\Token; |
11 | | -use PhpMyAdmin\SqlParser\TokensList; |
12 | | -use PhpMyAdmin\SqlParser\TokenType; |
13 | 9 |
|
14 | | -use function implode; |
15 | 10 | use function trim; |
16 | 11 |
|
17 | 12 | /** |
|
21 | 16 | */ |
22 | 17 | final class CreateDefinition implements Component |
23 | 18 | { |
24 | | - /** |
25 | | - * All field options. |
26 | | - */ |
27 | | - private const FIELD_OPTIONS = [ |
28 | | - // Tells the `OptionsArray` to not sort the options. |
29 | | - // See the note below. |
30 | | - '_UNSORTED' => true, |
31 | | - |
32 | | - 'NOT NULL' => 1, |
33 | | - 'NULL' => 1, |
34 | | - 'DEFAULT' => [ |
35 | | - 2, |
36 | | - 'expr', |
37 | | - ['breakOnAlias' => true], |
38 | | - ], |
39 | | - /* Following are not according to grammar, but MySQL happily accepts |
40 | | - * these at any location */ |
41 | | - 'CHARSET' => [ |
42 | | - 2, |
43 | | - 'var', |
44 | | - ], |
45 | | - 'COLLATE' => [ |
46 | | - 3, |
47 | | - 'var', |
48 | | - ], |
49 | | - 'AUTO_INCREMENT' => 3, |
50 | | - 'KEY' => 4, |
51 | | - 'PRIMARY' => 4, |
52 | | - 'PRIMARY KEY' => 4, |
53 | | - 'UNIQUE' => 4, |
54 | | - 'UNIQUE KEY' => 4, |
55 | | - 'COMMENT' => [ |
56 | | - 5, |
57 | | - 'var', |
58 | | - ], |
59 | | - 'COLUMN_FORMAT' => [ |
60 | | - 6, |
61 | | - 'var', |
62 | | - ], |
63 | | - 'ON UPDATE' => [ |
64 | | - 7, |
65 | | - 'expr', |
66 | | - ], |
67 | | - |
68 | | - // Generated columns options. |
69 | | - 'GENERATED ALWAYS' => 8, |
70 | | - 'AS' => [ |
71 | | - 9, |
72 | | - 'expr', |
73 | | - ['parenthesesDelimited' => true], |
74 | | - ], |
75 | | - 'VIRTUAL' => 10, |
76 | | - 'PERSISTENT' => 11, |
77 | | - 'STORED' => 11, |
78 | | - 'CHECK' => [ |
79 | | - 12, |
80 | | - 'expr', |
81 | | - ['parenthesesDelimited' => true], |
82 | | - ], |
83 | | - 'INVISIBLE' => 13, |
84 | | - 'ENFORCED' => 14, |
85 | | - 'NOT' => 15, |
86 | | - 'COMPRESSED' => 16, |
87 | | - // Common entries. |
88 | | - // |
89 | | - // NOTE: Some of the common options are not in the same order which |
90 | | - // causes troubles when checking if the options are in the right order. |
91 | | - // I should find a way to define multiple sets of options and make the |
92 | | - // parser select the right set. |
93 | | - // |
94 | | - // 'UNIQUE' => 4, |
95 | | - // 'UNIQUE KEY' => 4, |
96 | | - // 'COMMENT' => [5, 'var'], |
97 | | - // 'NOT NULL' => 1, |
98 | | - // 'NULL' => 1, |
99 | | - // 'PRIMARY' => 4, |
100 | | - // 'PRIMARY KEY' => 4, |
101 | | - ]; |
102 | | - |
103 | 19 | /** |
104 | 20 | * The name of the new column. |
105 | 21 | * |
@@ -167,149 +83,6 @@ public function __construct( |
167 | 83 | } |
168 | 84 | } |
169 | 85 |
|
170 | | - /** |
171 | | - * @param Parser $parser the parser that serves as context |
172 | | - * @param TokensList $list the list of tokens that are being parsed |
173 | | - * @param array<string, mixed> $options parameters for parsing |
174 | | - * |
175 | | - * @return CreateDefinition[] |
176 | | - */ |
177 | | - public static function parse(Parser $parser, TokensList $list, array $options = []): array |
178 | | - { |
179 | | - $ret = []; |
180 | | - |
181 | | - $expr = new static(); |
182 | | - |
183 | | - /** |
184 | | - * The state of the parser. |
185 | | - * |
186 | | - * Below are the states of the parser. |
187 | | - * |
188 | | - * 0 -----------------------[ ( ]------------------------> 1 |
189 | | - * |
190 | | - * 1 --------------------[ CONSTRAINT ]------------------> 1 |
191 | | - * 1 -----------------------[ key ]----------------------> 2 |
192 | | - * 1 -------------[ constraint / column name ]-----------> 2 |
193 | | - * |
194 | | - * 2 --------------------[ data type ]-------------------> 3 |
195 | | - * |
196 | | - * 3 ---------------------[ options ]--------------------> 4 |
197 | | - * |
198 | | - * 4 --------------------[ REFERENCES ]------------------> 4 |
199 | | - * |
200 | | - * 5 ------------------------[ , ]-----------------------> 1 |
201 | | - * 5 ------------------------[ ) ]-----------------------> 6 (-1) |
202 | | - * |
203 | | - * @var int |
204 | | - */ |
205 | | - $state = 0; |
206 | | - |
207 | | - for (; $list->idx < $list->count; ++$list->idx) { |
208 | | - /** |
209 | | - * Token parsed at this moment. |
210 | | - */ |
211 | | - $token = $list->tokens[$list->idx]; |
212 | | - |
213 | | - // End of statement. |
214 | | - if ($token->type === TokenType::Delimiter) { |
215 | | - break; |
216 | | - } |
217 | | - |
218 | | - // Skipping whitespaces and comments. |
219 | | - if (($token->type === TokenType::Whitespace) || ($token->type === TokenType::Comment)) { |
220 | | - continue; |
221 | | - } |
222 | | - |
223 | | - if ($state === 0) { |
224 | | - if (($token->type !== TokenType::Operator) || ($token->value !== '(')) { |
225 | | - $parser->error('An opening bracket was expected.', $token); |
226 | | - |
227 | | - break; |
228 | | - } |
229 | | - |
230 | | - $state = 1; |
231 | | - } elseif ($state === 1) { |
232 | | - if ($token->type === TokenType::Keyword && $token->keyword === 'CONSTRAINT') { |
233 | | - $expr->isConstraint = true; |
234 | | - } elseif (($token->type === TokenType::Keyword) && ($token->flags & Token::FLAG_KEYWORD_KEY)) { |
235 | | - $expr->key = Key::parse($parser, $list); |
236 | | - $state = 4; |
237 | | - } elseif ($token->type === TokenType::Symbol || $token->type === TokenType::None) { |
238 | | - $expr->name = $token->value; |
239 | | - if (! $expr->isConstraint) { |
240 | | - $state = 2; |
241 | | - } |
242 | | - } elseif ($token->type === TokenType::Keyword) { |
243 | | - if ($token->flags & Token::FLAG_KEYWORD_RESERVED) { |
244 | | - // Reserved keywords can't be used |
245 | | - // as field names without backquotes |
246 | | - $parser->error( |
247 | | - 'A symbol name was expected! ' |
248 | | - . 'A reserved keyword can not be used ' |
249 | | - . 'as a column name without backquotes.', |
250 | | - $token, |
251 | | - ); |
252 | | - |
253 | | - return $ret; |
254 | | - } |
255 | | - |
256 | | - // Non-reserved keywords are allowed without backquotes |
257 | | - $expr->name = $token->value; |
258 | | - $state = 2; |
259 | | - } else { |
260 | | - $parser->error('A symbol name was expected!', $token); |
261 | | - |
262 | | - return $ret; |
263 | | - } |
264 | | - } elseif ($state === 2) { |
265 | | - $expr->type = DataType::parse($parser, $list); |
266 | | - $state = 3; |
267 | | - } elseif ($state === 3) { |
268 | | - $expr->options = OptionsArray::parse($parser, $list, self::FIELD_OPTIONS); |
269 | | - $state = 4; |
270 | | - } elseif ($state === 4) { |
271 | | - if ($token->type === TokenType::Keyword && $token->keyword === 'REFERENCES') { |
272 | | - ++$list->idx; // Skipping keyword 'REFERENCES'. |
273 | | - $expr->references = Reference::parse($parser, $list); |
274 | | - } else { |
275 | | - --$list->idx; |
276 | | - } |
277 | | - |
278 | | - $state = 5; |
279 | | - } elseif ($state === 5) { |
280 | | - if (! empty($expr->type) || ! empty($expr->key)) { |
281 | | - $ret[] = $expr; |
282 | | - } |
283 | | - |
284 | | - $expr = new static(); |
285 | | - if ($token->value === ',') { |
286 | | - $state = 1; |
287 | | - } elseif ($token->value === ')') { |
288 | | - $state = 6; |
289 | | - ++$list->idx; |
290 | | - break; |
291 | | - } else { |
292 | | - $parser->error('A comma or a closing bracket was expected.', $token); |
293 | | - $state = 0; |
294 | | - break; |
295 | | - } |
296 | | - } |
297 | | - } |
298 | | - |
299 | | - // Last iteration was not saved. |
300 | | - if (! empty($expr->type) || ! empty($expr->key)) { |
301 | | - $ret[] = $expr; |
302 | | - } |
303 | | - |
304 | | - if (($state !== 0) && ($state !== 6)) { |
305 | | - $parser->error('A closing bracket was expected.', $list->tokens[$list->idx - 1]); |
306 | | - } |
307 | | - |
308 | | - --$list->idx; |
309 | | - |
310 | | - return $ret; |
311 | | - } |
312 | | - |
313 | 86 | public function build(): string |
314 | 87 | { |
315 | 88 | $tmp = ''; |
@@ -340,12 +113,6 @@ public function build(): string |
340 | 113 | return trim($tmp); |
341 | 114 | } |
342 | 115 |
|
343 | | - /** @param CreateDefinition[] $component the component to be built */ |
344 | | - public static function buildAll(array $component): string |
345 | | - { |
346 | | - return "(\n " . implode(",\n ", $component) . "\n)"; |
347 | | - } |
348 | | - |
349 | 116 | public function __toString(): string |
350 | 117 | { |
351 | 118 | return $this->build(); |
|
0 commit comments