Use only LEFT JOINs when a meta_query contains a NOT EXISTS clause.
Mixing LEFT and INNER JOIN in these cases results in posts with no metadata being improperly excluded from results. Props johnrom. Fixes #29062. git-svn-id: https://develop.svn.wordpress.org/trunk@29890 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
e7d3a9a26c
commit
40dc982a30
@ -1123,6 +1123,14 @@ class WP_Meta_Query {
|
||||
|
||||
$sql = $this->get_sql_clauses();
|
||||
|
||||
/*
|
||||
* If any JOINs are LEFT JOINs (as in the case of NOT EXISTS), then all JOINs should
|
||||
* be LEFT. Otherwise posts with no metadata will be excluded from results.
|
||||
*/
|
||||
if ( false !== strpos( $sql['join'], 'LEFT JOIN' ) ) {
|
||||
$sql['join'] = str_replace( 'INNER JOIN', 'LEFT JOIN', $sql['join'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the meta query's generated SQL.
|
||||
*
|
||||
|
@ -610,6 +610,42 @@ class Tests_Post_Query extends WP_UnitTestCase {
|
||||
$this->assertEquals( 0, count( $query->posts ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 29062
|
||||
*/
|
||||
public function test_meta_query_compare_not_exists_with_another_condition_relation_or() {
|
||||
$posts = $this->factory->post->create_many( 4 );
|
||||
update_post_meta( $posts[0], 'color', 'orange' );
|
||||
update_post_meta( $posts[1], 'color', 'blue' );
|
||||
update_post_meta( $posts[1], 'vegetable', 'onion' );
|
||||
update_post_meta( $posts[2], 'vegetable', 'shallot' );
|
||||
|
||||
$post_3_meta = get_post_meta( $posts[3] );
|
||||
foreach ( $post_3_meta as $meta_key => $meta_value ) {
|
||||
delete_post_meta( $posts[3], $meta_key );
|
||||
}
|
||||
|
||||
$query = new WP_Query( array(
|
||||
'meta_query' => array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => 'vegetable',
|
||||
'value' => 'onion',
|
||||
),
|
||||
array(
|
||||
'key' => 'color',
|
||||
'compare' => 'NOT EXISTS',
|
||||
),
|
||||
),
|
||||
'update_post_meta_cache' => false,
|
||||
'update_post_term_cache' => false,
|
||||
'fields' => 'ids',
|
||||
) );
|
||||
|
||||
$expected = array( $posts[1], $posts[2], $posts[3] );
|
||||
$this->assertEqualSets( $expected, $query->posts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 23033
|
||||
* @group meta
|
||||
|
Loading…
Reference in New Issue
Block a user