Skip to content

Commit dbefb5b

Browse files
authored
Migrations bug (#2305)
* fix: typed $default in schema DSL + NodeModifier dispatch refactor * fix: normalize check constraint expression round-trip through pg_get_constraintdef * fix: normalize domain default through normalizeDefault() in PgCatalogProvider * fix: EXCLUDE constraint and index predicate idempotency, DSL/value-object boundary cleanup * fix: read trigger WHEN clause from pg_trigger, simplify Parser DI * fix: read unique constraint nullsNotDistinct from pg_index * fix: dsl definitions
1 parent ad236e0 commit dbefb5b

69 files changed

Lines changed: 2382 additions & 264 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

documentation/components/libs/postgresql.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -596,9 +596,9 @@ class ColumnCounter implements NodeVisitor
596596
{
597597
public int $count = 0;
598598

599-
public static function nodeClass(): string
599+
public static function nodeClasses(): array
600600
{
601-
return ColumnRef::class;
601+
return [ColumnRef::class];
602602
}
603603

604604
public function enter(object $node): ?int
@@ -629,15 +629,15 @@ interface NodeVisitor
629629
public const DONT_TRAVERSE_CHILDREN = 1;
630630
public const STOP_TRAVERSAL = 2;
631631

632-
/** @return class-string */
633-
public static function nodeClass(): string;
632+
/** @return list<class-string> */
633+
public static function nodeClasses(): array;
634634

635635
public function enter(object $node): ?int;
636636
public function leave(object $node): ?int;
637637
}
638638
```
639639

640-
Visitors declare which node type they handle via `nodeClass()`. Return values:
640+
Visitors declare which node types they handle via `nodeClasses()` (one or many). Return values:
641641

642642
- `null` - continue traversal
643643
- `DONT_TRAVERSE_CHILDREN` - skip children (from `enter()` only)
@@ -663,9 +663,9 @@ use function Flow\PostgreSql\DSL\{sql_parse, sql_deparse};
663663

664664
final readonly class AddDistinctModifier implements NodeModifier
665665
{
666-
public static function nodeClass(): string
666+
public static function nodeClasses(): array
667667
{
668-
return SelectStmt::class;
668+
return [SelectStmt::class];
669669
}
670670

671671
public function modify(object $node, ModificationContext $context): int|object|null
@@ -690,8 +690,8 @@ echo sql_deparse($query); // SELECT DISTINCT id, name FROM users
690690
```php
691691
interface NodeModifier
692692
{
693-
/** @return class-string */
694-
public static function nodeClass(): string;
693+
/** @return list<class-string> */
694+
public static function nodeClasses(): array;
695695

696696
public function modify(object $node, ModificationContext $context): int|object|null;
697697
}

src/bridge/symfony/postgresql-messenger/src/Flow/Bridge/Symfony/PostgreSQLMessenger/MessengerCatalogProvider.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@ public function get() : Catalog
3333
),
3434
schema_column_text('body', nullable: false),
3535
schema_column_text('headers', nullable: false),
36-
schema_column_varchar('queue_name', 190, nullable: false),
36+
schema_column_varchar('queue_name', 190, nullable: false, default: 'default'),
3737
schema_column_timestamp_tz('created_at', nullable: false),
3838
schema_column_timestamp_tz('available_at', nullable: false),
3939
schema_column_timestamp_tz('delivered_at', nullable: true),
4040
],
4141
primaryKey: schema_primary_key(['id']),
4242
indexes: [
43-
schema_index($this->tableName . '_queue_name_idx', ['queue_name']),
44-
schema_index($this->tableName . '_available_at_idx', ['available_at']),
45-
schema_index($this->tableName . '_delivered_at_idx', ['delivered_at']),
43+
schema_index('idx_' . $this->tableName . '_queue_name', ['queue_name']),
44+
schema_index('idx_' . $this->tableName . '_available_at', ['available_at']),
45+
schema_index('idx_' . $this->tableName . '_delivered_at', ['delivered_at']),
4646
],
4747
schema: $this->schemaName,
4848
),

src/bridge/symfony/postgresql-messenger/tests/Flow/Bridge/Symfony/PostgreSQLMessenger/Tests/Unit/MessengerCatalogProviderTest.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,17 @@ public function test_index_names_use_custom_table_name_prefix() : void
6464
$provider->get()->get('public')->tables[0]->indexes,
6565
);
6666

67-
self::assertContains('my_queue_queue_name_idx', $indexNames);
68-
self::assertContains('my_queue_available_at_idx', $indexNames);
69-
self::assertContains('my_queue_delivered_at_idx', $indexNames);
67+
self::assertContains('idx_my_queue_queue_name', $indexNames);
68+
self::assertContains('idx_my_queue_available_at', $indexNames);
69+
self::assertContains('idx_my_queue_delivered_at', $indexNames);
70+
}
71+
72+
public function test_queue_name_has_default_value() : void
73+
{
74+
$provider = new MessengerCatalogProvider();
75+
$queueNameColumn = $provider->get()->get('public')->tables[0]->column('queue_name');
76+
77+
self::assertSame("'default'", $queueNameColumn->default);
7078
}
7179

