From 5af9d67fe245c9853891156ad6c79e9476ceb1e9 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Fri, 3 Jul 2026 06:26:00 -0600 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=BB=88=E5=AE=A1=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E2=80=94=E2=80=94test=5Fcase=5Fid=20=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E3=80=81modify=20=E7=A9=BA=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E3=80=81=E5=BC=82=E5=B8=B8=E5=85=9C=E5=BA=95?= =?UTF-8?q?=E4=B8=8E=E6=96=87=E6=A1=A3=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- docs/superpowers/plans/2026-07-03-sql-problem-display.md | 1 + docs/superpowers/specs/2026-07-03-sql-problem-display-design.md | 2 ++ judge/sql_runner.py | 2 ++ problem/serializers.py | 2 +- problem/views/admin.py | 2 +- 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/superpowers/plans/2026-07-03-sql-problem-display.md b/docs/superpowers/plans/2026-07-03-sql-problem-display.md index f394f80..cafa560 100644 --- a/docs/superpowers/plans/2026-07-03-sql-problem-display.md +++ b/docs/superpowers/plans/2026-07-03-sql-problem-display.md @@ -33,6 +33,7 @@ - `TableDump = {"name": str, "columns": [{"name": str, "type": str}], "rows": [[原始值]], "total_rows": int, "truncated": bool}` - `ExpectedQuery = {"columns": [str], "rows": [[原始值]], "total_rows": int, "truncated": bool}`(query 模式) - `ExpectedModify = {"changed_tables": [TableDump, ...]}`(modify 模式,只含执行标准答案后内容有变化的表) + - 被标准答案 DROP 的表以 `{"dropped": true, "rows": [], "total_rows": 0}` 条目出现(columns 取初始结构);标准答案未改任何表时抛 SQLCaseError - [ ] **Step 1: 在 `sql_runner.py` 末尾追加展示数据生成代码** diff --git a/docs/superpowers/specs/2026-07-03-sql-problem-display-design.md b/docs/superpowers/specs/2026-07-03-sql-problem-display-design.md index 3463ffe..1764d05 100644 --- a/docs/superpowers/specs/2026-07-03-sql-problem-display-design.md +++ b/docs/superpowers/specs/2026-07-03-sql-problem-display-design.md @@ -44,6 +44,8 @@ SQL 题目前沿用传统题的展示结构:「输入/输出」两段富文本 - query 模式:`expected` 为 `{columns, rows}` 结果集 - modify 模式:`expected` 为 `{"changed_tables": [{name, columns, rows, total_rows, truncated}]}`,只含有变化的表 +- modify 模式中被标准答案 DROP 的表以 `{"name", "columns"(原结构), "rows": [], "total_rows": 0, "truncated": false, "dropped": true}` 条目出现,前端渲染为「XX 表已被删除」 +- modify 模式若标准答案未改动任何表,保存时报错(视为出题配置问题) ### 生成逻辑 diff --git a/judge/sql_runner.py b/judge/sql_runner.py index 14ad7be..21f30f8 100644 --- a/judge/sql_runner.py +++ b/judge/sql_runner.py @@ -324,6 +324,8 @@ def build_display(init_sql, ref_sql, mode, *, memory_limit_mb=64): _execute_trusted(conn, ref_sql, time.monotonic() + trusted_limit_s, "标准答案执行失败") after = _dump_tables(conn) changed = {name for name in set(before) | set(after) if before.get(name) != after.get(name)} + if not changed: + raise SQLCaseError(JudgeStatus.SYSTEM_ERROR, "标准答案未修改任何表数据,请检查题目配置") changed_tables = _dump_display_tables(conn, only=changed) # 被标准答案 DROP 的表已不在库中,用初始展示数据补齐条目(前端据 dropped 提示“表已删除”) existing = {t["name"] for t in changed_tables} diff --git a/problem/serializers.py b/problem/serializers.py index e3ff3f9..51e4682 100644 --- a/problem/serializers.py +++ b/problem/serializers.py @@ -63,7 +63,7 @@ class CreateOrEditProblemSerializer(serializers.Serializer): input_description = serializers.CharField(allow_blank=True) output_description = serializers.CharField(allow_blank=True) samples = serializers.ListField(child=CreateSampleSerializer(), allow_empty=True) - test_case_id = serializers.CharField(max_length=32) + test_case_id = serializers.RegexField(regex=r"^[a-zA-Z0-9]+$", max_length=32) test_case_score = serializers.ListField(child=CreateTestCaseScoreSerializer(), allow_empty=True) time_limit = serializers.IntegerField(min_value=1, max_value=1000 * 60) memory_limit = serializers.IntegerField(min_value=1, max_value=1024) diff --git a/problem/views/admin.py b/problem/views/admin.py index 691428a..226297b 100644 --- a/problem/views/admin.py +++ b/problem/views/admin.py @@ -238,7 +238,7 @@ class ProblemBase(APIView): if not keys: return "题目没有任何测试点" input_name = info["test_cases"][keys[0]]["input_name"] - except (KeyError, AttributeError): + except (KeyError, AttributeError, TypeError): return "测试点信息损坏,请重新上传测试点" try: with open(os.path.join(test_case_dir, input_name), encoding="utf-8") as f: