From c27d7049999037bb131ab2e59e28feafcd8fb55c Mon Sep 17 00:00:00 2001 From: scribu Date: Mon, 6 Sep 2010 11:04:50 +0000 Subject: [PATCH] Use multiple JOINs instead of CASE in _wp_meta_sql(). See #14572 git-svn-id: http://svn.automattic.com/wordpress/trunk@15580 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/functions.php | 45 +++++++++++++++++++++++++-------------- wp-includes/user.php | 9 +++----- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/wp-includes/functions.php b/wp-includes/functions.php index 23f70f137f..b598161dc0 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -4243,10 +4243,13 @@ function _wp_search_sql($string, $cols) { * @since 3.1.0 * * @param array $queries An array of queries - * @param string $meta_id_column The column that holds the object id - * @return string + * @param string $primary_table + * @param string $primary_id_column + * @param string $meta_table + * @param string $meta_id_column + * @return array( $join_sql, $where_sql ) */ -function _wp_meta_sql( $queries, $meta_id_column ) { +function _wp_meta_sql( $queries, $primary_table, $primary_id_column, $meta_table, $meta_id_column ) { global $wpdb; $clauses = array(); @@ -4262,29 +4265,39 @@ function _wp_meta_sql( $queries, $meta_id_column ) { if ( empty( $meta_key ) ) continue; - $clause = $wpdb->prepare( "WHEN %s THEN meta_value ", $meta_key ); - if ( empty( $meta_value ) ) { - $clauses[] = $clause . "IS NOT NULL"; + $clauses[ $meta_key ] = ""; } elseif ( 'like' == $meta_compare ) { - $clauses[] = $clause . $wpdb->prepare( "LIKE %s", '%' . like_escape( $meta_value ) . '%' ); + $clauses[ $meta_key ] = $wpdb->prepare( "LIKE %s", '%' . like_escape( $meta_value ) . '%' ); } else { - $clauses[] = $clause . $wpdb->prepare( "$meta_compare %s", $meta_value ); + $clauses[ $meta_key ] = $wpdb->prepare( "$meta_compare %s", $meta_value ); } } if ( empty( $clauses ) ) - return ''; + return array('', ''); - return " - AND CASE meta_key - " . implode( "\n", $clauses ) . " - END - GROUP BY $meta_id_column - HAVING COUNT(*) = " . count( $clauses ); + $join = ''; + $where = ''; + + $i = 0; + foreach ( $clauses as $meta_key => $value_query ) { + $alias = $i ? 'mt' . $i : $meta_table; + + $join .= "\nINNER JOIN $meta_table"; + $join .= $i ? " AS $alias" : ''; + $join .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column)"; + + $where .= $wpdb->prepare( " AND $alias.meta_key = %s", $meta_key ); + if ( !empty( $value_query ) ) + $where .= " AND $alias.meta_value $value_query"; + + $i++; + } + + return array( $join, $where ); } - /* * Used internally to tidy up the search terms * diff --git a/wp-includes/user.php b/wp-includes/user.php index 5dfce4ae17..5deab86687 100644 --- a/wp-includes/user.php +++ b/wp-includes/user.php @@ -463,12 +463,9 @@ class WP_User_Query { $meta_queries[] = wp_array_slice_assoc( $qv, array( 'meta_key', 'meta_value', 'meta_compare' ) ); - $meta_query_sql = _wp_meta_sql( $meta_queries, 'user_id' ); - - if ( !empty( $meta_query_sql ) ) { - $this->query_from .= " INNER JOIN $wpdb->usermeta ON ($wpdb->users.ID = $wpdb->usermeta.user_id)"; - $this->query_where .= $meta_query_sql; - } + list( $meta_join, $meta_where ) = _wp_meta_sql( $meta_queries, $wpdb->users, 'ID', $wpdb->usermeta, 'user_id' ); + $this->query_from .= $meta_join; + $this->query_where .= $meta_where; if ( !empty($qv['include']) ) { $ids = implode( ',', wp_parse_id_list( $qv['include'] ) );