Opened 2 years ago

Closed 2 years ago

#17165 closed enhancement (fixed)

Introduce WP_Meta_Query

Reported by: scribu Owned by:
Priority: normal Milestone: 3.2
Component: Query Version:
Severity: normal Keywords: has-patch needs-testing
Cc: rgunday@…, otterish@…, mikeschinkel@…

Description

Similar to WP_Tax_Query.

Also, make get_meta_sql() public.

Related: #16742

Attachments (12)

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

Download all attachments as: .zip

Change History (36)

Related: #17011

  • Cc rgunday@… added
  • Cc otterish@… added
  • Keywords has-patch added; needs-patch removed

scribu2 years ago

comment:5   ryan2 years ago

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

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.

  • 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.

  • Cc mikeschinkel@… added

scribu2 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 2 years ago by scribu (next)

scribu2 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.

  • Keywords commit added
  • Keywords needs-refresh added; commit removed

greuben2 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

greuben2 years ago

scribu2 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.

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: ↓ 17   ryan2 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?

scribu2 years ago

comment:17 in reply to: ↑ 16   scribu2 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.

scribu2 years ago

  • Keywords commit added; needs-testing removed

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

greuben2 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: ↓ 21   scribu2 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   greuben2 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.

greuben2 years ago

  • Keywords needs-testing added; commit removed

scribu2 years ago

scribu2 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.

  • 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.