7280
public function test_table_has_custom_name_and_schema() : void

src/lib/postgresql/src/Flow/PostgreSql/AST/NodeModifier.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace Flow\PostgreSql\AST;
66

7+
use Google\Protobuf\Internal\Message;
8+
79
/**
810
* Interface for AST node modifiers.
911
*
@@ -23,11 +25,14 @@ interface NodeModifier
2325
public const STOP_TRAVERSAL = 2;
2426

2527
/**
26-
* Returns the fully qualified class name of the node type this modifier handles.
28+
* Returns the fully qualified class names of the node types this modifier handles.
29+
*
30+
* A modifier may handle more than one node type; the traverser will dispatch it
31+
* for every type listed here.
2732
*
28-
* @return class-string The node class this modifier is registered for
33+
* @return list<class-string<Message>> The node classes this modifier is registered for
2934
*/
30-
public static function nodeClass() : string;
35+
public static function nodeClasses() : array;
3136

3237
/**
3338
* Called to modify a node of the registered type.
@@ -38,7 +43,7 @@ public static function nodeClass() : string;
3843
* - Return STOP_TRAVERSAL to stop the entire traversal
3944
* - Return a new node to replace the current node (used for wrapping operations)
4045
*
41-
* @param object $node The node instance to modify (type depends on nodeClass())
46+
* @param object $node The node instance to modify (one of the types listed in nodeClasses())
4247
* @param ModificationContext $context Context providing parent information
4348
*
4449
* @return null|int|object

src/lib/postgresql/src/Flow/PostgreSql/AST/NodeVisitor.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
namespace Flow\PostgreSql\AST;
66

7+
use Google\Protobuf\Internal\Message;
8+
79
/**
810
* Interface for AST node visitors.
911
*
1012
* Visitors are registered for specific node types and only receive nodes of that type.
11-
* Use the static nodeClass() method to declare which node type this visitor handles.
13+
* Use the static nodeClasses() method to declare which node types this visitor handles.
1214
*/
1315
interface NodeVisitor
1416
{
@@ -28,16 +30,19 @@ interface NodeVisitor
2830
public const STOP_TRAVERSAL = 2;
2931

3032
/**
31-
* Returns the fully qualified class name of the node type this visitor handles.
33+
* Returns the fully qualified class names of the node types this visitor handles.
34+
*
35+
* A visitor may handle more than one node type; the traverser will dispatch it
36+
* for every type listed here.
3237
*
33-
* @return class-string The node class this visitor is registered for
38+
* @return list<class-string<Message>> The node classes this visitor is registered for
3439
*/
35-
public static function nodeClass() : string;
40+
public static function nodeClasses() : array;
3641

3742
/**
3843
* Called when entering a node of the registered type.
3944
*
40-
* @param object $node The node instance (type depends on nodeClass())
45+
* @param object $node The node instance (one of the types listed in nodeClasses())
4146
*
4247
* @return null|int Return value determines traversal behavior:
4348
* - null: Continue traversal
@@ -49,7 +54,7 @@ public function enter(object $node) : ?int;
4954
/**
5055
* Called when leaving a node of the registered type.
5156
*
52-
* @param object $node The node instance (type depends on nodeClass())
57+
* @param object $node The node instance (one of the types listed in nodeClasses())
5358
*
5459
* @return null|int Return value determines traversal behavior:
5560
* - null: Continue traversal

src/lib/postgresql/src/Flow/PostgreSql/AST/Transformers/CountModifier.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
*/
2727
final readonly class CountModifier implements NodeModifier
2828
{
29-
public static function nodeClass() : string
29+
public static function nodeClasses() : array
3030
{
31-
return SelectStmt::class;
31+
return [SelectStmt::class];
3232
}
3333

3434
/** @phpstan-ignore return.unusedType (interface requires full signature) */

src/lib/postgresql/src/Flow/PostgreSql/AST/Transformers/ExplainModifier.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ public function __construct(
1414
) {
1515
}
1616

17-
public static function nodeClass() : string
17+
public static function nodeClasses() : array
1818
{
19-
return SelectStmt::class;
19+
return [SelectStmt::class];
2020
}
2121

2222
public function modify(object $node, ModificationContext $context) : ?object

src/lib/postgresql/src/Flow/PostgreSql/AST/Transformers/KeysetPaginationModifier.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ public function __construct(
4646
) {
4747
}
4848

49-
public static function nodeClass() : string
49+
public static function nodeClasses() : array
5050
{
51-
return SelectStmt::class;
51+
return [SelectStmt::class];
5252
}
5353

5454
/** @phpstan-ignore return.unusedType (interface requires full signature) */

src/lib/postgresql/src/Flow/PostgreSql/AST/Transformers/PaginationModifier.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ public function __construct(
3737
) {
3838
}
3939

40-
public static function nodeClass() : string
40+
public static function nodeClasses() : array
4141
{
42-
return SelectStmt::class;
42+
return [SelectStmt::class];
4343
}
4444

4545
public function modify(object $node, ModificationContext $context) : int|object|null

0 commit comments

Comments
 (0)