Skip to content

Commit 98ad9a2

Browse files
authored
Fix submissions_status RPC when UNION ALL doesn't keep the order (#1201)
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.
1 parent d6d10fc commit 98ad9a2

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

cms/server/admin/server.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
import logging
2929

30-
from sqlalchemy import func, not_
30+
from sqlalchemy import func, not_, literal_column
3131

3232
from cms import config, ServiceCoord, get_service_shards
3333
from cms.db import SessionGen, Dataset, Submission, SubmissionResult, Task
@@ -176,13 +176,17 @@ def submissions_status(contest_id):
176176
.filter(Task.contest_id == contest_id)
177177
queries['total'] = total_query
178178

179-
stats = {}
179+
# Add a "key" column for keeping track of each stats, in case they
180+
# get shuffled.
181+
for key, query in queries.items():
182+
key_column = literal_column(f"'{key}'").label("key")
183+
queries[key] = query.add_columns(key_column)
184+
180185
keys = list(queries.keys())
181186
results = queries[keys[0]].union_all(
182187
*(queries[key] for key in keys[1:])).all()
183188

184-
for i, k in enumerate(keys):
185-
stats[k] = results[i][0]
189+
stats = {key: value for value, key in results}
186190
stats['compiling'] += 2 * stats['total'] - sum(stats.values())
187191

188192
return stats

0 commit comments

Comments
 (0)