Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address PK issues for show create table queries #127

Merged
merged 13 commits into from
Jul 19, 2024

Conversation

jeroenpf
Copy link
Contributor

Fixes: #123

In this PR i propose a refactor of the handling of show create table queries.

The main issue was that it is possible for a primary key to be composite (more than one column). The existing implementation only supports a single PK which causes the CREATE TABLE statement to be invalid. An example of such a table is the wp_term_relationships found in WordPress:

-- original MySQL statement
CREATE TABLE `wp_term_relationships` (
 `object_id` bigint(20) unsigned NOT NULL DEFAULT 0,
 `term_taxonomy_id` bigint(20) unsigned NOT NULL DEFAULT 0,
 `term_order` int(11) NOT NULL DEFAULT 0,
 PRIMARY KEY (`object_id`,`term_taxonomy_id`),
 KEY `term_taxonomy_id` (`term_taxonomy_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- statement produced by SQLite database integration
CREATE TABLE wp_term_relationships (
	`object_id` bigint(20) unsigned PRIMARY KEY AUTO_INCREMENT NOT NULL,
	`term_taxonomy_id` bigint(20) unsigned NOT NULL,
	`term_order` int(11) NOT NULL,
	KEY wp_term_relationships__term_taxonomy_id (term_taxonomy_id),
	UNIQUE KEY sqlite_autoindex_wp_term_relationships_1 (object_id, term_taxonomy_id)
);

SQLite also creates a unique key for any primary key (single or composite) which is something that is not necessary for MySQL and should be skipped from the final create statement.

In this PR

  • Refactor the code to separate things into smaller methods.
  • Add the PK definition before the keys and remove it from the column definitions.
  • Use backticks around table names, column names and key identifiers. This is to prevent issues when names of identifiers are using reserved keywords, ensure case sensitivity and allow them to contain special chars or spaces.
  • Improve detection of AUTO_INCREMENT column. Now we falsely mark columns as AUTO_INCREMENT just because they happen to be the primary key and be of type integer.
  • Fix creating an invalid UNIQUE KEY for the PK. When we find that the unique key is identical to the primary key, we can skip the unique key as it is redundant.

The final query output for show create wp_term_relationships looks as follows:

DROP TABLE IF EXISTS `wp_term_relationships`;
CREATE TABLE `wp_term_relationships` (
	`object_id` bigint(20) unsigned NOT NULL DEFAULT 0,
	`term_taxonomy_id` bigint(20) unsigned NOT NULL DEFAULT 0,
	`term_order` int(11) NOT NULL DEFAULT 0,
	PRIMARY KEY (`object_id`, `term_taxonomy_id`),
	KEY `wp_term_relationships__idx_term_taxonomy_id_x` (`term_taxonomy_id`)
);

Testing

  • Run the unit tests
  • Create a site with SQLite and then run $wpdb->query('show create wp_term_relationships') - The result should be a valid MySQL compatible query as shown above.

}

if ( '' !== $column->dflt_value ) {
$definition[] = 'DEFAULT ' . $column->dflt_value; // quotes?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we please expand this comment, it's unclear what it means.

Comment on lines +3539 to +3540
// If the PK columns are the same as the unique key columns, skip the key.
// This is because the PK is already unique in MySQL.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, these comments help a lot.

tests/WP_SQLite_Translator_Tests.php Show resolved Hide resolved
@aristath aristath changed the base branch from main to develop July 19, 2024 07:16
Copy link
Collaborator

@bgrgicak bgrgicak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jeroenpf the PR looks good to me. Thanks for working on this.

I just left one question about tests after we answer that I'm happy to merge the PR.

@jeroenpf
Copy link
Contributor Author

Thanks @bgrgicak for the review. I've addressed your latest comment so we should be good to go.

@bgrgicak bgrgicak merged commit 9a80eb8 into WordPress:develop Jul 19, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Show create incorrectly handles composite PKs
3 participants