Index: wp-includes/query.php
===================================================================
--- wp-includes/query.php	(revision 15471)
+++ wp-includes/query.php	(working copy)
@@ -27,7 +27,38 @@
 	return $wp_query->get($var);
 }
 
+
 /**
+ * Retrieve the currently-queried object.  Wrapper for $wp_query->get_queried_object()
+ *
+ * @uses WP_Query::get_queried_object
+ *
+ * @since 3.1.0
+ * @access public
+ *
+ * @return object
+ */
+function get_queried_object() {
+	global $wp_query;
+	return $wp_query->get_queried_object();
+}
+
+/**
+ * Retrieve ID of the current queried object. Wrapper for $wp_query->get_queried_object_id()
+ * 
+ * @uses WP_Query::get_queried_object_id()
+ *
+ * @since 3.1.0
+ * @access public
+ *
+ * @return int
+ */
+function get_queried_object_id() {
+	global $wp_query;
+	return $wp_query->get_queried_object_id();
+}
+
+/**
  * Set query variable.
  *
  * @see WP_Query::set()
@@ -98,182 +129,138 @@
  */
 
 /**
- * Is query requesting an archive page.
+ * Is the query for an archive page?
  *
+ * Month, Year, Category, Author, Post Type archive...
+ *
+ * @see WP_Query::is_archive()
  * @since 1.5.0
  * @uses $wp_query
  *
- * @return bool True if page is archive.
+ * @return bool
  */
 function is_archive() {
 	global $wp_query;
 
-	return $wp_query->is_archive;
+	return $wp_query->is_archive();
 }
 
 /**
- * Is query requesting an attachment page.
+ * Is the query for a post type archive page?
  *
+ * @see WP_Query::is_post_type_archive()
+ * @since 3.1.0
+ * @uses $wp_query
+ *
+ * @param mixed $post_types Optional. Post type or array of posts types to check against.
+ * @return bool
+ */
+function is_post_type_archive( $post_types = '' ) {
+	global $wp_query;
+
+	return $wp_query->is_post_type_archive( $post_types );
+}
+
+/**
+ * Is the query for an attachment page?
+ *
+ * @see WP_Query::is_attachment()
  * @since 2.0.0
  * @uses $wp_query
  *
- * @return bool True if page is attachment.
+ * @return bool
  */
 function is_attachment() {
 	global $wp_query;
 
-	return $wp_query->is_attachment;
+	return $wp_query->is_attachment();
 }
 
 /**
- * Is query requesting an author page.
+ * Is the query for an author archive page?
  *
- * If the $author parameter is specified then the check will be expanded to
- * include whether the queried author matches the one given in the parameter.
- * You can match against integers and against strings.
+ * If the $author parameter is specified, this function will additionally
+ * check if the query is for one of the authors specified.
  *
- * If matching against an integer, the ID should be used of the author for the
- * test. If the $author is an ID and matches the author page user ID, then
- * 'true' will be returned.
- *
- * If matching against strings, then the test will be matched against both the
- * nickname and user nicename and will return true on success.
- *
+ * @see WP_Query::is_author()
  * @since 1.5.0
  * @uses $wp_query
  *
- * @param string|int $author Optional. Is current page this author.
- * @return bool True if page is author or $author (if set).
+ * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
+ * @return bool
  */
