packages/sql-faker/src/PostgreSql/Generation/Rewrite/Column/ForeignKeyActionRule.php

1<?php
2
3declare(strict_types=1);
4
5namespace SqlFaker\PostgreSql\Generation\Rewrite\Column;
6
7use Override;
8use SqlFaker\Generation\Token\RewriteRule;
9use SqlFaker\Generation\Token\TerminalSequence;
10
11/**
12 * key_update rejects SET NULL/DEFAULT column lists; key_delete permits them.
13 * @see https://github.com/postgres/postgres/blob/REL_17_2/src/backend/parser/gram.y#L4432-L4444
14 */
15final class ForeignKeyActionRule implements RewriteRule
16{
17    /**
18     * Keeps the action and removes only its update-specific column list.
19     */
20    #[Override]
21    public function rewrite(TerminalSequence $sequence): TerminalSequence
22    {
23        foreach ($sequence->occurrences('key_update') as $owner) {
24            $action = $sequence->child($owner, 'key_action');
25            $columns = $action === null ? null : $sequence->child($action->id, 'opt_column_list');
26            $range = $columns === null ? null : $sequence->range($columns->id);
27            if ($range !== null) {
28                $sequence = $sequence->replace($range[0], $range[1] - $range[0], [], 'gram.y:key_update:column-list');
29            }
30        }
31        return $sequence;
32    }
33}
34