From 655cc9517660877d90653a86ea0ece57993d6c0b Mon Sep 17 00:00:00 2001 From: Edoardo Morassutto Date: Wed, 26 Jan 2022 12:02:02 +0100 Subject: [PATCH] Fix submissions_status RPC when UNION ALL doesn't keep the order UNION ALL is not guaranteed to keep the order of the results. In fact with (at least) Postgres 13 the order is not well defined and can change between executions. This patch adds an extra column to the query, tagging each statistics with its key, so that we can reconstruct the correct order of the results. --- cms/server/admin/server.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cms/server/admin/server.py b/cms/server/admin/server.py index 796ab8469..f5fb18522 100644 --- a/cms/server/admin/server.py +++ b/cms/server/admin/server.py @@ -27,7 +27,7 @@ import logging -from sqlalchemy import func, not_ +from sqlalchemy import func, not_, literal_column from cms import config, ServiceCoord, get_service_shards from cms.db import SessionGen, Dataset, Submission, SubmissionResult, Task @@ -176,13 +176,17 @@ def submissions_status(contest_id): .filter(Task.contest_id == contest_id) queries['total'] = total_query - stats = {} + # Add a "key" column for keeping track of each stats, in case they + # get shuffled. + for key, query in queries.items(): + key_column = literal_column("'%s'" % key).label("key") + queries[key] = query.add_column(key_column) + keys = list(queries.keys()) results = queries[keys[0]].union_all( *(queries[key] for key in keys[1:])).all() - for i, k in enumerate(keys): - stats[k] = results[i][0] + stats = {key: value for value, key in results} stats['compiling'] += 2 * stats['total'] - sum(stats.values()) return stats