-function is_author($author = '') {
+function is_author( $author = '' ) {
 	global $wp_query;
 
-	if ( !$wp_query->is_author )
-		return false;
-
-	if ( empty($author) )
-		return true;
-
-	$author_obj = $wp_query->get_queried_object();
-
-	$author = (array) $author;
-
-	if ( in_array( $author_obj->ID, $author ) )
-		return true;
-	elseif ( in_array( $author_obj->nickname, $author ) )
-		return true;
-	elseif ( in_array( $author_obj->user_nicename, $author ) )
-		return true;
-
-	return false;
+	return $wp_query->is_author( $author );
 }
 
 /**
- * Whether current page query contains a category name or given category name.
+ * Is the query for a category archive page?
  *
- * The category list can contain category IDs, names, or category slugs. If any
- * of them are part of the query, then it will return true.
+ * If the $category parameter is specified, this function will additionally
+ * check if the query is for one of the categories specified.
  *
+ * @see WP_Query::is_category()
  * @since 1.5.0
  * @uses $wp_query
  *
- * @param string|array $category Optional.
+ * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
  * @return bool
  */
-function is_category($category = '') {
+function is_category( $category = '' ) {
 	global $wp_query;
 
-	if ( !$wp_query->is_category )
-		return false;
-
-	if ( empty($category) )
-		return true;
-
-	$cat_obj = $wp_query->get_queried_object();
-
-	$category = (array) $category;
-
-	if ( in_array( $cat_obj->term_id, $category ) )
-		return true;
-	elseif ( in_array( $cat_obj->name, $category ) )
-		return true;
-	elseif ( in_array( $cat_obj->slug, $category ) )
-		return true;
-
-	return false;
+	return $wp_query->is_category( $category );
 }
 
 /**
- * Whether the current page query has the given tag slug or contains tag.
+ * Is the query for a tag archive page?
  *
+ * If the $tag parameter is specified, this function will additionally
+ * check if the query is for one of the tags specified.
+ *
+ * @see WP_Query::is_tag()
  * @since 2.3.0
  * @uses $wp_query
  *
- * @param string|array $slug Optional. Single tag or list of tags to check for.
+ * @param mixed $slug Optional. Tag slug or array of slugs.
  * @return bool
  */
 function is_tag( $slug = '' ) {
 	global $wp_query;
 
-	if ( !$wp_query->is_tag )
-		return false;
-
-	if ( empty( $slug ) )
-		return true;
-
-	$tag_obj = $wp_query->get_queried_object();
-
-	$slug = (array) $slug;
-
-	if ( in_array( $tag_obj->slug, $slug ) )
-		return true;
-
-	return false;
+	return $wp_query->is_tag( $slug );
 }
 
 /**
- * Whether the current query is for the given taxonomy and/or term.
+ * Is the query for a taxonomy archive page?
  *
- * If no taxonomy argument is set, returns true if any taxonomy is queried.
- * If the taxonomy argument is passed but no term argument, returns true
- *    if the taxonomy or taxonomies in the argument are being queried.
- * If both taxonomy and term arguments are passed, returns true
- *    if the current query is for a term contained in the terms argument
- *    which has a taxonomy contained in the taxonomy argument.
+ * If the $taxonomy parameter is specified, this function will additionally
+ * check if the query is for that specific $taxonomy.
  *
+ * If the $term parameter is specified in addition to the $taxonomy parameter,
+ * this function will additionally check if the query is for one of the terms
+ * specified.
+ *
+ * @see WP_Query::is_tax()
  * @since 2.5.0
  * @uses $wp_query
  *
- * @param string|array $taxonomy Optional. Taxonomy slug or slugs to check in current query.
- * @param int|array|string $term. Optional. A single or array of, The term's ID, Name or Slug
+ * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
+ * @param mixed $term Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
  * @return bool
  */
 function is_tax( $taxonomy = '', $term = '' ) {
 	global $wp_query, $wp_taxonomies;
 
-	$queried_object = $wp_query->get_queried_object();
-	$tax_array = array_intersect(array_keys($wp_taxonomies), (array) $taxonomy);
-	$term_array = (array) $term;
-
-	if ( !$wp_query->is_tax )
-		return false;
-
-	if ( empty( $taxonomy ) )
-		return true;
-
-	if ( empty( $term ) ) // Only a Taxonomy provided
-		return isset($queried_object->taxonomy) && count( $tax_array ) && in_array($queried_object->taxonomy, $tax_array);
-
-	return isset($queried_object->term_id) &&
-			count(array_intersect(
-				array($queried_object->term_id, $queried_object->name, $queried_object->slug),
-				$term_array
-			));
+	return $wp_query->is_tax( $taxonomy, $term );
 }
 
 /**
  * Whether the current URL is within the comments popup window.
  *
+ * @see WP_Query::is_comments_popup()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -282,12 +269,13 @@
 function is_comments_popup() {
 	global $wp_query;
 
-	return $wp_query->is_comments_popup;
+	return $wp_query->is_comments_popup();
 }
 
 /**
- * Whether current URL is based on a date.
+ * Is the query for a date archive?
  *
+ * @see WP_Query::is_date()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -296,12 +284,13 @@
 function is_date() {
 	global $wp_query;
 
-	return $wp_query->is_date;
+	return $wp_query->is_date();
 }
 
 /**
- * Whether current blog URL contains a day.
+ * Is the query for a day archive?
  *
+ * @see WP_Query::is_day()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -310,12 +299,13 @@
 function is_day() {
 	global $wp_query;
 
-	return $wp_query->is_day;
+	return $wp_query->is_day();
 }
 
 /**
- * Whether current page query is feed URL.
+ * Is the query for a feed?
  *
+ * @see WP_Query::is_feed()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -324,12 +314,13 @@
 function is_feed() {
 	global $wp_query;
 
-	return $wp_query->is_feed;
+	return $wp_query->is_feed();
 }
 
 /**
- * Whether current page query is comment feed URL.
+ * Is the query for a comments feed?
  *
+ * @see WP_Query::is_comments_feed()
  * @since 3.0.0
  * @uses $wp_query
  *
@@ -338,12 +329,22 @@
 function is_comment_feed() {
 	global $wp_query;
 
-	return $wp_query->is_comment_feed;
+	return $wp_query->is_comment_feed();
 }
 
 /**
- * Whether current page query is the front of the site.
+ * Is the query for the front page of the site?
  *
+ * This is for what is displayed at your site's main URL.
+ *
+ * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
+ *
+ * If you set a static page for the front page of your site, this function will return
+ * true when viewing that page.
+ *
+ * Otherwise the same as @see is_home()
+ *
+ * @see WP_Query::is_front_page()
  * @since 2.5.0
  * @uses is_home()
  * @uses get_option()
@@ -351,22 +352,24 @@
  * @return bool True, if front of site.
  */
 function is_front_page() {
-	// most likely case
-	if ( 'posts' == get_option('show_on_front') && is_home() )
-		return true;
-	elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') && is_page(get_option('page_on_front')) )
-		return true;
-	else
-		return false;
+	global $wp_query;
+
+	return $wp_query->is_front_page();
 }
 
 /**
- * Whether current page view is the blog homepage.
+ * Is the query for the blog homepage?
  *
- * This is the page which is showing the time based blog content of your site
- * so if you set a static page for the front page of your site then this will
- * only be true on the page which you set as the "Posts page" in Reading Settings.
+ * This is the page which shows the time based blog content of your site.
  *
+ * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'.
+ *
+ * If you set a static page for the front page of your site, this function will return
+ * true only on the page you set as the "Posts page".
+ *
+ * @see is_front_page()
+ *
+ * @see WP_Query::is_home()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -375,12 +378,13 @@
 function is_home() {
 	global $wp_query;
 
-	return $wp_query->is_home;
+	return $wp_query->is_home();
 }
 
 /**
- * Whether current page query contains a month.
+ * Is the query for a month archive?
  *
+ * @see WP_Query::is_month()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -389,52 +393,35 @@
 function is_month() {
 	global $wp_query;
 
-	return $wp_query->is_month;
+	return $wp_query->is_month();
 }
 
 /**
- * Whether query is page or contains given page(s).
+ * Is the query for a single Page?
  *
- * Calls the function without any parameters will only test whether the current
- * query is of the page type. Either a list or a single item can be tested
- * against for whether the query is a page and also is the value or one of the
- * values in the page parameter.
+ * If the $page parameter is specified, this function will additionally
+ * check if the query is for one of the Pages specified.
  *
- * The parameter can contain the page ID, page title, or page name. The
- * parameter can also be an array of those three values.
+ * @see is_single()
+ * @see is_singular()
  *
+ * @see WP_Query::is_single()
  * @since 1.5.0
  * @uses $wp_query
  *
- * @param mixed $page Either page or list of pages to test against.
+ * @param mixed $page Page ID, title, slug, or array of Page IDs, titles, and slugs.
  * @return bool
  */
-function is_page($page = '') {
+function is_page( $page = '' ) {
 	global $wp_query;
 
-	if ( !$wp_query->is_page )
-		return false;
-
-	if ( empty($page) )
-		return true;
-
-	$page_obj = $wp_query->get_queried_object();
-
-	$page = (array) $page;
-
-	if ( in_array( $page_obj->ID, $page ) )
-		return true;
-	elseif ( in_array( $page_obj->post_title, $page ) )
-		return true;
-	else if ( in_array( $page_obj->post_name, $page ) )
-		return true;
-
-	return false;
+	return $wp_query->is_page( $page );
 }
 
 /**
- * Whether query contains multiple pages for the results.
+ * Is the query for paged result and not for the first page?
  *
+ * @see WP_Query::is_paged()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -443,32 +430,13 @@
 function is_paged() {
 	global $wp_query;
 
-	return $wp_query->is_paged;
+	return $wp_query->is_paged();
 }
 
 /**
- * Whether the current page was created by a plugin.
+ * Is the query for a post or page preview?
  *
- * The plugin can set this by using the global $plugin_page and setting it to
- * true.
- *
- * @since 1.5.0
- * @global bool $plugin_page Used by plugins to tell the query that current is a plugin page.
- *
- * @return bool
- */
-function is_plugin_page() {
-	global $plugin_page;
-
-	if ( isset($plugin_page) )
-		return true;
-
-	return false;
-}
-
-/**
- * Whether the current query is preview of post or page.
- *
+ * @see WP_Query::is_preview()
  * @since 2.0.0
  * @uses $wp_query
  *
@@ -477,12 +445,13 @@
 function is_preview() {
 	global $wp_query;
 
-	return $wp_query->is_preview;
+	return $wp_query->is_preview();
 }
 
 /**
- * Whether the current query post is robots.
+ * Is the query for the robots file?
  *
+ * @see WP_Query::is_robots()
  * @since 2.1.0
  * @uses $wp_query
  *
@@ -491,12 +460,13 @@
 function is_robots() {
 	global $wp_query;
 
-	return $wp_query->is_robots;
+	return $wp_query->is_robots();
 }
 
 /**
- * Whether current query is the result of a user search.
+ * Is the query for a search?
  *
+ * @see WP_Query::is_search()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -505,70 +475,59 @@
 function is_search() {
 	global $wp_query;
 
-	return $wp_query->is_search;
+	return $wp_query->is_search();
 }
 
 /**
- * Whether the current page query is single page.
+ * Is the query for a single post?
  *
- * The parameter can contain the post ID, post title, or post name. The
- * parameter can also be an array of those three values.
+ * If the $post parameter is specified, this function will additionally
+ * check if the query is for one of the Posts specified.
  *
- * This applies to other post types, attachments, pages, posts. Just means that
- * the current query has only a single object.
+ * Can also be used for attachments or any other post type except pages.
  *
+ * @see is_page()
+ * @see is_singular()
+ *
+ * @see WP_Query::is_single()
  * @since 1.5.0
  * @uses $wp_query
  *
- * @param mixed $post Either post or list of posts to test against.
+ * @param mixed $post Post ID, title, slug, or array of Post IDs, titles, and slugs.
  * @return bool
  */
-function is_single($post = '') {
+function is_single( $post = '' ) {
 	global $wp_query;
 
-	if ( !$wp_query->is_single )
-		return false;
-
-	if ( empty($post) )
-		return true;
-
-	$post_obj = $wp_query->get_queried_object();
-
-	$post = (array) $post;
-
-	if ( in_array( $post_obj->ID, $post ) )
-		return true;
-	elseif ( in_array( $post_obj->post_title, $post ) )
-		return true;
-	elseif ( in_array( $post_obj->post_name, $post ) )
-		return true;
-
-	return false;
+	return $wp_query->is_single( $post );
 }
 
 /**
- * Whether is single post, is a page, or is an attachment.
+ * Is the query for a single post of any post type (post, attachment, page, ... )?
  *
+ * If the $post_types parameter is specified, this function will additionally
+ * check if the query is for one of the Posts Types specified.
+ *
+ * @see is_page()
+ * @see is_single()
+ *
+ * @see WP_Query::is_singular()
  * @since 1.5.0
  * @uses $wp_query
  *
- * @param string|array $post_types Optional. Post type or types to check in current query.
+ * @param mixed $post_types Optional. Post Type or array of Post Types
  * @return bool
  */
-function is_singular($post_types = '') {
+function is_singular( $post_types = '' ) {
 	global $wp_query;
 
-	if ( empty($post_types) || !$wp_query->is_singular )
-		return $wp_query->is_singular;
-
-	$post_obj = $wp_query->get_queried_object();
-
-	return in_array($post_obj->post_type, (array) $post_types);
+	return $wp_query->is_singular( $post_types );
 }
 
 /**
- * Whether the query contains a time.
+ * Is the query for a specific time?
  *
+ * @see WP_Query::is_time()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -577,12 +536,13 @@
 function is_time() {
 	global $wp_query;
 
-	return $wp_query->is_time;
+	return $wp_query->is_time();
 }
 
 /**
- * Whether the query is a trackback.
+ * Is the query for a trackback endpoint call?
  *
+ * @see WP_Query::is_trackback()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -591,12 +551,13 @@
 function is_trackback() {
 	global $wp_query;
 
-	return $wp_query->is_trackback;
+	return $wp_query->is_trackback();
 }
 
 /**
- * Whether the query contains a year.
+ * Is the query for a specific year?
  *
+ * @see WP_Query::is_year()
  * @since 1.5.0
  * @uses $wp_query
  *
@@ -605,21 +566,22 @@
 function is_year() {
 	global $wp_query;
 
-	return $wp_query->is_year;
+	return $wp_query->is_year();
 }
 
 /**
- * Whether current page query is a 404 and no results for WordPress query.
+ * Is the query a 404 (returns no results)?
  *
+ * @see WP_Query::is_404()
  * @since 1.5.0
  * @uses $wp_query
  *
- * @return bool True, if nothing is found matching WordPress Query.
+ * @return bool
  */
 function is_404() {
 	global $wp_query;
 
-	return $wp_query->is_404;
+	return $wp_query->is_404();
 }
 
 /*
@@ -729,16 +691,16 @@
 class WP_Query {
 
 	/**
-	 * Query string
+	 * Query vars set by the user
 	 *
 	 * @since 1.5.0
 	 * @access public
-	 * @var string
+	 * @var array
 	 */
 	var $query;
 
 	/**
-	 * Query search variables set by the user.
+	 * Query vars, after parsing
 	 *
 	 * @since 1.5.0
 	 * @access public
@@ -816,7 +778,7 @@
 	 *
 	 * @since 1.5.0
 	 * @access public
-	 * @var int
+	 * @var object
 	 */
 	var $post;
 
@@ -1064,6 +1026,15 @@
 	var $is_comments_popup = false;
 
 	/**
+	 * Set if query is paged
+	 *
+	 * @since 1.5.0
+	 * @access public
+	 * @var bool
+	 */
+	var $is_paged = false;
+
+	/**
 	 * Set if query is part of administration page.
 	 *
 	 * @since 1.5.0
@@ -1111,6 +1082,15 @@
 	var $is_posts_page = false;
 
 	/**
+	 * Set if query is for a post type archive.
+	 *
+	 * @since 3.1.0
+	 * @access public
+	 * @var bool
+	 */
+	var $is_post_type_archive = false;
+
+	/**
 	 * Resets query flags to false.
 	 *
 	 * The query flags are what page info WordPress was able to figure out.
@@ -1120,6 +1100,7 @@
 	 */
 	function init_query_flags() {
 		$this->is_single = false;
+		$this->is_preview = false;
 		$this->is_page = false;
 		$this->is_archive = false;
 		$this->is_date = false;
@@ -1137,12 +1118,14 @@
 		$this->is_trackback = false;
 		$this->is_home = false;
 		$this->is_404 = false;
+		$this->is_comments_popup = false;
 		$this->is_paged = false;
 		$this->is_admin = false;
 		$this->is_attachment = false;
 		$this->is_singular = false;
 		$this->is_robots = false;
 		$this->is_posts_page = false;
+		$this->is_post_type_archive = false;
 	}
 
 	/**
@@ -1155,11 +1138,22 @@
 		unset($this->posts);
 		unset($this->query);
 		$this->query_vars = array();
+		$this->tax_query = array();
+		$this->meta_query = array();
 		unset($this->queried_object);
 		unset($this->queried_object_id);
 		$this->post_count = 0;
 		$this->current_post = -1;
 		$this->in_the_loop = false;
+		unset( $this->request );
+		unset( $this->post );
+		unset( $this->comments );
+		unset( $this->comment );
+		$this->comment_count = 0;
+		$this->current_comment = -1;
+		$this->found_posts = 0;
+		$this->max_num_pages = 0;
+		$this->max_num_comment_pages = 0;
 
 		$this->init_query_flags();
 	}
@@ -1218,10 +1212,11 @@
 			, 'preview'
 			, 's'
 			, 'sentence'
+			, 'fields'
 		);
 
 		foreach ( $keys as $key ) {
-			if ( !isset($array[$key]))
+			if ( !isset($array[$key]) )
 				$array[$key] = '';
 		}
 
@@ -1229,7 +1224,7 @@
 			'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and');
 
 		foreach ( $array_keys as $key ) {
-			if ( !isset($array[$key]))
+			if ( !isset($array[$key]) )
 				$array[$key] = array();
 		}
 		return $array;
@@ -1246,11 +1241,7 @@
 	function parse_query($query) {
 		if ( !empty($query) || !isset($this->query) ) {
 			$this->init();
-			if ( is_array($query) )
-				$this->query_vars = $query;
-			else
-				parse_str($query, $this->query_vars);
-			$this->query = $query;
+			$this->query = $this->query_vars = wp_parse_args($query);
 		}
 
 		$this->query_vars = $this->fill_query_vars($this->query_vars);
@@ -1296,11 +1287,13 @@
 		} elseif ( '' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id']) ) {
 			$this->is_page = true;
 			$this->is_single = false;
-		} elseif ( !empty($qv['s']) ) {
-			$this->is_search = true;
 		} else {
-		// Look for archive queries.  Dates, categories, authors.
+		// Look for archive queries.  Dates, categories, authors, search, post type archives.
 
+			if ( !empty($qv['s']) ) {
+				$this->is_search = true;
+			}
+
 			if ( '' !== $qv['second'] ) {
 				$this->is_time = true;
 				$this->is_date = true;
@@ -1354,37 +1347,32 @@
 				$this->is_date = true;
 			}
 
-			if ( empty($qv['cat']) || ($qv['cat'] == '0') ) {
+			if ( empty($qv['cat']) || ($qv['cat'] == '0') )
 				$this->is_category = false;
-			} else {
-				if ( strpos($qv['cat'], '-') !== false ) {
-					$this->is_category = false;
-				} else {
-					$this->is_category = true;
-				}
-			}
+			else
+				$this->is_category = strpos($qv['cat'], '-') === false;
 
-			if ( '' != $qv['category_name'] ) {
+			if ( !empty($qv['category_name']) ) {
 				$this->is_category = true;
 			}
 
-			if ( !is_array($qv['category__in']) || empty($qv['category__in']) ) {
+			if ( empty($qv['category__in']) ) {
 				$qv['category__in'] = array();
 			} else {
-				$qv['category__in'] = array_map('absint', $qv['category__in']);
+				$qv['category__in'] = array_map('absint', (array) $qv['category__in']);
 				$this->is_category = true;
 			}
 
-			if ( !is_array($qv['category__not_in']) || empty($qv['category__not_in']) ) {
+			if ( empty($qv['category__not_in']) ) {
 				$qv['category__not_in'] = array();
 			} else {
-				$qv['category__not_in'] = array_map('absint', $qv['category__not_in']);
+				$qv['category__not_in'] = array_map('absint', (array) $qv['category__not_in']);
 			}
 
-			if ( !is_array($qv['category__and']) || empty($qv['category__and']) ) {
+			if ( empty($qv['category__and']) ) {
 				$qv['category__and'] = array();
 			} else {
-				$qv['category__and'] = array_map('absint', $qv['category__and']);
+				$qv['category__and'] = array_map('absint', (array) $qv['category__and']);
 				$this->is_category = true;
 			}
 
@@ -1392,40 +1380,40 @@
 				$this->is_tag = true;
 
 			$qv['tag_id'] = absint($qv['tag_id']);
-			if (  !empty($qv['tag_id']) )
+			if ( !empty($qv['tag_id']) )
 				$this->is_tag = true;
 
-			if ( !is_array($qv['tag__in']) || empty($qv['tag__in']) ) {
+			if ( empty($qv['tag__in']) ) {
 				$qv['tag__in'] = array();
 			} else {
-				$qv['tag__in'] = array_map('absint', $qv['tag__in']);
+				$qv['tag__in'] = array_map('absint', (array) $qv['tag__in']);
 				$this->is_tag = true;
 			}
 
-			if ( !is_array($qv['tag__not_in']) || empty($qv['tag__not_in']) ) {
+			if ( empty($qv['tag__not_in']) ) {
 				$qv['tag__not_in'] = array();
 			} else {
-				$qv['tag__not_in'] = array_map('absint', $qv['tag__not_in']);
+				$qv['tag__not_in'] = array_map('absint', (array) $qv['tag__not_in']);
 			}
 
 			if ( !is_array($qv['tag__and']) || empty($qv['tag__and']) ) {
 				$qv['tag__and'] = array();
 			} else {
-				$qv['tag__and'] = array_map('absint', $qv['tag__and']);
-				$this->is_category = true;
+				$qv['tag__and'] = array_map('absint', (array) $qv['tag__and']);
+				$this->is_tag = true;
 			}
 
-			if ( !is_array($qv['tag_slug__in']) || empty($qv['tag_slug__in']) ) {
+			if ( empty($qv['tag_slug__in']) ) {
 				$qv['tag_slug__in'] = array();
 			} else {
-				$qv['tag_slug__in'] = array_map('sanitize_title', $qv['tag_slug__in']);
+				$qv['tag_slug__in'] = array_map('sanitize_title', (array) $qv['tag_slug__in']);
 				$this->is_tag = true;
 			}
 
-			if ( !is_array($qv['tag_slug__and']) || empty($qv['tag_slug__and']) ) {
+			if ( empty($qv['tag_slug__and']) ) {
 				$qv['tag_slug__and'] = array();
 			} else {
-				$qv['tag_slug__and'] = array_map('sanitize_title', $qv['tag_slug__and']);
+				$qv['tag_slug__and'] = array_map('sanitize_title', (array) $qv['tag_slug__and']);
 				$this->is_tag = true;
 			}
 
@@ -1449,11 +1437,16 @@
 				$this->is_author = true;
 			}
 
-			if ( '' != $qv['author_name'] ) {
+			if ( '' != $qv['author_name'] )
 				$this->is_author = true;
+
+			if ( !empty( $qv['post_type'] ) && ! is_array( $qv['post_type'] ) ) {
+				$post_type_obj = get_post_type_object( $qv['post_type'] );
+				if ( ! empty( $post_type_obj->has_archive ) )
+					$this->is_post_type_archive = true;
 			}
 
-			if ( ($this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax) )
+			if ( $this->is_post_type_archive || $this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax )
 				$this->is_archive = true;
 		}
 
@@ -1528,9 +1521,9 @@
 
 		if ( !empty($qv['post_type']) ) {
 			if ( is_array($qv['post_type']) )
-				$qv['post_type'] = array_map('sanitize_user', $qv['post_type'], array(true));
+				$qv['post_type'] = array_map('sanitize_key', $qv['post_type']);
 			else
-				$qv['post_type'] = sanitize_user($qv['post_type'], true);
+				$qv['post_type'] = sanitize_key($qv['post_type']);
 		}
 
 		if ( !empty($qv['post_status']) )
@@ -1625,13 +1618,19 @@
 		$join = '';
 		$search = '';
 		$groupby = '';
-		$fields = "$wpdb->posts.*";
+		$fields = '';
 		$post_status_join = false;
 		$page = 1;
 
-		if ( !isset($q['caller_get_posts']) )
-			$q['caller_get_posts'] = false;
+		if ( isset( $q['caller_get_posts'] ) ) {
+			_deprecated_argument( 'WP_Query', '3.1', __( '"caller_get_posts" is deprecated. Use "ignore_sticky_posts" instead.' ) );
+			if ( !isset( $q['ignore_sticky_posts'] ) )
+				$q['ignore_sticky_posts'] = $q['caller_get_posts'];
+		}
 
+		if ( !isset( $q['ignore_sticky_posts'] ) )
+			$q['ignore_sticky_posts'] = false;
+
 		if ( !isset($q['suppress_filters']) )
 			$q['suppress_filters'] = false;
 
@@ -1700,6 +1699,17 @@
 		else
 			$q['no_found_rows'] = false;
 
+		switch ( $q['fields'] ) {
+			case 'ids':
+				$fields = "$wpdb->posts.ID";
+				break;
+			case 'id=>parent':
+				$fields = "$wpdb->posts.ID, $wpdb->posts.post_parent";
+				break;
+			default:
+				$fields = "$wpdb->posts.*";
+		}
+
 		// If a month is specified in the querystring, load that month
 		if ( $q['m'] ) {
 			$q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']);
@@ -1757,7 +1767,7 @@
 		}
 
 		if ( '' != $q['name'] ) {
-			$q['name'] = sanitize_title($q['name']);
+			$q['name'] = sanitize_title_for_query( $q['name'] );
 			$where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'";
 		} elseif ( '' != $q['pagename'] ) {
 			if ( isset($this->queried_object_id) ) {
@@ -1785,9 +1795,7 @@
 
 			$page_for_posts = get_option('page_for_posts');
 			if  ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) {
-				$q['pagename'] = str_replace('%2F', '/', urlencode(urldecode($q['pagename'])));
-				$page_paths = '/' . trim($q['pagename'], '/');
-				$q['pagename'] = sanitize_title(basename($page_paths));
+				$q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) );
 				$q['name'] = $q['pagename'];
 				$where .= " AND ($wpdb->posts.ID = '$reqpage')";
 				$reqpage_obj = get_page($reqpage);
@@ -1799,9 +1807,7 @@
 				}
 			}
 		} elseif ( '' != $q['attachment'] ) {
-			$q['attachment'] = str_replace('%2F', '/', urlencode(urldecode($q['attachment'])));
-			$attach_paths = '/' . trim($q['attachment'], '/');
-			$q['attachment'] = sanitize_title(basename($attach_paths));
+			$q['attachment'] = sanitize_title_for_query( wp_basename( $q['attachment'] ) );
 			$q['name'] = $q['attachment'];
 			$where .= " AND $wpdb->posts.post_name = '" . $q['attachment'] . "'";
 		}
@@ -2102,7 +2108,7 @@
 					$q['author_name'] = $q['author_name'][count($q['author_name'])-2]; // there was a trailling slash
 				}
 			}
-			$q['author_name'] = sanitize_title($q['author_name']);
+			$q['author_name'] = sanitize_title_for_query( $q['author_name'] );
 			$q['author'] = get_user_by('slug', $q['author_name']);
 			if ( $q['author'] )
 				$q['author'] = $q['author']->ID;
@@ -2178,13 +2184,11 @@
 				$q['orderby'] = "$wpdb->posts.post_date ".$q['order'];
 		}
 
-		if ( is_array($post_type) ) {
+		if ( is_array( $post_type ) ) {
 			$post_type_cap = 'multiple_post_type';
 		} else {
-			$post_type_object = get_post_type_object ( $post_type );
-			if ( !empty($post_type_object) )
-				$post_type_cap = $post_type_object->capability_type;
-			else
+			$post_type_object = get_post_type_object( $post_type );
+			if ( empty( $post_type_object ) )
 				$post_type_cap = $post_type;
 		}
 
@@ -2211,8 +2215,7 @@
 			$post_type_object = get_post_type_object ( 'post' );
 		}
 
-		if ( !empty($post_type_object) ) {
-			$post_type_cap = $post_type_object->capability_type;
+		if ( ! empty( $post_type_object ) ) {
 			$edit_cap = $post_type_object->cap->edit_post;
 			$read_cap = $post_type_object->cap->read_post;
 			$edit_others_cap = $post_type_object->cap->edit_others_posts;
@@ -2405,6 +2408,7 @@
 			$groupby = 'GROUP BY ' . $groupby;
 		if ( !empty( $orderby ) )
 			$orderby = 'ORDER BY ' . $orderby;
+
 		$found_rows = '';
 		if ( !$q['no_found_rows'] && !empty($limits) )
 			$found_rows = 'SQL_CALC_FOUND_ROWS';
@@ -2413,7 +2417,24 @@
 		if ( !$q['suppress_filters'] )
 			$this->request = apply_filters_ref_array('posts_request', array( $this->request, &$this ) );
 
+		if ( 'ids' == $q['fields'] ) {
+			$this->posts = $wpdb->get_col($this->request);
+
+			return $this->posts;
+		}
+
+		if ( 'id=>parent' == $q['fields'] ) {
+			$this->posts = $wpdb->get_results($this->request);
+
+			$r = array();
+			foreach ( $this->posts as $post )
+				$r[ $post->ID ] = $post->post_parent;
+
+			return $r;
+		}
+
 		$this->posts = $wpdb->get_results($this->request);
+
 		// Raw results filter.  Prior to status checks.
 		if ( !$q['suppress_filters'] )
 			$this->posts = apply_filters_ref_array('posts_results', array( $this->posts, &$this ) );
@@ -2472,7 +2493,7 @@
 
 		// Put sticky posts at the top of the posts array
 		$sticky_posts = get_option('sticky_posts');
-		if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['caller_get_posts'] ) {
+		if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
 			$num_posts = count($this->posts);
 			$sticky_offset = 0;
 			// Loop over posts and relocate stickies to the front.
@@ -2604,6 +2625,7 @@
 
 	/**
 	 * Rewind the posts and reset post index.
+
 	 *
 	 * @since 1.5.0
 	 * @access public
@@ -2735,8 +2757,10 @@
 			if ( is_wp_error($term) || empty($term) )
 				return NULL;
 			$term = $term[0];
-			$this->queried_object = $term;
-			$this->queried_object_id = $term->term_id;
+			if ( $term && ! is_wp_error($term) )  {
+				$this->queried_object = $term;
+				$this->queried_object_id = $term->term_id;
+			}
 		} elseif ( $this->is_posts_page ) {
 			$page_for_posts = get_option('page_for_posts');
 			$this->queried_object = & get_page( $page_for_posts );
@@ -2791,6 +2815,479 @@
 			$this->query($query);
 		}
 	}
+
+	/**
+ 	 * Is the query for an archive page?
+ 	 *
+ 	 * Month, Year, Category, Author, Post Type archive...
+	 *
+ 	 * @since 3.1.0
+ 	 *
+ 	 * @return bool
+ 	 */
+	function is_archive() {
+		return (bool) $this->is_archive;
+	}
+
+	/**
+	 * Is the query for a post type archive page?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @param mixed $post_types Optional. Post type or array of posts types to check against.
+	 * @return bool
+	 */
+	function is_post_type_archive( $post_types = '' ) {
+		if ( empty( $post_types ) || !$this->is_post_type_archive )
+			return (bool) $this->is_post_type_archive;
+
+		if ( ! isset( $this->posts[0] ) )
+			return false;
+
+		$post = $this->posts[0];
+
+		return in_array( $post->post_type, (array) $post_types );
+	}
+
+	/**
+	 * Is the query for an attachment page?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_attachment() {
+		return (bool) $this->is_attachment;
+	}
+
+	/**
+	 * Is the query for an author archive page?
+	 *
+	 * If the $author parameter is specified, this function will additionally
+	 * check if the query is for one of the authors specified.
+	 *
+	 * @since 3.1.0
+	 *
+	 * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
+	 * @return bool
+	 */
+	function is_author( $author = '' ) {
+		if ( !$this->is_author )
+			return false;
+
+		if ( empty($author) )
+			return true;
+
+		$author_obj = $this->get_queried_object();
+
+		$author = (array) $author;
+
+		if ( in_array( $author_obj->ID, $author ) )
+			return true;
+		elseif ( in_array( $author_obj->nickname, $author ) )
+			return true;
+		elseif ( in_array( $author_obj->user_nicename, $author ) )
+			return true;
+
+		return false;
+	}
+
+	/**
+	 * Is the query for a category archive page?
+	 *
+	 * If the $category parameter is specified, this function will additionally
+	 * check if the query is for one of the categories specified.
+	 *
+	 * @since 3.1.0
+	 *
+	 * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
+	 * @return bool
+	 */
+	function is_category( $category = '' ) {
+		if ( !$this->is_category )
+			return false;
+
+		if ( empty($category) )
+			return true;
+
+		$cat_obj = $this->get_queried_object();
+
+		$category = (array) $category;
+
+		if ( in_array( $cat_obj->term_id, $category ) )
+			return true;
+		elseif ( in_array( $cat_obj->name, $category ) )
+			return true;
+		elseif ( in_array( $cat_obj->slug, $category ) )
+			return true;
+
+		return false;
+	}
+
+	/**
+	 * Is the query for a tag archive page?
+	 *
+	 * If the $tag parameter is specified, this function will additionally
+	 * check if the query is for one of the tags specified.
+	 *
+	 * @since 3.1.0
+	 *
+	 * @param mixed $slug Optional. Tag slug or array of slugs.
+	 * @return bool
+	 */
+	function is_tag( $slug = '' ) {
+		if ( !$this->is_tag )
+			return false;
+
+		if ( empty( $slug ) )
+			return true;
+
+		$tag_obj = $this->get_queried_object();
+
+		$slug = (array) $slug;
+
+		if ( in_array( $tag_obj->slug, $slug ) )
+			return true;
+
+		return false;
+	}
+
+	/**
+	 * Is the query for a taxonomy archive page?
+	 *
+	 * If the $taxonomy parameter is specified, this function will additionally
+	 * check if the query is for that specific $taxonomy.
+	 *
+	 * If the $term parameter is specified in addition to the $taxonomy parameter,
+	 * this function will additionally check if the query is for one of the terms
+	 * specified.
+	 *
+	 * @since 3.1.0
+	 *
+	 * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
+	 * @param mixed $term. Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
+	 * @return bool
+	 */
+	function is_tax( $taxonomy = '', $term = '' ) {
+		global $wp_taxonomies;
+
+		if ( !$this->is_tax )
+			return false;
+
+		if ( empty( $taxonomy ) )
+			return true;
+
+		$queried_object = $this->get_queried_object();
+		$tax_array = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy );
+		$term_array = (array) $term;
+
+		if ( empty( $term ) ) // Only a Taxonomy provided
+			return isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array );
+
+		return isset( $queried_object->term_id ) &&
+			count( array_intersect(
+				array( $queried_object->term_id, $queried_object->name, $queried_object->slug ),
+				$term_array
+			) );
+	}
+
+	/**
+	 * Whether the current URL is within the comments popup window.
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_comments_popup() {
+		return (bool) $this->is_comments_popup;
+	}
+
+	/**
+	 * Is the query for a date archive?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_date() {
+		return (bool) $this->is_date;
+	}
+
+
+	/**
+	 * Is the query for a day archive?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_day() {
+		return (bool) $this->is_day;
+	}
+
+	/**
+	 * Is the query for a feed?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_feed() {
+		return (bool) $this->is_feed;
+	}
+
+	/**
+	 * Is the query for a comments feed?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_comment_feed() {
+		return (bool) $this->is_comment_feed;
+	}
+
+	/**
+	 * Is the query for the front page of the site?
+	 *
+	 * This is for what is displayed at your site's main URL.
+	 *
+	 * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
+	 *
+	 * If you set a static page for the front page of your site, this function will return
+	 * true when viewing that page.
+	 *
+	 * Otherwise the same as @see WP_Query::is_home()
+	 *
+	 * @since 3.1.0
+	 * @uses is_home()
+	 * @uses get_option()
+	 *
+	 * @return bool True, if front of site.
+	 */
+	function is_front_page() {
+		// most likely case
+		if ( 'posts' == get_option( 'show_on_front') && $this->is_home() )
+			return true;
+		elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) )
+			return true;
+		else
+			return false;
+	}
+
+	/**
+	 * Is the query for the blog homepage?
+	 *
+	 * This is the page which shows the time based blog content of your site.
+	 *
+	 * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'.
+	 *
+	 * If you set a static page for the front page of your site, this function will return
+	 * true only on the page you set as the "Posts page".
+	 *
+	 * @see WP_Query::is_front_page()
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool True if blog view homepage.
+	 */
+	function is_home() {
+		return (bool) $this->is_home;
+	}
+
+	/**
+	 * Is the query for a month archive?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_month() {
+		return (bool) $this->is_month;
+	}
+
+	/**
+	 * Is the query for a single Page?
+	 *
+	 * If the $page parameter is specified, this function will additionally
+	 * check if the query is for one of the Pages specified.
+	 *
+	 * @see WP_Query::is_single()
+	 * @see WP_Query::is_singular()
+	 *
+	 * @since 3.1.0
+	 *
+	 * @param mixed $page Page ID, title, slug, or array of Page IDs, titles, and slugs.
+	 * @return bool
+	 */
+	function is_page( $page = '' ) {
+		if ( !$this->is_page )
+			return false;
+
+		if ( empty( $page ) )
+			return true;
+
+		$page_obj = $this->get_queried_object();
+
+		$page = (array) $page;
+
+		if ( in_array( $page_obj->ID, $page ) )
+			return true;
+		elseif ( in_array( $page_obj->post_title, $page ) )
+			return true;
+		else if ( in_array( $page_obj->post_name, $page ) )
+			return true;
+
+		return false;
+	}
+
+	/**
+	 * Is the query for paged result and not for the first page?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool                                                                  
+	 */
+	function is_paged() {
+		return (bool) $this->is_paged;
+	}
+
+	/**
+	 * Is the query for a post or page preview?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_preview() {
+		return (bool) $this->is_preview;
+	}
+
+	/**
+	 * Is the query for the robots file?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_robots() {
+		return (bool) $this->is_robots;
+	}
+
+	/**
+	 * Is the query for a search?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_search() {
+		return (bool) $this->is_search;
+	}
+
+	/**
+	 * Is the query for a single post?
+	 *
+	 * If the $post parameter is specified, this function will additionally
+	 * check if the query is for one of the Posts specified.
+	 *
+	 * Can also be used for attachments or any other post type except pages.
+	 *
+	 * @see WP_Query::is_page()
+	 * @see WP_Query::is_singular()
+	 *
+	 * @since 3.1.0
+	 *
+	 * @param mixed $post Post ID, title, slug, or array of Post IDs, titles, and slugs.
+	 * @return bool
+	 */
+	function is_single( $post = '' ) {
+		if ( !$this->is_single )
+			return false;
+
+		if ( empty($post) )
+			return true;
+
+		$post_obj = $this->get_queried_object();
+
+		$post = (array) $post;
+
+		if ( in_array( $post_obj->ID, $post ) )
+			return true;
+		elseif ( in_array( $post_obj->post_title, $post ) )
+			return true;
+		elseif ( in_array( $post_obj->post_name, $post ) )
+			return true;
+
+		return false;
+	}
+
+	/**
+	 * Is the query for a single post of any post type (post, attachment, page, ... )?
+	 *
+	 * If the $post_types parameter is specified, this function will additionally
+	 * check if the query is for one of the Posts Types specified.
+	 *
+	 * @see WP_Query::is_page()
+	 * @see WP_Query::is_single()
+	 *
+	 * @since 3.1.0
+	 *
+	 * @param mixed $post_types Optional. Post Type or array of Post Types
+	 * @return bool
+	 */
+	function is_singular( $post_types = '' ) {
+		if ( empty( $post_types ) || !$this->is_singular )
+			return (bool) $this->is_singular;
+
+		$post_obj = $this->get_queried_object();
+
+		return in_array( $post_obj->post_type, (array) $post_types );
+	}
+
+	/**
+	 * Is the query for a specific time?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_time() {
+		return (bool) $this->is_time;
+	}
+
+	/**
+	 * Is the query for a trackback endpoint call?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_trackback() {
+		return (bool) $this->is_trackback;
+	}
+
+	/**
+	 * Is the query for a specific year?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_year() {
+		return (bool) $this->is_year;
+	}
+
+	/**
+	 * Is the query a 404 (returns no results)?
+	 *
+	 * @since 3.1.0
+	 *
+	 * @return bool
+	 */
+	function is_404() {
+		return (bool) $this->is_404;
+	}
 }
 
 /**
@@ -2809,20 +3306,28 @@
 	if ( is_404() && '' != $wp_query->query_vars['name'] ) :
 		global $wpdb;
 
-		$query = "SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND meta_key = '_wp_old_slug' AND meta_value='" . $wp_query->query_vars['name'] . "'";
+		// Guess the current post_type based on the query vars.
+		if ( get_query_var('post_type') )
+			$post_type = get_query_var('post_type');
+		elseif ( !empty($wp_query->query_vars['pagename']) )
+			$post_type = 'page';
+		else
+			$post_type = 'post';
 
+		$query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND post_type = %s AND meta_key = '_wp_old_slug' AND meta_value = %s", $post_type, $wp_query->query_vars['name']);
+
 		// if year, monthnum, or day have been specified, make our query more precise
 		// just in case there are multiple identical _wp_old_slug values
 		if ( '' != $wp_query->query_vars['year'] )
-			$query .= " AND YEAR(post_date) = '{$wp_query->query_vars['year']}'";
+			$query .= $wpdb->prepare(" AND YEAR(post_date) = %d", $wp_query->query_vars['year']);
 		if ( '' != $wp_query->query_vars['monthnum'] )
-			$query .= " AND MONTH(post_date) = '{$wp_query->query_vars['monthnum']}'";
+			$query .= $wpdb->prepare(" AND MONTH(post_date) = %d", $wp_query->query_vars['monthnum']);
 		if ( '' != $wp_query->query_vars['day'] )
-			$query .= " AND DAYOFMONTH(post_date) = '{$wp_query->query_vars['day']}'";
+			$query .= $wpdb->prepare(" AND DAYOFMONTH(post_date) = %d", $wp_query->query_vars['day']);
 
 		$id = (int) $wpdb->get_var($query);
 
-		if ( !$id )
+		if ( ! $id )
 			return;
 
 		$link = get_permalink($id);
@@ -2845,13 +3350,13 @@
  * @return bool True when finished.
  */
 function setup_postdata($post) {
-	global $id, $authordata, $day, $currentmonth, $page, $pages, $multipage, $more, $numpages;
+	global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages;
 
 	$id = (int) $post->ID;
 
 	$authordata = get_userdata($post->post_author);
 
-	$day = mysql2date('d.m.y', $post->post_date, false);
+	$currentday = mysql2date('d.m.y', $post->post_date, false);
 	$currentmonth = mysql2date('m', $post->post_date, false);
 	$numpages = 1;
 	$page = get_query_var('page');
