Use `LEFT JOIN` when building `WP_Tax_Query` SQL.

`LEFT JOIN` ensures that `NOT EXISTS` queries will not miss posts that have
no taxonomy data whatsoever.

Props swissspidy, crstauf.
Fixes #36343.

git-svn-id: https://develop.svn.wordpress.org/trunk@37184 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges 2016-04-12 20:36:31 +00:00
parent 65ec7e5d81
commit 765e23a4a6
2 changed files with 46 additions and 1 deletions

View File

@ -440,7 +440,7 @@ class WP_Tax_Query {
// Store the alias with this clause, so later siblings can use it.
$clause['alias'] = $alias;
$join .= " INNER JOIN $wpdb->term_relationships";
$join .= " LEFT JOIN $wpdb->term_relationships";
$join .= $i ? " AS $alias" : '';
$join .= " ON ($this->primary_table.$this->primary_id_column = $alias.object_id)";
}

View File

@ -409,6 +409,51 @@ class Tests_Query_TaxQuery extends WP_UnitTestCase {
$this->assertEqualSets( array( $p1, $p3 ), $q->posts );
}
/**
* @ticket 36343
*/
public function test_tax_query_operator_not_exists_combined() {
register_post_type( 'wptests_cpt1' );
register_taxonomy( 'wptests_tax1', 'wptests_cpt1' );
register_taxonomy( 'wptests_tax2', 'wptests_cpt1' );
$t1 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax1' ) );
$t2 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax1' ) );
$t3 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax2' ) );
$p1 = self::factory()->post->create( array( 'post_type' => 'wptests_cpt1' ) );
$p2 = self::factory()->post->create( array( 'post_type' => 'wptests_cpt1' ) );
$p3 = self::factory()->post->create( array( 'post_type' => 'wptests_cpt1' ) );
$p4 = self::factory()->post->create( array( 'post_type' => 'wptests_cpt1' ) );
wp_set_object_terms( $p1, array( $t1 ), 'wptests_tax1' );
wp_set_object_terms( $p2, array( $t2 ), 'wptests_tax1' );
wp_set_object_terms( $p3, array( $t3 ), 'wptests_tax2' );
$q = new WP_Query( array(
'post_type' => 'wptests_cpt1',
'fields' => 'ids',
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'wptests_tax1',
'operator' => 'NOT EXISTS',
),
array(
'taxonomy' => 'wptests_tax1',
'field' => 'slug',
'terms' => get_term_field( 'slug', $t1 ),
),
),
) );
unregister_post_type( 'wptests_cpt1' );
unregister_taxonomy( 'wptests_tax1' );
unregister_taxonomy( 'wptests_tax2' );
$this->assertEqualSets( array( $p1, $p3, $p4 ), $q->posts );
}
/**
* @ticket 29181
*/