WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 4 years ago

#17165 closed enhancement (fixed)

Introduce WP_Meta_Query

Reported by: scribu Owned by:
Milestone: 3.2 Priority: normal
Severity: normal Version:
Component: Query Keywords: has-patch needs-testing
Focuses: Cc:

Description

Similar to WP_Tax_Query.

Also, make get_meta_sql() public.

Related: #16742

Attachments (12)

17165.diff (11.3 KB) - added by scribu 4 years ago.
17165.2.diff (12.1 KB) - added by scribu 4 years ago.
17165.3.diff (12.2 KB) - added by scribu 4 years ago.
17165.4.diff (12.1 KB) - added by greuben 4 years ago.
17165.5.diff (12.2 KB) - added by greuben 4 years ago.
17165.6.diff (12.1 KB) - added by scribu 4 years ago.
17165.7.diff (12.1 KB) - added by scribu 4 years ago.
unit-meta-query.php (1.9 KB) - added by scribu 4 years ago.
17165.8.diff (12.1 KB) - added by greuben 4 years ago.
17165.relation.diff (12.5 KB) - added by greuben 4 years ago.
17165.relation.2.diff (12.6 KB) - added by scribu 4 years ago.
unit-meta-query.2.php (2.7 KB) - added by scribu 4 years ago.

Download all attachments as: .zip

Change History (36)

comment:1 @scribu4 years ago

Related: #17011

comment:2 @greuben4 years ago

  • Cc rgunday@… added

comment:3 @kawauso4 years ago

  • Cc otterish@… added

comment:4 @scribu4 years ago

  • Keywords has-patch added; needs-patch removed

@scribu4 years ago

comment:5 @ryan4 years ago

Do we still need the meta query re-parsing hack from [17552] with this?

comment:6 @scribu4 years ago

Probably not, but I would like to get the current patch in before we start messing with query vars again, since it's blocking other tickets.

comment:7 @scribu4 years ago

  • Keywords needs-patch added; has-patch removed

Nevermind, I see I forgot to remove the extra call to _parse_meta_query(), which would cause a fatal error.

comment:8 @mikeschinkel4 years ago

  • Cc mikeschinkel@… added

@scribu4 years ago

comment:9 @scribu4 years ago

  • Keywords has-patch added; needs-patch removed

17165.2.diff removes the remaining call to _parse_meta_query() and also introduces a get_meta_sql() functions, similar to get_tax_sql(), for convenience.

Version 0, edited 4 years ago by scribu (next)

@scribu4 years ago

comment:10 @scribu4 years ago

17165.3.diff makes the second call to $this->meta_query->parse_query_vars( $q ); just before the !empty( $this->meta_query->queries ) check.

comment:11 @scribu4 years ago

  • Keywords commit added

comment:12 @scribu4 years ago

  • Keywords needs-refresh added; commit removed

@greuben4 years ago

comment:13 @greuben4 years ago

  • Keywords needs-testing added; needs-refresh removed

Patch refreshed.

@scribu: Your patch(refreshed) but just a minor change, I have moved $this->meta_query = new WP_Meta_Query(); to WP_Query::query(); to avoid fatal errors when directly calling WP_Query->query(); See #17118

@greuben4 years ago

@scribu4 years ago

comment:14 @scribu4 years ago

Unlike tax_query, we don't need to set any query flags based on meta_query.

Therefore, we can call meta_query->parse_query_vars() only once, at the beginning of WP_Query::get_posts().

This is what 17165.6.diff does.

comment:15 @scribu4 years ago

At this point, the WP_Meta_Query class isn't very useful.

However, it will become useful when the 'relation' arg comes into play. See #17011

comment:16 follow-up: @ryan4 years ago

Now that we're on PHP5 can we lose call_user_func_array() on get_sql() and simply do $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this)?

Should the constructor call parse_query_vars() on $meta_query?

@scribu4 years ago

comment:17 in reply to: ↑ 16 @scribu4 years ago

Replying to ryan:

Now that we're on PHP5 can we lose call_user_func_array() on get_sql() and simply do $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this)?

Done: 17165.7.diff

Should the constructor call parse_query_vars() on $meta_query?

No, the constructor accepts only the value of the 'meta_query' var, while parse_query_vars() accepts the entire array of query vars.

When the 'relation' arg is introduced, parse_query_vars() will probably call the constructor, not the other way around.

@scribu4 years ago

comment:18 @scribu4 years ago

  • Keywords commit added; needs-testing removed

I have updated the unit-meta-query.php file and it passes all tests.

@greuben4 years ago

comment:19 @greuben4 years ago

One small change, check if parsed queries are arrays.
Try this query

$q = new WP_Query(
array(
	'fields' => 'ids',
	'ignore_sticky_posts' => true,
	'meta_query' => array(
		'test' => 'test',
		array(
			'key' => 'foo',
			'value' => array( 'foobar' ),
			'compare' => 'IN'
		)
	)
) );
echo  $q->request;

The result

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') AND wp_postmeta.meta_key = 't' AND CAST(wp_postmeta.meta_value AS CHAR) = 't' AND mt1.meta_key = 'foo' AND CAST(mt1.meta_value AS CHAR) IN ('foobar') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 5

comment:20 follow-up: @scribu4 years ago

If we're going to start checking for is_array(), might as well implement the 'relation' arg in one go.

Care to refresh and integrate the patch from #17011 into the latest patch here?

comment:21 in reply to: ↑ 20 @greuben4 years ago

Replying to scribu:

If we're going to start checking for is_array(), might as well implement the 'relation' arg in one go.

The reason I've used 'test' and not 'relation' in the example code above is because #17011 is a different ticket and in case if doesn't go in or causes regressions we should still be able to avoid that kind of sql queries.

Care to refresh and integrate the patch from #17011 into the latest patch here?

Sure managing the relation arg here seems more relevant.

@greuben4 years ago

comment:22 @greuben4 years ago

  • Keywords needs-testing added; commit removed

@scribu4 years ago

@scribu4 years ago

comment:23 @scribu4 years ago

17165.relation.2.diff: parse_query_vars() populates a $meta_query arg and passes it to the constructor for further processing.

unit-meta-query.2.php: update and added 2 tests for the 'relation' arg.

comment:24 @ryan4 years ago

  • Resolution set to fixed
  • Status changed from new to closed

(In [17699]) Introduce WP_Meta_Query and relation support. Props scribu, greuben. fixes #17165 #17011

Note: See TracTickets for help on using tickets.