From e6823199d62a56368ff8bb29631c8e9f172e04c5 Mon Sep 17 00:00:00 2001 From: ejurgensen Date: Sun, 20 Feb 2022 10:18:13 +0100 Subject: [PATCH] [db] Fix incorrect sorting of album/artist searches via web api (#1421) Fix incorrect sorting of album/artist searches via web api. Also works with composers etc. Fixes issue #1418 --- src/db.c | 30 +++++++++++++++++------------- src/parsers/smartpl_parser.y | 4 ++-- src/smartpl_query.c | 6 ++++++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/db.c b/src/db.c index 40a2f4ca..e2a01598 100644 --- a/src/db.c +++ b/src/db.c @@ -2217,11 +2217,12 @@ db_build_query_group_albums(struct query_params *qp, struct query_clause *qc) char *query; count = sqlite3_mprintf("SELECT COUNT(DISTINCT f.songalbumid) FROM files f %s;", qc->where); - query = sqlite3_mprintf("SELECT " \ - " g.id, g.persistentid, f.album, f.album_sort, COUNT(f.id) as track_count, " \ - " 1 as album_count, f.album_artist, f.songartistid, " \ - " SUM(f.song_length), MIN(f.data_kind), MIN(f.media_kind), MAX(f.year), MAX(f.date_released), " \ - " MAX(f.time_added), MAX(f.time_played), MAX(f.seek) " \ + query = sqlite3_mprintf("SELECT" \ + " g.id, g.persistentid, f.album, f.album_sort, COUNT(f.id) AS track_count," \ + " 1 AS album_count, f.album_artist, f.songartistid," \ + " SUM(f.song_length) AS song_length, MIN(f.data_kind) AS data_kind, MIN(f.media_kind) AS media_kind," \ + " MAX(f.year) AS year, MAX(f.date_released) AS date_released," \ + " MAX(f.time_added) AS time_added, MAX(f.time_played) AS time_played, MAX(f.seek) AS seek " \ "FROM files f JOIN groups g ON f.songalbumid = g.persistentid %s " \ "GROUP BY f.songalbumid %s %s %s;", qc->where, qc->having, qc->order, qc->index); @@ -2235,11 +2236,12 @@ db_build_query_group_artists(struct query_params *qp, struct query_clause *qc) char *query; count = sqlite3_mprintf("SELECT COUNT(DISTINCT f.songartistid) FROM files f %s;", qc->where); - query = sqlite3_mprintf("SELECT " \ - " g.id, g.persistentid, f.album_artist, f.album_artist_sort, COUNT(f.id) as track_count, " \ - " COUNT(DISTINCT f.songalbumid) as album_count, f.album_artist, f.songartistid, " \ - " SUM(f.song_length), MIN(f.data_kind), MIN(f.media_kind), MAX(f.year), MAX(f.date_released), " \ - " MAX(f.time_added), MAX(f.time_played), MAX(f.seek) " \ + query = sqlite3_mprintf("SELECT" \ + " g.id, g.persistentid, f.album_artist, f.album_artist_sort, COUNT(f.id) AS track_count," \ + " COUNT(DISTINCT f.songalbumid) AS album_count, f.album_artist, f.songartistid," \ + " SUM(f.song_length) AS song_length, MIN(f.data_kind) AS data_kind, MIN(f.media_kind) AS media_kind," \ + " MAX(f.year) AS year, MAX(f.date_released) AS date_released," \ + " MAX(f.time_added) AS time_added, MAX(f.time_played) AS time_played, MAX(f.seek) AS seek " \ "FROM files f JOIN groups g ON f.songartistid = g.persistentid %s " \ "GROUP BY f.songartistid %s %s %s;", qc->where, qc->having, qc->order, qc->index); @@ -2321,9 +2323,11 @@ db_build_query_browse(struct query_params *qp, struct query_clause *qc) where = browse_clause[qp->type & ~Q_F_BROWSE].where; count = sqlite3_mprintf("SELECT COUNT(*) FROM (SELECT %s FROM files f %s AND %s != '' %s);", select, qc->where, where, qc->group); - query = sqlite3_mprintf("SELECT %s, COUNT(f.id) as track_count, COUNT(DISTINCT f.songalbumid) as album_count, COUNT(DISTINCT f.songartistid) as artist_count, " - " SUM(f.song_length), MIN(f.data_kind), MIN(f.media_kind), MAX(f.year), MAX(f.date_released), " - " MAX(f.time_added), MAX(f.time_played), MAX(f.seek) FROM files f %s AND %s != '' %s %s %s;", + query = sqlite3_mprintf("SELECT %s, COUNT(f.id) AS track_count, COUNT(DISTINCT f.songalbumid) AS album_count, COUNT(DISTINCT f.songartistid) AS artist_count," + " SUM(f.song_length) AS song_length, MIN(f.data_kind) AS data_kind, MIN(f.media_kind) AS media_kind," + " MAX(f.year) AS year, MAX(f.date_released) AS date_released," + " MAX(f.time_added) AS time_added, MAX(f.time_played) AS time_played, MAX(f.seek) AS seek " + "FROM files f %s AND %s != '' %s %s %s;", select, qc->where, where, qc->group, qc->order, qc->index); return db_build_query_check(qp, count, query); diff --git a/src/parsers/smartpl_parser.y b/src/parsers/smartpl_parser.y index be695c39..dbef20ce 100644 --- a/src/parsers/smartpl_parser.y +++ b/src/parsers/smartpl_parser.y @@ -311,7 +311,7 @@ static void sql_append_recursive(struct smartpl_result *result, struct result_pa case SQL_APPEND_FIELD: assert(a->l == NULL); assert(a->r == NULL); - sql_append(result, part, "f.%s", (char *)a->data); + sql_append(result, part, "%s", (char *)a->data); break; case SQL_APPEND_STR: assert(a->l == NULL); @@ -328,7 +328,7 @@ static void sql_append_recursive(struct smartpl_result *result, struct result_pa assert(a->l == NULL); assert(a->r == NULL); if (a->data) - sql_append(result, part, "f.%s ", (char *)a->data); + sql_append(result, part, "%s ", (char *)a->data); sql_append(result, part, "%s", is_not ? op_not : op); break; case SQL_APPEND_PARENS: diff --git a/src/smartpl_query.c b/src/smartpl_query.c index 98ecdee6..57a3d1a7 100644 --- a/src/smartpl_query.c +++ b/src/smartpl_query.c @@ -113,6 +113,12 @@ smartpl_query_parse_string(struct smartpl *smartpl, const char *expression) free_smartpl(smartpl, 1); + // Note the fields returned by the smartpl parser will not be prefixed with + // "f." (unlike the daap parser results and most other queries). The reason is + // that the smartpl syntax allows the user to request ordering by a calculated + // field in a group query, and calculated fields are not in the "f" namespace. + // An example of this happening is if the JSON API search is called with + // type=album and the smartpl expression has "order+by+time_played+desc". smartpl->title = strdup(result.title); smartpl->query_where = strdup(result.where); smartpl->having = safe_strdup(result.having);