diff --git a/README.md b/README.md index 801257d..3f272fb 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,8 @@ $this->commentOnColumn(table: 'address', name: 'name', comment: null)
Add index +> Note: Adding an index on a table will execute an "analyze" on indexed columns to update statistics + ```php $this->addIndex(name: 'idx_contact_email', table: 'contact', columns: ['email'], unique: false, usingMethod: 'GIN', where: 'country = "France"') ``` diff --git a/src/Doctrine/Migration.php b/src/Doctrine/Migration.php index 342b66e..1eebc26 100644 --- a/src/Doctrine/Migration.php +++ b/src/Doctrine/Migration.php @@ -37,7 +37,7 @@ public function down(Schema $schema): void $this->throwIrreversibleMigrationException(); } - protected function addUnsafeSql(string $sql, array $params = [], array $types = [], int $statementTimeout = null): void + protected function addUnsafeSql(string $sql, array $params = [], array $types = [], ?int $statementTimeout = null): void { if (null !== $statementTimeout) { parent::addSql("SET statement_timeout TO '{$statementTimeout}s'"); @@ -76,6 +76,10 @@ protected function addIndex( $where ? " WHERE $where" : '', )); $this->addUnsafeSql("SET lock_timeout TO '3s'"); + $this->addUnsafeSql(sprintf('ANALYZE %s (%s)', + $table, + implode(',', $columns), + )); } protected function dropIndex(string $name): void @@ -88,7 +92,7 @@ protected function renameIndex(string $from, string $to): void $this->addUnsafeSql(sprintf('ALTER INDEX %s RENAME TO %s', $from, $to)); } - protected function addColumn(string $table, string $name, string $type, string $defaultValue = null, bool $nullable = true): void + protected function addColumn(string $table, string $name, string $type, ?string $defaultValue = null, bool $nullable = true): void { if (null !== $defaultValue && u($defaultValue)->trim()->ignoreCase()->equalsTo('NULL')) { throw new AbortMigration(__METHOD__.' requires the usage of null PHP value instead of string one as default value.'); @@ -192,7 +196,7 @@ protected function createTable(string $table, array $columnDefinitions): void * @param string|null $options Can be used to add things like: * [ ON DELETE|ON UPDATE referential_action ] [ DEFERRABLE|NOT DEFERRABLE ] [ INITIALLY DEFERRED|INITIALLY IMMEDIATE ] */ - protected function addForeignKey(string $table, string $name, string $column, string $referenceTable, string $referenceColumn, string $options = null): void + protected function addForeignKey(string $table, string $name, string $column, string $referenceTable, string $referenceColumn, ?string $options = null): void { $this->addUnsafeSql(sprintf('ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s(%s)%s NOT VALID', $table, diff --git a/tests/Database/Doctrine/Migrations/MigrationTest.php b/tests/Database/Doctrine/Migrations/MigrationTest.php index 3c506a4..3b123aa 100644 --- a/tests/Database/Doctrine/Migrations/MigrationTest.php +++ b/tests/Database/Doctrine/Migrations/MigrationTest.php @@ -71,6 +71,7 @@ public function testAddIndexConcurrentlyWithOneColumn(): void 'SET lock_timeout TO \'0\'', 'CREATE INDEX CONCURRENTLY idx_approver_email ON approver (email)', 'SET lock_timeout TO \'3s\'', + 'ANALYZE approver (email)', ]); } @@ -83,6 +84,7 @@ public function testAddIndexConcurrentlyWithMultipleColumns(): void 'SET lock_timeout TO \'0\'', 'CREATE INDEX CONCURRENTLY idx_approver_first_name_email ON approver (first_name,email)', 'SET lock_timeout TO \'3s\'', + 'ANALYZE approver (first_name,email)', ]); } @@ -95,6 +97,7 @@ public function testAddUniqueIndexConcurrently(): void 'SET lock_timeout TO \'0\'', 'CREATE UNIQUE INDEX CONCURRENTLY uq_signer_email ON signer (email)', 'SET lock_timeout TO \'3s\'', + 'ANALYZE signer (email)', ]); } @@ -107,6 +110,7 @@ public function testAddIndexConcurrentlyUsingGinMethod(): void 'SET lock_timeout TO \'0\'', 'CREATE INDEX CONCURRENTLY idx_signer_email ON signer USING GIN(email)', 'SET lock_timeout TO \'3s\'', + 'ANALYZE signer (email)', ]); } @@ -119,6 +123,7 @@ public function testAddIndexConcurrentlyWhere(): void 'SET lock_timeout TO \'0\'', 'CREATE INDEX CONCURRENTLY idx_signer_email ON signer (email) WHERE name = "foo"', 'SET lock_timeout TO \'3s\'', + 'ANALYZE signer (email)', ]); } @@ -331,7 +336,7 @@ public function up(Schema $schema): void throw new \Exception('Unused for this test'); } - public function addUnsafeSql(string $sql, array $params = [], array $types = [], int $statementTimeout = null): void + public function addUnsafeSql(string $sql, array $params = [], array $types = [], ?int $statementTimeout = null): void { parent::addUnsafeSql($sql, $params, $types, $statementTimeout); } @@ -351,7 +356,7 @@ public function renameIndex(string $from, string $to): void parent::renameIndex($from, $to); } - public function addColumn(string $table, string $name, string $type, string $defaultValue = null, bool $nullable = true): void + public function addColumn(string $table, string $name, string $type, ?string $defaultValue = null, bool $nullable = true): void { parent::addColumn($table, $name, $type, $defaultValue, $nullable); } @@ -396,7 +401,7 @@ public function createTable(string $table, array $columnDefinitions): void parent::createTable($table, $columnDefinitions); } - public function addForeignKey(string $table, string $name, string $column, string $referenceTable, string $referenceColumn, string $options = null): void + public function addForeignKey(string $table, string $name, string $column, string $referenceTable, string $referenceColumn, ?string $options = null): void { parent::addForeignKey($table, $name, $column, $referenceTable, $referenceColumn, $options); }