Index: wp-includes/taxonomy.php
===================================================================
--- wp-includes/taxonomy.php	(revision 16551)
+++ wp-includes/taxonomy.php	(working copy)
@@ -524,9 +524,19 @@
 	global $wpdb;
 
 	$join = '';
-	$where = '';
+	$where = array();
 	$i = 0;
+
+	if ( isset( $tax_query['relation'] ) && strtoupper( $tax_query['relation'] ) == 'OR' ) {
+		$relation = 'OR';
+	} else {
+		$relation = 'AND';
+	}
+
 	foreach ( $tax_query as $query ) {
+		if ( ! is_array( $query ) )
+			continue;
+
 		extract( wp_parse_args( $query, array(
 			'taxonomy' => array(),
 			'terms' => array(),
@@ -566,9 +576,14 @@
 		}
 
 		if ( 'IN' == $operator ) {
-			if ( empty( $terms ) )
-				return array( 'join' => '', 'where' => ' AND 0 = 1');
 
+			if ( empty( $terms ) ) {
+				if ( 'OR' == $relation )
+					continue;
+				else
+					return array( 'join' => '', 'where' => ' AND 0 = 1' );
+			}
+
 			$terms = implode( ',', $terms );
 
 			$alias = $i ? 'tt' . $i : $wpdb->term_relationships;
@@ -577,24 +592,30 @@
 			$join .= $i ? " AS $alias" : '';
 			$join .= " ON ($primary_table.$primary_id_column = $alias.object_id)";
 
-			$where .= " AND $alias.term_taxonomy_id $operator ($terms)";
-
-			$i++;
+			$where[] = "$alias.term_taxonomy_id $operator ($terms)";
 		}
 		elseif ( 'NOT IN' == $operator ) {
+
 			if ( empty( $terms ) )
 				continue;
 
 			$terms = implode( ',', $terms );
 
-			$where .= " AND $primary_table.$primary_id_column NOT IN (
-				SELECT object_id 
-				FROM $wpdb->term_relationships 
+			$where[] = "$primary_table.$primary_id_column NOT IN (
+				SELECT object_id
+				FROM $wpdb->term_relationships
 				WHERE term_taxonomy_id IN ($terms)
 			)";
 		}
+
+		$i++;
 	}
 
+	if ( !empty( $where ) )
+		$where = ' AND ( ' . implode( " $relation ", $where ) . ' )';
+	else
+		$where = '';
+
 	return compact( 'join', 'where' );
 }
 
