Skip to content

Commit 2751bb4

Browse files
committed
fix(schema): drop PARTITIONS N from PostgreSQL hash partitioning
The shared Schema\Trait\Partitioning emits `PARTITIONS N` after the PARTITION BY clause when a count is set — but that's MySQL-only syntax. PostgreSQL rejects it: hash partitions are declared with separate `CREATE TABLE … PARTITION OF parent FOR VALUES WITH (modulus N, remainder R)` statements. Override compileCreatePartitioning in Schema\PostgreSQL to omit the count clause so $table->partitionByHash($expr, 4) silently drops the 4 instead of generating invalid DDL. Includes a regression test asserting the count is not emitted.
1 parent 69ed516 commit 2751bb4

3 files changed

Lines changed: 34 additions & 0 deletions

File tree

.claude/scheduled_tasks.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"sessionId":"1d4a85b1-8448-43af-af56-fde14c42dbc3","pid":21827,"procStart":"Fri May 8 10:26:06 2026","acquiredAt":1778287476666}

src/Query/Schema/PostgreSQL.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,4 +588,19 @@ public function dropPartition(string $table, string $name): Statement
588588
executor: $this->executor,
589589
);
590590
}
591+
592+
/**
593+
* PostgreSQL accepts `PARTITION BY {RANGE|LIST|HASH} (expr)` but not the
594+
* `PARTITIONS N` count modifier — that is MySQL-only. Override the shared
595+
* trait to omit the count.
596+
*/
597+
#[\Override]
598+
public function compileCreatePartitioning(Table $table): string
599+
{
600+
if ($table->partitionType === null) {
601+
return '';
602+
}
603+
604+
return 'PARTITION BY ' . $table->partitionType->value . '(' . $table->partitionExpression . ')';
605+
}
591606
}

tests/Query/Schema/PostgreSQLTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,24 @@ public function testCreateTableWithPartitionByHash(): void
10281028
$this->assertSame('CREATE TABLE "events" ("id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, PRIMARY KEY ("id")) PARTITION BY HASH(id)', $result->query);
10291029
}
10301030

1031+
public function testCreateTableWithPartitionByHashIgnoresCount(): void
1032+
{
1033+
// PostgreSQL does not support `PARTITIONS N` (MySQL-only). The count
1034+
// argument must be silently dropped from the generated DDL.
1035+
$schema = new Schema();
1036+
$result = $schema->table('events')
1037+
->id()
1038+
->partitionByHash('id', 4)
1039+
->create();
1040+
$this->assertBindingCount($result);
1041+
1042+
$this->assertSame(
1043+
'CREATE TABLE "events" ("id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, PRIMARY KEY ("id")) PARTITION BY HASH(id)',
1044+
$result->query,
1045+
);
1046+
$this->assertStringNotContainsString('PARTITIONS', $result->query);
1047+
}
1048+
10311049
public function testAlterWithForeignKeyOnDeleteAndUpdate(): void
10321050
{
10331051
$schema = new Schema();

0 commit comments

Comments
 (0)