Limit index length to 191 characters by default, additionally connect HPOS to verify DB tooling. (#39250)
This commit is contained in:
commit
fa2aba5256
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: fix
|
||||
|
||||
Limit index length to 191 characters by default, additionally connect HPOS to verify DB tooling.
|
|
@ -8,6 +8,10 @@
|
|||
|
||||
use Automattic\Jetpack\Constants;
|
||||
use Automattic\WooCommerce\Admin\Notes\Notes;
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\DataSynchronizer;
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||
use Automattic\WooCommerce\Internal\Features\FeaturesController;
|
||||
use Automattic\WooCommerce\Internal\ProductAttributesLookup\DataRegenerator;
|
||||
use Automattic\WooCommerce\Internal\ProductDownloads\ApprovedDirectories\Register as Download_Directories;
|
||||
use Automattic\WooCommerce\Internal\ProductDownloads\ApprovedDirectories\Synchronize as Download_Directories_Sync;
|
||||
|
@ -483,9 +487,21 @@ class WC_Install {
|
|||
self::create_tables();
|
||||
}
|
||||
|
||||
$schema = self::get_schema();
|
||||
|
||||
$feature_controller = wc_get_container()->get( FeaturesController::class );
|
||||
if (
|
||||
$feature_controller->feature_is_enabled( DataSynchronizer::ORDERS_DATA_SYNC_ENABLED_OPTION )
|
||||
|| $feature_controller->feature_is_enabled( CustomOrdersTableController::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION )
|
||||
) {
|
||||
$schema .= wc_get_container()
|
||||
->get( OrdersTableDataStore::class )
|
||||
->get_database_schema();
|
||||
}
|
||||
|
||||
$missing_tables = wc_get_container()
|
||||
->get( DatabaseUtil::class )
|
||||
->get_missing_tables( self::get_schema() );
|
||||
->get_missing_tables( $schema );
|
||||
|
||||
if ( 0 < count( $missing_tables ) ) {
|
||||
if ( $modify_notice ) {
|
||||
|
@ -1145,12 +1161,7 @@ class WC_Install {
|
|||
$collate = $wpdb->get_charset_collate();
|
||||
}
|
||||
|
||||
/*
|
||||
* Indexes have a maximum size of 767 bytes. Historically, we haven't need to be concerned about that.
|
||||
* As of WP 4.2, however, they moved to utf8mb4, which uses 4 bytes per character. This means that an index which
|
||||
* used to have room for floor(767/3) = 255 characters, now only has room for floor(767/4) = 191 characters.
|
||||
*/
|
||||
$max_index_length = 191;
|
||||
$max_index_length = wc_get_container()->get( DatabaseUtil::class )->get_max_index_length();
|
||||
|
||||
$product_attributes_lookup_table_creation_sql = wc_get_container()->get( DataRegenerator::class )->get_table_creation_sql();
|
||||
|
||||
|
|
|
@ -2589,6 +2589,10 @@ FROM $order_meta_table
|
|||
$operational_data_table_name = $this->get_operational_data_table_name();
|
||||
$meta_table = $this->get_meta_table_name();
|
||||
|
||||
$max_index_length = $this->database_util->get_max_index_length();
|
||||
$composite_meta_value_index_length = max( $max_index_length - 8 - 100 - 1, 20 ); // 8 for order_id, 100 for meta_key, 10 minimum for meta_value.
|
||||
$composite_customer_id_email_length = max( $max_index_length - 20, 20 ); // 8 for customer_id, 20 minimum for email.
|
||||
|
||||
$sql = "
|
||||
CREATE TABLE $orders_table_name (
|
||||
id bigint(20) unsigned,
|
||||
|
@ -2611,8 +2615,8 @@ CREATE TABLE $orders_table_name (
|
|||
PRIMARY KEY (id),
|
||||
KEY status (status),
|
||||
KEY date_created (date_created_gmt),
|
||||
KEY customer_id_billing_email (customer_id, billing_email),
|
||||
KEY billing_email (billing_email),
|
||||
KEY customer_id_billing_email (customer_id, billing_email({$composite_customer_id_email_length})),
|
||||
KEY billing_email (billing_email($max_index_length)),
|
||||
KEY type_status (type, status),
|
||||
KEY parent_order_id (parent_order_id),
|
||||
KEY date_updated (date_updated_gmt)
|
||||
|
@ -2634,7 +2638,7 @@ CREATE TABLE $addresses_table_name (
|
|||
phone varchar(100) null,
|
||||
KEY order_id (order_id),
|
||||
UNIQUE KEY address_type_order_id (address_type, order_id),
|
||||
KEY email (email),
|
||||
KEY email (email($max_index_length)),
|
||||
KEY phone (phone)
|
||||
) $collate;
|
||||
CREATE TABLE $operational_data_table_name (
|
||||
|
@ -2664,8 +2668,8 @@ CREATE TABLE $meta_table (
|
|||
order_id bigint(20) unsigned null,
|
||||
meta_key varchar(255),
|
||||
meta_value text null,
|
||||
KEY meta_key_value (meta_key, meta_value(100)),
|
||||
KEY order_id_meta_key_meta_value (order_id, meta_key, meta_value(100))
|
||||
KEY meta_key_value (meta_key(100), meta_value($composite_meta_value_index_length)),
|
||||
KEY order_id_meta_key_meta_value (order_id, meta_key(100), meta_value($composite_meta_value_index_length))
|
||||
) $collate;
|
||||
";
|
||||
|
||||
|
|
|
@ -424,7 +424,10 @@ class FeaturesController {
|
|||
case 'new_navigation':
|
||||
return Init::TOGGLE_OPTION_NAME;
|
||||
case 'custom_order_tables':
|
||||
case CustomOrdersTableController::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION:
|
||||
return CustomOrdersTableController::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION;
|
||||
case DataSynchronizer::ORDERS_DATA_SYNC_ENABLED_OPTION:
|
||||
return DataSynchronizer::ORDERS_DATA_SYNC_ENABLED_OPTION;
|
||||
default:
|
||||
return "woocommerce_feature_{$feature_id}_enabled";
|
||||
}
|
||||
|
|
|
@ -268,4 +268,27 @@ $on_duplicate_clause
|
|||
return $wpdb->query( $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get max index length.
|
||||
*
|
||||
* @return int Max index length.
|
||||
*/
|
||||
public function get_max_index_length() : int {
|
||||
/**
|
||||
* Filters the maximum index length in the database.
|
||||
*
|
||||
* Indexes have a maximum size of 767 bytes. Historically, we haven't need to be concerned about that.
|
||||
* As of WP 4.2, however, they moved to utf8mb4, which uses 4 bytes per character. This means that an index which
|
||||
* used to have room for floor(767/3) = 255 characters, now only has room for floor(767/4) = 191 characters.
|
||||
*
|
||||
* Additionally, MyISAM engine also limits the index size to 1000 bytes. We add this filter so that interested folks on InnoDB engine can increase the size till allowed 3071 bytes.
|
||||
*
|
||||
* @param int $max_index_length Maximum index length. Default 191.
|
||||
*
|
||||
* @since 8.0.0
|
||||
*/
|
||||
$max_index_length = apply_filters( 'woocommerce_database_max_index_length', 191 );
|
||||
// Index length cannot be more than 768, which is 3078 bytes in utf8mb4 and max allowed by InnoDB engine.
|
||||
return min( absint( $max_index_length ), 767 );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue