From 582ff13a113c4e3a27776c0948d00bc77ce011b7 Mon Sep 17 00:00:00 2001 From: wpdev Date: Sun, 27 Sep 2026 10:20:30 +0800 Subject: [PATCH] test(2meet-data-optimizer): compare site-wide rating sorts by sort key, not id - The PR-079 live router cases ran the HivePress rating sort on the whole site with an unqualified DECIMAL: native rounds 4.5 to 5 and orders its many ties by chance, so the id order passed or failed with the query plan. They now send DECIMAL(10,1), as the HivePress Rating field does, and compare each position's native sort key and found_posts; the flat-first / GROUP BY assertions stay. - Verify: live router 18/18 twice; all suites 56/56 - PR: PR-089b --- tests/live/suites/router.php | 37 ++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/tests/live/suites/router.php b/tests/live/suites/router.php index 40f326c..f57f83f 100644 --- a/tests/live/suites/router.php +++ b/tests/live/suites/router.php @@ -427,6 +427,7 @@ TMDO_Live::test( /** * HivePress-style sort-only search (rating__order), fields ids, first page. + * DECIMAL(10,1): what the HivePress Rating field (decimals 1) sends. * * @param string $order ASC | DESC. * @return array WP_Query args. @@ -441,8 +442,8 @@ function tmdo_live_router_rating_sort( string $order ): array { 'meta_query' => array( array( 'relation' => 'OR', - 'rating__order' => array( 'key' => 'hp_rating', 'type' => 'DECIMAL', 'compare' => 'NOT EXISTS' ), - array( 'key' => 'hp_rating', 'type' => 'DECIMAL', 'compare' => 'EXISTS' ), + 'rating__order' => array( 'key' => 'hp_rating', 'type' => 'DECIMAL(10,1)', 'compare' => 'NOT EXISTS' ), + array( 'key' => 'hp_rating', 'type' => 'DECIMAL(10,1)', 'compare' => 'EXISTS' ), ), ), 'orderby' => 'rating__order', @@ -450,6 +451,27 @@ function tmdo_live_router_rating_sort( string $order ): array { ); } +/** + * The native sort key of each post, in order (null without a rating). On the + * whole site many listings share a rating and native orders ties by chance, + * so a page is compared by its keys, not its ids. + * + * @param array $ids Post ids. + * @return array + */ +function tmdo_live_router_rating_keys( array $ids ): array { + global $wpdb; + $ids = array_map( 'intval', $ids ); + if ( empty( $ids ) ) { + return array(); + } + $rows = $wpdb->get_results( + "SELECT post_id, CAST(meta_value AS DECIMAL(10,1)) AS k FROM {$wpdb->postmeta} WHERE meta_key = 'hp_rating' AND post_id IN (" . implode( ',', $ids ) . ')', + OBJECT_K + ); + return array_map( static fn( $id ) => isset( $rows[ $id ] ) ? (string) $rows[ $id ]->k : null, $ids ); +} + /** * Native and routed runs of the same query. * @@ -476,7 +498,7 @@ TMDO_Live::test( TMDO_Post_Query_Router::forget_coverage(); foreach ( array( 'DESC', 'ASC' ) as $order ) { list( $native, $routed ) = tmdo_live_router_native_and_routed( tmdo_live_router_rating_sort( $order ) ); - tmdo_live_assert_same( array_map( 'intval', $native->posts ), array_map( 'intval', $routed->posts ), "{$order} ids" ); + tmdo_live_assert_same( tmdo_live_router_rating_keys( $native->posts ), tmdo_live_router_rating_keys( $routed->posts ), "{$order} sort keys" ); tmdo_live_assert_same( $native->found_posts, $routed->found_posts, "{$order} found_posts" ); tmdo_live_assert_true( 0 === strpos( ltrim( $routed->request ), 'SELECT STRAIGHT_JOIN' ), "{$order} flat-first: " . $routed->request ); } @@ -497,7 +519,8 @@ TMDO_Live::test( } finally { TMDO_Post_Query_Router::forget_coverage(); } - tmdo_live_assert_same( array_map( 'intval', $native->posts ), array_map( 'intval', $routed->posts ), 'ids' ); + tmdo_live_assert_same( tmdo_live_router_rating_keys( $native->posts ), tmdo_live_router_rating_keys( $routed->posts ), 'sort keys' ); + tmdo_live_assert_same( $native->found_posts, $routed->found_posts, 'found_posts' ); tmdo_live_assert_true( false === strpos( $routed->request, 'STRAIGHT_JOIN' ), 'not flat-first: ' . $routed->request ); } ); @@ -532,7 +555,8 @@ TMDO_Live::test( 'tax_query' => array( array( 'taxonomy' => 'hp_listing_category', 'field' => 'term_id', 'terms' => array( 999999999 ), 'operator' => 'NOT IN' ) ), ); list( $native, $routed ) = tmdo_live_router_native_and_routed( $args ); - tmdo_live_assert_same( array_map( 'intval', $native->posts ), array_map( 'intval', $routed->posts ), 'ids' ); + tmdo_live_assert_same( tmdo_live_router_rating_keys( $native->posts ), tmdo_live_router_rating_keys( $routed->posts ), 'sort keys' ); + tmdo_live_assert_same( $native->found_posts, $routed->found_posts, 'found_posts' ); tmdo_live_assert_true( 0 === strpos( ltrim( $routed->request ), 'SELECT STRAIGHT_JOIN' ), 'flat-first: ' . $routed->request ); tmdo_live_assert_true( false === stripos( $routed->request, 'GROUP BY' ), 'no GROUP BY: ' . $routed->request ); } @@ -552,7 +576,8 @@ TMDO_Live::test( 'tax_query' => array( array( 'taxonomy' => 'hp_listing_category', 'field' => 'term_id', 'terms' => $terms, 'operator' => 'IN' ) ), ); list( $native, $routed ) = tmdo_live_router_native_and_routed( $args ); - tmdo_live_assert_same( array_map( 'intval', $native->posts ), array_map( 'intval', $routed->posts ), 'ids' ); + tmdo_live_assert_same( tmdo_live_router_rating_keys( $native->posts ), tmdo_live_router_rating_keys( $routed->posts ), 'sort keys' ); + tmdo_live_assert_same( $native->found_posts, $routed->found_posts, 'found_posts' ); tmdo_live_assert_true( false !== stripos( $routed->request, 'GROUP BY' ), 'GROUP BY kept: ' . $routed->request ); } );