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:
Boone Gorges 2014-10-14 02:16:28 +00:00
parent e7d3a9a26c
commit 40dc982a30
2 changed files with 44 additions and 0 deletions

View File

@ -1123,6 +1123,14 @@ class WP_Meta_Query {
$sql = $this->get_sql_clauses(); $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. * Filter the meta query's generated SQL.
* *

View File

@ -610,6 +610,42 @@ class Tests_Post_Query extends WP_UnitTestCase {
$this->assertEquals( 0, count( $query->posts ) ); $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 * @ticket 23033
* @group meta * @group meta