Files
OJ2/apps/api/src/db/0035_recount_solved_metrics.sql
T
xuyueandClaude Opus 5.5 55038cc78b
Deploy / deploy (push) Canceled after 0s
fix(判题): 判题机卡住不再让全班一直「等待评分」,重判和同时交对也不再把做对题数算多
- 正式判题、样例重跑、运行时错误诊断都加了超时(默认 120 秒,时限放宽的题按比例放宽),
  超时记系统错误、提示是中文;回包和试运行一样边读边数,超过 16MB 就掐断,
  免得一个疯狂打印的错误程序把 worker 撑爆
- 做对题数、中等、困难、一次就对改成在锁里按定义现数:原来逐次 +1,两条挨着判完或重判
  一条做对的提交都会多加,库里 372 人多了 1–4 道。0035 把存量一次订正
- 重判不再给提交次数、凌晨/早起计数 +1,编译错误按前后差值改;「错了几次才对」只数这条之前的
- 已拿到的成就数只 jsonb_set 那一个键,不再整块写回冲掉并发判题刚写的指标

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:15:08 +08:00

47 lines
2.1 KiB
SQL

-- 做对题数、中等、困难、一次就对四项按定义重数(判题结算从这一版起也是现数,见
-- services/achievements.ts 的 solvedCounts)。原来逐次 +1,并发判完和重判会多加:
-- 2026-10 的库里 372 人的做对题数比实际多 1–4 道。只改这四个键、只写值变了的行;
-- 已经拿到的成就一个不收回。不含比赛,做对 = ACCEPTED(0) / AST_CHECK_FAILED(10)。
UPDATE "user_stat" AS target
SET "metrics" = target."metrics" || jsonb_build_object(
'accepted_count', fresh.accepted,
'mid_ac_count', fresh.mid,
'hard_ac_count', fresh.hard,
'first_try_ac_count', fresh.first_try
)
FROM (
SELECT st."id",
coalesce(c.accepted, 0) AS accepted,
coalesce(c.mid, 0) AS mid,
coalesce(c.hard, 0) AS hard,
coalesce(f.first_try, 0) AS first_try
FROM "user_stat" st
LEFT JOIN (
SELECT s."user_id",
count(DISTINCT s."problem_id") FILTER (WHERE s."result" IN (0, 10))::int AS accepted,
count(DISTINCT s."problem_id") FILTER (WHERE s."result" IN (0, 10) AND p."difficulty" = 'Mid')::int AS mid,
count(DISTINCT s."problem_id") FILTER (WHERE s."result" IN (0, 10) AND p."difficulty" = 'High')::int AS hard
FROM "submission" s
JOIN "problem" p ON p."id" = s."problem_id"
WHERE s."contest_id" IS NULL
GROUP BY s."user_id"
) c ON c."user_id" = st."user_id"
LEFT JOIN (
SELECT first."user_id", count(*) FILTER (WHERE first."result" IN (0, 10))::int AS first_try
FROM (
SELECT DISTINCT ON (s."user_id", s."problem_id") s."user_id", s."result"
FROM "submission" s
WHERE s."contest_id" IS NULL
ORDER BY s."user_id", s."problem_id", s."create_time", s."id"
) first
GROUP BY first."user_id"
) f ON f."user_id" = st."user_id"
) fresh
WHERE target."id" = fresh."id"
AND (
(target."metrics" -> 'accepted_count') IS DISTINCT FROM to_jsonb(fresh.accepted)
OR (target."metrics" -> 'mid_ac_count') IS DISTINCT FROM to_jsonb(fresh.mid)
OR (target."metrics" -> 'hard_ac_count') IS DISTINCT FROM to_jsonb(fresh.hard)
OR (target."metrics" -> 'first_try_ac_count') IS DISTINCT FROM to_jsonb(fresh.first_try)
);