Loading core/modules/pgsql/src/Driver/Database/pgsql/Insert.php +12 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,18 @@ public function execute() { if (isset($table_information->serial_fields[0])) { $last_insert_id = $stmt->fetchField(); } if (!empty($this->fromQuery) && !empty($table_information->serial_fields)) { // Set the sequence value if the table has serial fields and the from // query is either using all fields or includes a serial field. $from_fields = $this->fromQuery->getFields(); foreach ($table_information->serial_fields as $index => $serial_field) { if (empty($from_fields) || isset($from_fields[$serial_field])) { $this->connection->query("SELECT setval('" . $table_information->sequences[$index] . "', MAX(" . $serial_field . ")) FROM {" . $this->table . "}"); } } } $this->connection->releaseSavepoint(); } catch (\Exception $e) { Loading core/tests/Drupal/KernelTests/Core/Database/InsertTest.php +43 −0 Original line number Diff line number Diff line Loading @@ -236,4 +236,47 @@ public function testInsertIntegrityViolation(): void { ->execute(); } /** * Tests inserting from a select into a table that has a serial primary key. */ public function testInsertFromWithSerialKey(): void { // Create a copy of the test table. $schema = database_test_schema(); $this->connection->schema()->createTable('test_backup', $schema['test']); $this->connection->insert('test_backup')->from($this->connection->select('test')->fields('test'))->execute(); $this->assertSame(4, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); $this->connection->insert('test_backup')->fields([ 'name' => 'Larry', 'age' => '30', ])->execute(); $this->assertSame(5, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); // Recreate table to reset the serial counters. $this->connection->schema()->dropTable('test_backup'); $this->connection->schema()->createTable('test_backup', $schema['test']); // Add fields to the select query, so that the primary key is included. $this->connection->insert('test_backup')->from($this->connection->select('test')->fields('test', ['id', 'name']))->execute(); $this->assertSame(4, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); $this->connection->insert('test_backup')->fields([ 'name' => 'Larry', 'age' => '30', ])->execute(); $this->assertSame(5, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); // Recreate table to reset the serial counters. $this->connection->schema()->dropTable('test_backup'); $this->connection->schema()->createTable('test_backup', $schema['test']); // Add fields to the select query, so that the primary key is included. $this->connection->insert('test_backup')->from($this->connection->select('test')->fields('test', ['name']))->execute(); $this->assertSame(4, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); $this->connection->insert('test_backup')->fields([ 'name' => 'Larry', 'age' => '30', ])->execute(); $this->assertSame(5, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); } } Loading
core/modules/pgsql/src/Driver/Database/pgsql/Insert.php +12 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,18 @@ public function execute() { if (isset($table_information->serial_fields[0])) { $last_insert_id = $stmt->fetchField(); } if (!empty($this->fromQuery) && !empty($table_information->serial_fields)) { // Set the sequence value if the table has serial fields and the from // query is either using all fields or includes a serial field. $from_fields = $this->fromQuery->getFields(); foreach ($table_information->serial_fields as $index => $serial_field) { if (empty($from_fields) || isset($from_fields[$serial_field])) { $this->connection->query("SELECT setval('" . $table_information->sequences[$index] . "', MAX(" . $serial_field . ")) FROM {" . $this->table . "}"); } } } $this->connection->releaseSavepoint(); } catch (\Exception $e) { Loading
core/tests/Drupal/KernelTests/Core/Database/InsertTest.php +43 −0 Original line number Diff line number Diff line Loading @@ -236,4 +236,47 @@ public function testInsertIntegrityViolation(): void { ->execute(); } /** * Tests inserting from a select into a table that has a serial primary key. */ public function testInsertFromWithSerialKey(): void { // Create a copy of the test table. $schema = database_test_schema(); $this->connection->schema()->createTable('test_backup', $schema['test']); $this->connection->insert('test_backup')->from($this->connection->select('test')->fields('test'))->execute(); $this->assertSame(4, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); $this->connection->insert('test_backup')->fields([ 'name' => 'Larry', 'age' => '30', ])->execute(); $this->assertSame(5, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); // Recreate table to reset the serial counters. $this->connection->schema()->dropTable('test_backup'); $this->connection->schema()->createTable('test_backup', $schema['test']); // Add fields to the select query, so that the primary key is included. $this->connection->insert('test_backup')->from($this->connection->select('test')->fields('test', ['id', 'name']))->execute(); $this->assertSame(4, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); $this->connection->insert('test_backup')->fields([ 'name' => 'Larry', 'age' => '30', ])->execute(); $this->assertSame(5, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); // Recreate table to reset the serial counters. $this->connection->schema()->dropTable('test_backup'); $this->connection->schema()->createTable('test_backup', $schema['test']); // Add fields to the select query, so that the primary key is included. $this->connection->insert('test_backup')->from($this->connection->select('test')->fields('test', ['name']))->execute(); $this->assertSame(4, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); $this->connection->insert('test_backup')->fields([ 'name' => 'Larry', 'age' => '30', ])->execute(); $this->assertSame(5, (int) $this->connection->select('test_backup')->countQuery()->execute()->fetchField()); } }