diff --git a/NEWS b/NEWS
index 9e1565a11..09a282dd7 100644
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,11 @@ ver 0.19 (not yet released)
 * install systemd unit for socket activation
 * Android port
 
+ver 0.18.12 (not yet released)
+* database
+  - proxy: fix build failure with libmpdclient 2.2
+  - proxy: fix add/search and other commands with libmpdclient < 2.9
+
 ver 0.18.11 (2014/05/12)
 * decoder
   - opus: fix missing song length on high-latency files
diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx
index 432280e4e..0640ae19e 100644
--- a/src/SongFilter.cxx
+++ b/src/SongFilter.cxx
@@ -214,6 +214,16 @@ SongFilter::Match(const LightSong &song) const
 	return true;
 }
 
+bool
+SongFilter::HasOtherThanBase() const
+{
+	for (const auto &i : items)
+		if (i.GetTag() != LOCATE_TAG_BASE_TYPE)
+			return true;
+
+	return false;
+}
+
 std::string
 SongFilter::GetBase() const
 {
diff --git a/src/SongFilter.hxx b/src/SongFilter.hxx
index 852220f29..ca7d7bd90 100644
--- a/src/SongFilter.hxx
+++ b/src/SongFilter.hxx
@@ -117,6 +117,11 @@ public:
 		return items;
 	}
 
+	gcc_pure
+	bool IsEmpty() const {
+		return items.empty();
+	}
+
 	/**
 	 * Is there at least one item with "fold case" enabled?
 	 */
@@ -129,6 +134,12 @@ public:
 		return false;
 	}
 
+	/**
+	 * Does this filter contain constraints other than "base"?
+	 */
+	gcc_pure
+	bool HasOtherThanBase() const;
+
 	/**
 	 * Returns the "base" specification (if there is one) or an
 	 * empty string.
diff --git a/src/db/Selection.cxx b/src/db/Selection.cxx
index 96382eed7..a886916cb 100644
--- a/src/db/Selection.cxx
+++ b/src/db/Selection.cxx
@@ -30,6 +30,18 @@ DatabaseSelection::DatabaseSelection(const char *_uri, bool _recursive,
 		uri = filter->GetBase();
 }
 
+bool
+DatabaseSelection::IsEmpty() const
+{
+	return uri.empty() && (filter == nullptr || filter->IsEmpty());
+}
+
+bool
+DatabaseSelection::HasOtherThanBase() const
+{
+	return filter != nullptr && filter->HasOtherThanBase();
+}
+
 bool
 DatabaseSelection::Match(const LightSong &song) const
 {
diff --git a/src/db/Selection.hxx b/src/db/Selection.hxx
index a39ce7afe..9802603fc 100644
--- a/src/db/Selection.hxx
+++ b/src/db/Selection.hxx
@@ -44,6 +44,15 @@ struct DatabaseSelection {
 	DatabaseSelection(const char *_uri, bool _recursive,
 			  const SongFilter *_filter=nullptr);
 
+	gcc_pure
+	bool IsEmpty() const;
+
+	/**
+	 * Does this selection contain constraints other than "base"?
+	 */
+	gcc_pure
+	bool HasOtherThanBase() const;
+
 	gcc_pure
 	bool Match(const LightSong &song) const;
 };
diff --git a/src/db/plugins/ProxyDatabasePlugin.cxx b/src/db/plugins/ProxyDatabasePlugin.cxx
index 1ef281e23..918e6be49 100644
--- a/src/db/plugins/ProxyDatabasePlugin.cxx
+++ b/src/db/plugins/ProxyDatabasePlugin.cxx
@@ -695,6 +695,23 @@ SearchSongs(struct mpd_connection *connection,
 	return result && CheckError(connection, error);
 }
 
+/**
+ * Check whether we can use the "base" constraint.  Requires
+ * libmpdclient 2.9 and MPD 0.18.
+ */
+gcc_pure
+static bool
+ServerSupportsSearchBase(const struct mpd_connection *connection)
+{
+#if LIBMPDCLIENT_CHECK_VERSION(2,9,0)
+	return mpd_connection_cmp_server_version(connection, 0, 18, 0) >= 0;
+#else
+	(void)connection;
+
+	return false;
+#endif
+}
+
 bool
 ProxyDatabase::Visit(const DatabaseSelection &selection,
 		     VisitDirectory visit_directory,
@@ -706,7 +723,10 @@ ProxyDatabase::Visit(const DatabaseSelection &selection,
 	if (!const_cast<ProxyDatabase *>(this)->EnsureConnected(error))
 		return nullptr;
 
-	if (!visit_directory && !visit_playlist && selection.recursive)
+	if (!visit_directory && !visit_playlist && selection.recursive &&
+	    (ServerSupportsSearchBase(connection)
+	     ? !selection.IsEmpty()
+	     : selection.HasOtherThanBase()))
 		/* this optimized code path can only be used under
 		   certain conditions */
 		return ::SearchSongs(connection, selection, visit_song, error);