WordPress.org

Make WordPress Core

Changeset 29890


Ignore:
Timestamp:
10/14/2014 02:16:28 AM (5 years ago)
Author:
boonebgorges
Message:

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.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/meta.php

    r29887 r29890  
    11231123
    11241124        $sql = $this->get_sql_clauses();
     1125
     1126        /*
     1127         * If any JOINs are LEFT JOINs (as in the case of NOT EXISTS), then all JOINs should
     1128         * be LEFT. Otherwise posts with no metadata will be excluded from results.
     1129         */
     1130        if ( false !== strpos( $sql['join'], 'LEFT JOIN' ) ) {
     1131            $sql['join'] = str_replace( 'INNER JOIN', 'LEFT JOIN', $sql['join'] );
     1132        }
    11251133
    11261134        /**
  • trunk/tests/phpunit/tests/post/query.php

    r29888 r29890  
    612612
    613613    /**
     614     * @ticket 29062
     615     */
     616    public function test_meta_query_compare_not_exists_with_another_condition_relation_or() {
     617        $posts = $this->factory->post->create_many( 4 );
     618        update_post_meta( $posts[0], 'color', 'orange' );
     619        update_post_meta( $posts[1], 'color', 'blue' );
     620        update_post_meta( $posts[1], 'vegetable', 'onion' );
     621        update_post_meta( $posts[2], 'vegetable', 'shallot' );
     622
     623        $post_3_meta = get_post_meta( $posts[3] );
     624        foreach ( $post_3_meta as $meta_key => $meta_value ) {
     625            delete_post_meta( $posts[3], $meta_key );
     626        }
     627
     628        $query = new WP_Query( array(
     629            'meta_query' => array(
     630                'relation' => 'OR',
     631                array(
     632                    'key' => 'vegetable',
     633                    'value' => 'onion',
     634                ),
     635                array(
     636                    'key' => 'color',
     637                    'compare' => 'NOT EXISTS',
     638                ),
     639            ),
     640            'update_post_meta_cache' => false,
     641            'update_post_term_cache' => false,
     642            'fields' => 'ids',
     643        ) );
     644
     645        $expected = array( $posts[1], $posts[2], $posts[3] );
     646        $this->assertEqualSets( $expected, $query->posts );
     647    }
     648
     649    /**
    614650     * @ticket 23033
    615651     * @group meta
Note: See TracChangeset for help on using the changeset viewer.