Skip to content

Commit a61700a

Browse files
committed
Implement DROP PRIMARY KEY and DROP CONSTRAINT for primary and unique keys
1 parent 5fdcef1 commit a61700a

File tree

2 files changed

+171
-18
lines changed

2 files changed

+171
-18
lines changed

tests/WP_SQLite_Driver_Metadata_Tests.php

Lines changed: 113 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,39 +1716,80 @@ public function testInformationSchemaAlterTableDropForeignKeys(): void {
17161716
);
17171717
}
17181718

1719-
public function testInformationSchemaAlterTableDropConstraint(): void {
1720-
$this->assertQuery( 'CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(255))' );
1721-
$this->assertQuery(
1722-
'CREATE TABLE t2 (
1723-
id INT,
1724-
CONSTRAINT fk1 FOREIGN KEY (id) REFERENCES t1 (id)
1725-
)'
1719+
public function testInformationSchemaAlterTableDropPrimaryKey(): void {
1720+
$this->assertQuery( 'CREATE TABLE t (id INT PRIMARY KEY, name VARCHAR(255))' );
1721+
1722+
$result = $this->assertQuery( 'SHOW CREATE TABLE t' );
1723+
$this->assertEquals(
1724+
array(
1725+
(object) array(
1726+
'Create Table' => implode(
1727+
"\n",
1728+
array(
1729+
'CREATE TABLE `t` (',
1730+
' `id` int NOT NULL,',
1731+
' `name` varchar(255) DEFAULT NULL,',
1732+
' PRIMARY KEY (`id`)',
1733+
') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci',
1734+
)
1735+
),
1736+
),
1737+
),
1738+
$result
17261739
);
17271740

1728-
$this->assertQuery( 'ALTER TABLE t2 DROP CONSTRAINT fk1' );
1741+
$this->assertQuery( 'ALTER TABLE t DROP PRIMARY KEY' );
17291742

1730-
// INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
1731-
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't2'" );
1743+
// INFORMATION_SCHEMA.TABLE_CONSTRAINTS
1744+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
17321745
$this->assertCount( 0, $result );
17331746

1734-
// INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
1735-
$result = $this->assertQuery( "SELECT * FROM information_schema.referential_constraints WHERE table_name = 't2'" );
1747+
// INFORMATION_SCHEMA.STATISTICS
1748+
$result = $this->assertQuery( "SELECT * FROM information_schema.statistics WHERE table_name = 't'" );
17361749
$this->assertCount( 0, $result );
17371750

1738-
// INFORMATION_SCHEMA.KEY_COLUMN_USAGE
1739-
$result = $this->assertQuery( "SELECT * FROM information_schema.key_column_usage WHERE table_name = 't2'" );
1751+
// SHOW CREATE TABLE
1752+
$result = $this->assertQuery( 'SHOW CREATE TABLE t' );
1753+
$this->assertEquals(
1754+
array(
1755+
(object) array(
1756+
'Create Table' => implode(
1757+
"\n",
1758+
array(
1759+
'CREATE TABLE `t` (',
1760+
' `id` int NOT NULL,',
1761+
' `name` varchar(255) DEFAULT NULL',
1762+
') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci',
1763+
)
1764+
),
1765+
),
1766+
),
1767+
$result
1768+
);
1769+
}
1770+
1771+
public function testInformationSchemaAlterTableDropUniqueKey(): void {
1772+
$this->assertQuery( 'CREATE TABLE t (id INT, name TEXT, CONSTRAINT c UNIQUE (name))' );
1773+
$this->assertQuery( 'ALTER TABLE t DROP INDEX c' );
1774+
1775+
// INFORMATION_SCHEMA.TABLE_CONSTRAINTS
1776+
$result = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't'" );
1777+
1778+
// INFORMATION_SCHEMA.STATISTICS
1779+
$result = $this->assertQuery( "SELECT * FROM information_schema.statistics WHERE table_name = 't'" );
17401780
$this->assertCount( 0, $result );
17411781

17421782
// SHOW CREATE TABLE
1743-
$result = $this->assertQuery( 'SHOW CREATE TABLE t2' );
1783+
$result = $this->assertQuery( 'SHOW CREATE TABLE t' );
17441784
$this->assertEquals(
17451785
array(
17461786
(object) array(
17471787
'Create Table' => implode(
17481788
"\n",
17491789
array(
1750-
'CREATE TABLE `t2` (',
1751-
' `id` int DEFAULT NULL',
1790+
'CREATE TABLE `t` (',
1791+
' `id` int DEFAULT NULL,',
1792+
' `name` text DEFAULT NULL',
17521793
') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci',
17531794
)
17541795
),
@@ -1758,6 +1799,61 @@ public function testInformationSchemaAlterTableDropConstraint(): void {
17581799
);
17591800
}
17601801

1802+
public function testInformationSchemaAlterTableDropConstraint(): void {
1803+
$this->assertQuery( 'CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(255))' );
1804+
$this->assertQuery(
1805+
'CREATE TABLE t2 (
1806+
id INT PRIMARY KEY,
1807+
name VARCHAR(255),
1808+
CONSTRAINT fk FOREIGN KEY (id) REFERENCES t1 (id),
1809+
CONSTRAINT name_unique UNIQUE (name)
1810+
)'
1811+
);
1812+
1813+
// Check the constraint records.
1814+
$table_constraints = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't2'" );
1815+
$referential_constraints = $this->assertQuery( "SELECT * FROM information_schema.referential_constraints WHERE table_name = 't2'" );
1816+
$key_column_usage = $this->assertQuery( "SELECT * FROM information_schema.key_column_usage WHERE table_name = 't2'" );
1817+
$statistics = $this->assertQuery( "SELECT * FROM information_schema.statistics WHERE table_name = 't2'" );
1818+
$this->assertCount( 3, $table_constraints );
1819+
$this->assertCount( 1, $referential_constraints );
1820+
$this->assertCount( 3, $key_column_usage );
1821+
$this->assertCount( 2, $statistics );
1822+
1823+
// Drop the primary key constraint.
1824+
$this->assertQuery( 'ALTER TABLE t2 DROP PRIMARY KEY' );
1825+
$table_constraints = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't2'" );
1826+
$referential_constraints = $this->assertQuery( "SELECT * FROM information_schema.referential_constraints WHERE table_name = 't2'" );
1827+
$key_column_usage = $this->assertQuery( "SELECT * FROM information_schema.key_column_usage WHERE table_name = 't2'" );
1828+
$statistics = $this->assertQuery( "SELECT * FROM information_schema.statistics WHERE table_name = 't2'" );
1829+
$this->assertCount( 2, $table_constraints );
1830+
$this->assertCount( 1, $referential_constraints );
1831+
$this->assertCount( 2, $key_column_usage );
1832+
$this->assertCount( 1, $statistics );
1833+
1834+
// Drop the unique key constraint.
1835+
$this->assertQuery( 'ALTER TABLE t2 DROP CONSTRAINT name_unique' );
1836+
$table_constraints = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't2'" );
1837+
$referential_constraints = $this->assertQuery( "SELECT * FROM information_schema.referential_constraints WHERE table_name = 't2'" );
1838+
$key_column_usage = $this->assertQuery( "SELECT * FROM information_schema.key_column_usage WHERE table_name = 't2'" );
1839+
$statistics = $this->assertQuery( "SELECT * FROM information_schema.statistics WHERE table_name = 't2'" );
1840+
$this->assertCount( 1, $table_constraints );
1841+
$this->assertCount( 1, $referential_constraints );
1842+
$this->assertCount( 1, $key_column_usage );
1843+
$this->assertCount( 0, $statistics );
1844+
1845+
// Drop the foreign key constraint.
1846+
$this->assertQuery( 'ALTER TABLE t2 DROP FOREIGN KEY fk' );
1847+
$table_constraints = $this->assertQuery( "SELECT * FROM information_schema.table_constraints WHERE table_name = 't2'" );
1848+
$referential_constraints = $this->assertQuery( "SELECT * FROM information_schema.referential_constraints WHERE table_name = 't2'" );
1849+
$key_column_usage = $this->assertQuery( "SELECT * FROM information_schema.key_column_usage WHERE table_name = 't2'" );
1850+
$statistics = $this->assertQuery( "SELECT * FROM information_schema.statistics WHERE table_name = 't2'" );
1851+
$this->assertCount( 0, $table_constraints );
1852+
$this->assertCount( 0, $referential_constraints );
1853+
$this->assertCount( 0, $key_column_usage );
1854+
$this->assertCount( 0, $statistics );
1855+
}
1856+
17611857
public function testInformationSchemaAlterTableDropMissingConstraint(): void {
17621858
$this->assertQuery( 'CREATE TABLE t1 (id INT PRIMARY KEY)' );
17631859

wp-includes/sqlite-ast/class-wp-sqlite-information-schema-builder.php

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,12 @@ public function record_alter_table( WP_Parser_Node $node ): void {
648648
continue;
649649
}
650650

651+
// DROP PRIMARY KEY
652+
if ( $action->has_child_token( WP_MySQL_Lexer::PRIMARY_SYMBOL ) ) {
653+
$this->record_drop_key( $table_is_temporary, $table_name, 'PRIMARY' );
654+
continue;
655+
}
656+
651657
// DROP FOREIGN KEY
652658
if ( $action->has_child_token( WP_MySQL_Lexer::FOREIGN_SYMBOL ) ) {
653659
$field_identifier = $action->get_first_child_node( 'fieldIdentifier' );
@@ -1263,7 +1269,11 @@ private function record_drop_constraint(
12631269
}
12641270

12651271
$constraint_type = $constraint_types[0];
1266-
if ( 'FOREIGN KEY' === $constraint_type ) {
1272+
if ( 'PRIMARY KEY' === $constraint_type ) {
1273+
$this->record_drop_key( $table_is_temporary, $table_name, 'PRIMARY' );
1274+
} elseif ( 'UNIQUE' === $constraint_type ) {
1275+
$this->record_drop_key( $table_is_temporary, $table_name, $name );
1276+
} elseif ( 'FOREIGN KEY' === $constraint_type ) {
12671277
$this->record_drop_foreign_key( $table_is_temporary, $table_name, $name );
12681278
} else {
12691279
throw new \Exception(
@@ -1272,6 +1282,53 @@ private function record_drop_constraint(
12721282
}
12731283
}
12741284

1285+
/**
1286+
* Analyze DROP PRIMARY KEY or DROP UNIQUE statement and record data
1287+
* in the information schema.
1288+
*
1289+
* @param bool $table_is_temporary Whether the table is temporary.
1290+
* @param string $table_name The table name.
1291+
* @param mixed $name The constraint name.
1292+
*/
1293+
private function record_drop_key(
1294+
bool $table_is_temporary,
1295+
string $table_name,
1296+
string $name
1297+
): void {
1298+
$this->delete_values(
1299+
$this->get_table_name( $table_is_temporary, 'table_constraints' ),
1300+
array(
1301+
'TABLE_SCHEMA' => $this->db_name,
1302+
'TABLE_NAME' => $table_name,
1303+
'CONSTRAINT_NAME' => $name,
1304+
)
1305+
);
1306+
1307+
$this->delete_values(
1308+
$this->get_table_name( $table_is_temporary, 'statistics' ),
1309+
array(
1310+
'TABLE_SCHEMA' => $this->db_name,
1311+
'TABLE_NAME' => $table_name,
1312+
'INDEX_NAME' => $name,
1313+
)
1314+
);
1315+
1316+
$this->delete_values(
1317+
$this->get_table_name( $table_is_temporary, 'key_column_usage' ),
1318+
array(
1319+
'TABLE_SCHEMA' => $this->db_name,
1320+
'TABLE_NAME' => $table_name,
1321+
'CONSTRAINT_NAME' => $name,
1322+
1323+
// Remove only PRIMARY/UNIQUE key records; not FOREIGN KEY data.
1324+
'REFERENCED_TABLE_SCHEMA' => null,
1325+
)
1326+
);
1327+
1328+
// Sync column info from constraint data.
1329+
$this->sync_column_key_info( $table_is_temporary, $table_name );
1330+
}
1331+
12751332
/**
12761333
* Analyze DROP FOREIGN KEY statement and record data in the information schema.
12771334
*

0 commit comments

Comments
 (0)