fix(2meet-data-optimizer): join each routed group and drop the redundant GROUP BY
- posts_join joins the flat table of every routed group (a wp_core key next to a post type group no longer fails with "Unknown column") - Flat tables are one row per post (UNIQUE post_id): remove the posts_groupby hook; skip the INNER JOIN status/date copy route for NOT EXISTS, which must match posts without a flat row - Verify: tests/live/run.php router (9/9); qbench Q05 475 == native, no SQL error; price filter EXPLAIN has no Using temporary - PR: PR-061
This commit is contained in:
@@ -39,7 +39,7 @@ Exit code 0 when every test passed, 1 otherwise. Output per test:
|
||||
| `shadow_write` | writes in shadow_read reach native meta (user, term, HivePress listing) |
|
||||
| `serialized` | array meta values are stored serialized in flat tables, never "Array" |
|
||||
| `resync` | dual_write / shadow_read: flat follows native after every write (4 entities × 2 modes: update, same value, delete, refused writes, stale flat, key rename by meta_id) |
|
||||
| `router` | a routed WP_Query returns the same ids, in order, as native (OR, several post types, untyped numeric compares, named orderby, LIKE) |
|
||||
| `router` | a routed WP_Query returns the same ids, in order, as native (OR, several post types, untyped numeric compares, named orderby, LIKE, keys of two groups, NOT EXISTS with the status/date copy route); routed SQL has no GROUP BY |
|
||||
| `zero_side_effect` | zone tables that were never created are never queried on save / delete |
|
||||
|
||||
## Tools (`tools/`)
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
* out of any meta_query and ANDed them, so OR relations (Q04, Q16), queries on
|
||||
* several post types (Q08), untyped comparisons on numeric columns (Q14,
|
||||
* native compares strings) and orderby on a named clause (Q15) returned other
|
||||
* posts than WordPress would; LIKE compared without wildcards (Q06).
|
||||
* posts than WordPress would; LIKE compared without wildcards (Q06). A key
|
||||
* of a second group (wp_core _thumbnail_id, Q05) was never joined, and every
|
||||
* routed query carried a GROUP BY although flat rows are one per post.
|
||||
*
|
||||
* Every case runs the same query twice on fixture posts — router hooks off,
|
||||
* then on with post mode shadow_read — and compares the ids in order.
|
||||
@@ -22,7 +24,7 @@ declare(strict_types=1);
|
||||
* @param array<string, mixed> $args Query args (meta_query, post_type, orderby …).
|
||||
* @param int[] $ids Fixture posts to search within.
|
||||
* @param bool $routed Hook a TMDO_Post_Query_Router for this query.
|
||||
* @return array{ids:int[], routed:bool}
|
||||
* @return array{ids:int[], routed:bool, sql:string}
|
||||
*/
|
||||
function tmdo_live_router_query( array $args, array $ids, bool $routed ): array {
|
||||
global $wpdb;
|
||||
@@ -46,7 +48,7 @@ function tmdo_live_router_query( array $args, array $ids, bool $routed ): array
|
||||
)
|
||||
);
|
||||
} finally {
|
||||
foreach ( array( 'pre_get_posts', 'posts_join', 'posts_where', 'posts_groupby', 'posts_orderby', 'posts_request', 'found_posts_query' ) as $hook ) {
|
||||
foreach ( array( 'pre_get_posts', 'posts_join', 'posts_where', 'posts_orderby', 'posts_request', 'found_posts_query' ) as $hook ) {
|
||||
$priority = has_filter( $hook, array( $router, $hook ) );
|
||||
if ( false !== $priority ) {
|
||||
remove_filter( $hook, array( $router, $hook ), $priority );
|
||||
@@ -57,6 +59,7 @@ function tmdo_live_router_query( array $args, array $ids, bool $routed ): array
|
||||
return array(
|
||||
'ids' => array_map( 'intval', $q->posts ),
|
||||
'routed' => ! empty( $q->get( 'wpdo_post_clauses' ) ),
|
||||
'sql' => (string) $q->request,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -107,14 +110,22 @@ function tmdo_live_router_listings(): array {
|
||||
* @param array<string, mixed> $args Query args.
|
||||
* @param int[] $ids Fixture ids.
|
||||
* @param bool|null $expect_routed true / false to assert, null to ignore.
|
||||
* @param bool $ordered Compare order too (false when the order has ties).
|
||||
*/
|
||||
function tmdo_live_router_assert_native( array $args, array $ids, ?bool $expect_routed = null ): void {
|
||||
function tmdo_live_router_assert_native( array $args, array $ids, ?bool $expect_routed = null, bool $ordered = true ): void {
|
||||
$native = tmdo_live_router_query( $args, $ids, false );
|
||||
$routed = tmdo_live_router_query( $args, $ids, true );
|
||||
tmdo_live_assert_same( $native['ids'], $routed['ids'], 'routed ids (in order) vs native' );
|
||||
if ( ! $ordered ) {
|
||||
sort( $native['ids'] );
|
||||
sort( $routed['ids'] );
|
||||
}
|
||||
tmdo_live_assert_same( $native['ids'], $routed['ids'], 'routed ids vs native' );
|
||||
if ( null !== $expect_routed ) {
|
||||
tmdo_live_assert_same( $expect_routed, $routed['routed'], 'query routed to the flat table' );
|
||||
}
|
||||
if ( $routed['routed'] ) {
|
||||
tmdo_live_assert_true( false === stripos( $routed['sql'], 'GROUP BY' ), 'routed query adds no GROUP BY: ' . $routed['sql'] );
|
||||
}
|
||||
}
|
||||
|
||||
TMDO_Live::test(
|
||||
@@ -246,3 +257,43 @@ TMDO_Live::test(
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
TMDO_Live::test(
|
||||
'Q05 keys of two groups are both joined, routed',
|
||||
static function () {
|
||||
$l = tmdo_live_router_listings();
|
||||
TMDO_Live_Fixtures::field( 'post', '_thumbnail_id', 'hp_listing' );
|
||||
update_post_meta( $l['L1'], '_thumbnail_id', '123' );
|
||||
update_post_meta( $l['L3'], '_thumbnail_id', '124' );
|
||||
tmdo_live_router_assert_native(
|
||||
array(
|
||||
'post_type' => 'hp_listing',
|
||||
'meta_query' => array(
|
||||
array( 'key' => 'hp_hourly_rate', 'value' => 42, 'compare' => '>=', 'type' => 'NUMERIC' ),
|
||||
array( 'key' => '_thumbnail_id', 'compare' => 'EXISTS' ),
|
||||
),
|
||||
),
|
||||
array_values( $l ),
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
TMDO_Live::test(
|
||||
'NOT EXISTS with explicit statuses and date order keeps posts without a flat row',
|
||||
static function () {
|
||||
$l = tmdo_live_router_listings();
|
||||
tmdo_live_router_assert_native(
|
||||
array(
|
||||
'post_type' => 'hp_listing',
|
||||
'post_status' => array( 'draft' ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'meta_query' => array( array( 'key' => 'hp_featured', 'compare' => 'NOT EXISTS' ) ),
|
||||
),
|
||||
array_values( $l ),
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user