From 6771b48c20a7997f120fbe27bea53e295c1dfafd Mon Sep 17 00:00:00 2001 From: Michael Pretty Date: Tue, 20 Jun 2023 14:34:59 -0400 Subject: [PATCH] get_index_columns using SHOW INDEX FROM query instead of information_schema (#36427) * get_index_columns using SHOW INDEX FROM query instead of information_schema * returning empty array for clarity * ignore interpolated query * adding changelog entry * Adding unit tests for the updated DatabaseUtil::get_index_columns() --------- Co-authored-by: Michael Pretty --- ...-36374-use-show-index-instead-of-db-schema | 4 ++ .../src/Internal/Utilities/DatabaseUtil.php | 17 +++--- .../Internal/Utilities/DatabaseUtilTest.php | 60 +++++++++++++++++++ 3 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 plugins/woocommerce/changelog/fix-36374-use-show-index-instead-of-db-schema create mode 100644 plugins/woocommerce/tests/php/src/Internal/Utilities/DatabaseUtilTest.php diff --git a/plugins/woocommerce/changelog/fix-36374-use-show-index-instead-of-db-schema b/plugins/woocommerce/changelog/fix-36374-use-show-index-instead-of-db-schema new file mode 100644 index 00000000000..51838e3164b --- /dev/null +++ b/plugins/woocommerce/changelog/fix-36374-use-show-index-instead-of-db-schema @@ -0,0 +1,4 @@ +Significance: minor +Type: fix + +Convert DatabaseUtil::get_index_columns() to use SHOW INDEX FROM instead of INFORMATION_SCHEMA query diff --git a/plugins/woocommerce/src/Internal/Utilities/DatabaseUtil.php b/plugins/woocommerce/src/Internal/Utilities/DatabaseUtil.php index 758a8140814..9817625c4eb 100644 --- a/plugins/woocommerce/src/Internal/Utilities/DatabaseUtil.php +++ b/plugins/woocommerce/src/Internal/Utilities/DatabaseUtil.php @@ -126,15 +126,14 @@ class DatabaseUtil { $index_name = 'PRIMARY'; } - // phpcs:disable WordPress.DB.PreparedSQL - return $wpdb->get_col( - " -SELECT column_name FROM INFORMATION_SCHEMA.STATISTICS -WHERE table_name='$table_name' -AND table_schema='" . DB_NAME . "' -AND index_name='$index_name'" - ); - // phpcs:enable WordPress.DB.PreparedSQL + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared + $results = $wpdb->get_results( $wpdb->prepare( "SHOW INDEX FROM $table_name WHERE Key_name = %s", $index_name ) ); + + if ( empty( $results ) ) { + return array(); + } + + return array_column( $results, 'Column_name' ); } /** diff --git a/plugins/woocommerce/tests/php/src/Internal/Utilities/DatabaseUtilTest.php b/plugins/woocommerce/tests/php/src/Internal/Utilities/DatabaseUtilTest.php new file mode 100644 index 00000000000..a00c57dc627 --- /dev/null +++ b/plugins/woocommerce/tests/php/src/Internal/Utilities/DatabaseUtilTest.php @@ -0,0 +1,60 @@ +sut = wc_get_container()->get( DatabaseUtil::class ); + parent::set_up(); + } + + /** + * @testdox Test that get_index_columns() will default to return the primary key index columns. + */ + public function test_get_index_columns_returns_primary_index_by_default() { + global $wpdb; + + $this->assertEquals( + array( 'product_id' ), + $this->sut->get_index_columns( $wpdb->prefix . 'wc_product_meta_lookup' ) + ); + } + + /** + * @testdox Test that get_index_columns() will return an array containing all columns of a multi-column index. + */ + public function test_get_index_columns_returns_multicolumn_index() { + global $wpdb; + + $this->assertEquals( + array( 'min_price', 'max_price' ), + $this->sut->get_index_columns( $wpdb->prefix . 'wc_product_meta_lookup', 'min_max_price' ) + ); + } + + /** + * @testdox Test that giving a non-existent index name to get_index_columns() will return an empty array. + */ + public function test_get_index_columns_returns_empty_for_invalid_index() { + global $wpdb; + + $this->assertEmpty( + $this->sut->get_index_columns( $wpdb->prefix . 'wc_product_meta_lookup', 'invalid_index_name' ) + ); + } +}