diff --git a/data/data.qrc b/data/data.qrc
index 6fbc6b9cb..f947641bf 100644
--- a/data/data.qrc
+++ b/data/data.qrc
@@ -335,5 +335,6 @@
icons/22x22/user-away.png
icons/32x32/search.png
schema/schema-35.sql
+ schema/schema-36.sql
diff --git a/data/schema/schema-36.sql b/data/schema/schema-36.sql
new file mode 100644
index 000000000..2b8a8b542
--- /dev/null
+++ b/data/schema/schema-36.sql
@@ -0,0 +1,7 @@
+ALTER TABLE %allsongstables ADD COLUMN effective_albumartist TEXT;
+
+UPDATE %allsongstables SET effective_albumartist = albumartist;
+
+UPDATE %allsongstables SET effective_albumartist = artist WHERE effective_albumartist = "";
+
+UPDATE schema_version SET version=36;
diff --git a/src/core/database.cpp b/src/core/database.cpp
index 0aa8fb1b1..9d99ab756 100644
--- a/src/core/database.cpp
+++ b/src/core/database.cpp
@@ -33,7 +33,7 @@
#include
const char* Database::kDatabaseFilename = "clementine.db";
-const int Database::kSchemaVersion = 35;
+const int Database::kSchemaVersion = 36;
const char* Database::kMagicAllSongsTables = "%allsongstables";
int Database::sNextConnectionId = 1;
diff --git a/src/core/organiseformat.cpp b/src/core/organiseformat.cpp
index aa3f99b99..dfd1991e0 100644
--- a/src/core/organiseformat.cpp
+++ b/src/core/organiseformat.cpp
@@ -140,13 +140,11 @@ QString OrganiseFormat::TagValue(const QString &tag, const Song &song) const {
else if (tag == "samplerate") value = QString::number(song.samplerate());
else if (tag == "extension") value = song.url().toLocalFile().section('.', -1, -1);
else if (tag == "artistinitial") {
- value = song.albumartist().trimmed();
- if (value.isEmpty()) value = song.artist().trimmed();
+ value = song.effective_albumartist().trimmed();
if (!value.isEmpty()) value = value[0].toUpper();
}
else if (tag == "albumartist") {
- value = song.albumartist();
- if (value.isEmpty()) value = song.artist();
+ value = song.is_compilation() ? "Various Artists" : song.effective_albumartist();
}
if (replace_the_ && (tag == "artist" || tag == "albumartist"))
diff --git a/src/core/song.cpp b/src/core/song.cpp
index b1e7ca162..7a744daad 100644
--- a/src/core/song.cpp
+++ b/src/core/song.cpp
@@ -105,7 +105,7 @@ const QStringList Song::kColumns = QStringList()
<< "art_manual" << "filetype" << "playcount" << "lastplayed" << "rating"
<< "forced_compilation_on" << "forced_compilation_off"
<< "effective_compilation" << "skipcount" << "score" << "beginning" << "length"
- << "cue_path" << "unavailable";
+ << "cue_path" << "unavailable" << "effective_albumartist";
const QString Song::kColumnSpec = Song::kColumns.join(", ");
const QString Song::kBindSpec = Prepend(":", Song::kColumns).join(", ");
@@ -588,6 +588,8 @@ void Song::InitFromQuery(const SqlRow& q, bool reliable_metadata, int col) {
d->cue_path_ = tostr(col + 34);
d->unavailable_ = q.value(col + 35).toBool();
+ // effective_albumartist = 36
+
#undef tostr
#undef toint
#undef tolonglong
@@ -1069,6 +1071,7 @@ void Song::BindToQuery(QSqlQuery *query) const {
query->bindValue(":cue_path", d->cue_path_);
query->bindValue(":unavailable", d->unavailable_ ? 1 : 0);
+ query->bindValue(":effective_albumartist", this->effective_albumartist());
#undef intval
#undef notnullintval
diff --git a/src/core/song.h b/src/core/song.h
index 6d01ed247..814ae076d 100644
--- a/src/core/song.h
+++ b/src/core/song.h
@@ -187,6 +187,7 @@ class Song {
const QString& album() const { return d->album_; }
const QString& artist() const { return d->artist_; }
const QString& albumartist() const { return d->albumartist_; }
+ const QString& effective_albumartist() const { return d->albumartist_.isEmpty() ? d->artist_ : d->albumartist_; }
const QString& composer() const { return d->composer_; }
int track() const { return d->track_; }
int disc() const { return d->disc_; }
diff --git a/src/library/librarymodel.cpp b/src/library/librarymodel.cpp
index 0341d0635..4ed78f393 100644
--- a/src/library/librarymodel.cpp
+++ b/src/library/librarymodel.cpp
@@ -174,7 +174,7 @@ void LibraryModel::SongsDiscovered(const SongList& songs) {
case GroupBy_Artist: key = song.artist(); break;
case GroupBy_Composer: key = song.composer(); break;
case GroupBy_Genre: key = song.genre(); break;
- case GroupBy_AlbumArtist: key = song.albumartist(); break;
+ case GroupBy_AlbumArtist: key = song.effective_albumartist(); break;
case GroupBy_Year:
key = QString::number(qMax(0, song.year())); break;
case GroupBy_YearAlbum:
@@ -700,7 +700,7 @@ void LibraryModel::InitQuery(GroupBy type, LibraryQuery* q) {
q->SetColumnSpec("DISTINCT genre");
break;
case GroupBy_AlbumArtist:
- q->SetColumnSpec("DISTINCT albumartist");
+ q->SetColumnSpec("DISTINCT effective_albumartist");
break;
case GroupBy_None:
q->SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
@@ -742,7 +742,7 @@ void LibraryModel::FilterQuery(GroupBy type, LibraryItem* item, LibraryQuery* q)
q->AddWhere("genre", item->key);
break;
case GroupBy_AlbumArtist:
- q->AddWhere("albumartist", item->key);
+ q->AddWhere("effective_albumartist", item->key);
break;
case GroupBy_FileType:
q->AddWhere("filetype", item->metadata.filetype());
@@ -854,7 +854,7 @@ LibraryItem* LibraryModel::ItemFromSong(GroupBy type,
case GroupBy_Composer: item->key = s.composer();
case GroupBy_Genre: if (item->key.isNull()) item->key = s.genre();
case GroupBy_Album: if (item->key.isNull()) item->key = s.album();
- case GroupBy_AlbumArtist: if (item->key.isNull()) item->key = s.albumartist();
+ case GroupBy_AlbumArtist: if (item->key.isNull()) item->key = s.effective_albumartist();
item->display_text = TextOrUnknown(item->key);
item->sort_text = SortTextForArtist(item->key);
break;
diff --git a/src/widgets/osd.cpp b/src/widgets/osd.cpp
index aeec24534..a5e90d80a 100644
--- a/src/widgets/osd.cpp
+++ b/src/widgets/osd.cpp
@@ -322,7 +322,7 @@ QString OSD::ReplaceVariable(const QString& variable, const Song& song) {
} else if (variable == "%title%") {
return song.PrettyTitle();
} else if (variable == "%albumartist%") {
- return song.albumartist();
+ return song.effective_albumartist();
} else if (variable == "%year%") {
return song.PrettyYear();
} else if (variable == "%composer%") {