Deadman922 commited on
Commit
7c17c2c
·
verified ·
1 Parent(s): 049cd6f

Upload graders.py

Browse files
Files changed (1) hide show
  1. server/graders.py +145 -0
server/graders.py CHANGED
@@ -1250,3 +1250,148 @@ def grade_dedup_bug(
1250
  },
1251
  partial_scores=partial_scores.copy(),
1252
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1250
  },
1251
  partial_scores=partial_scores.copy(),
1252
  )
1253
+
1254
+
1255
+ def grade_fk_integrity(
1256
+ action: SQLAction,
1257
+ ground_truth: Dict[str, Any],
1258
+ conn: sqlite3.Connection,
1259
+ ) -> SQLReward:
1260
+ """Single-step fk_integrity scorer — validates grader exists."""
1261
+ fix_sql = (action.fix_query or action.sql or "").strip()
1262
+ target_table = ground_truth.get("table", "invoices")
1263
+ parent_table = ground_truth.get("parent_table", "customers")
1264
+ parent_key = ground_truth.get("parent_key", "id")
1265
+ fk_col = ground_truth.get("column", "customer_id")
1266
+ snapshot = _snapshot_table(conn, target_table)
1267
+
1268
+ if not fix_sql or fix_sql.upper().startswith("SELECT"):
1269
+ return SQLReward(
1270
+ score=_clamp(0.0),
1271
+ step_reward=_clamp(0.0),
1272
+ feedback="No fix query provided",
1273
+ dimensions={"legacy_mode": True},
1274
+ partial_scores={},
1275
+ )
1276
+
1277
+ test_conn = _fresh_test_db(conn)
1278
+ try:
1279
+ test_conn.executescript(fix_sql)
1280
+ test_conn.commit()
1281
+ orphan_count = test_conn.execute(
1282
+ f"SELECT COUNT(*) FROM {quote_identifier(target_table)} t "
1283
+ f"LEFT JOIN {quote_identifier(parent_table)} p ON t.{quote_identifier(fk_col)} = p.{quote_identifier(parent_key)} "
1284
+ f"WHERE p.{quote_identifier(parent_key)} IS NULL"
1285
+ ).fetchone()[0]
1286
+ issue_resolved = orphan_count == 0
1287
+ preservation = _measure_data_preservation(
1288
+ test_conn, snapshot, target_table
1289
+ )
1290
+ score = 0.0
1291
+ if issue_resolved:
1292
+ score += 0.6
1293
+ if preservation >= 0.95:
1294
+ score += 0.4
1295
+ return SQLReward(
1296
+ score=_clamp(score),
1297
+ step_reward=_clamp(score),
1298
+ feedback=(
1299
+ "FK integrity resolved" if issue_resolved
1300
+ else f"Orphans remaining: {orphan_count}"
1301
+ ),
1302
+ dimensions={"legacy_mode": True, "composite": _clamp(score)},
1303
+ partial_scores={"issue_resolved": float(issue_resolved),
1304
+ "preservation": preservation},
1305
+ )
1306
+ except sqlite3.Error as exc:
1307
+ return SQLReward(
1308
+ score=_clamp(0.0),
1309
+ step_reward=_clamp(0.0),
1310
+ feedback=f"SQL error: {exc}",
1311
+ dimensions={"legacy_mode": True},
1312
+ partial_scores={},
1313
+ )
1314
+ finally:
1315
+ test_conn.close()
1316
+
1317
+
1318
+ def grade_schema_drift(
1319
+ action: SQLAction,
1320
+ ground_truth: Dict[str, Any],
1321
+ conn: sqlite3.Connection,
1322
+ ) -> SQLReward:
1323
+ """Single-step schema_drift scorer — validates grader exists."""
1324
+ fix_sql = (action.fix_query or action.sql or "").strip()
1325
+ canonical_table = ground_truth.get("table", "canonical_events")
1326
+ expected_cols = ground_truth.get(
1327
+ "expected_columns",
1328
+ ["event_id", "user_id", "event_type", "amount", "event_time"]
1329
+ )
1330
+ expected_rows = ground_truth.get("expected_row_count", 1200)
1331
+
1332
+ if not fix_sql:
1333
+ return SQLReward(
1334
+ score=_clamp(0.0),
1335
+ step_reward=_clamp(0.0),
1336
+ feedback="No fix query provided",
1337
+ dimensions={"legacy_mode": True},
1338
+ partial_scores={},
1339
+ )
1340
+
1341
+ test_conn = _fresh_test_db(conn)
1342
+ try:
1343
+ test_conn.executescript(fix_sql)
1344
+ test_conn.commit()
1345
+ tables = {
1346
+ r[0] for r in test_conn.execute(
1347
+ "SELECT name FROM sqlite_master WHERE type='table'"
1348
+ ).fetchall()
1349
+ }
1350
+ if canonical_table not in tables:
1351
+ return SQLReward(
1352
+ score=_clamp(0.0),
1353
+ step_reward=_clamp(0.0),
1354
+ feedback=f"Table {canonical_table} not created",
1355
+ dimensions={"legacy_mode": True},
1356
+ partial_scores={},
1357
+ )
1358
+ cols = {
1359
+ r[1] for r in test_conn.execute(
1360
+ f"PRAGMA table_info({quote_identifier(canonical_table)})"
1361
+ )
1362
+ }
1363
+ row_count = test_conn.execute(
1364
+ f"SELECT COUNT(*) FROM {quote_identifier(canonical_table)}"
1365
+ ).fetchone()[0]
1366
+ col_overlap = len(set(expected_cols) & cols) / max(1, len(expected_cols))
1367
+ row_align = 1.0 - min(
1368
+ 1.0, abs(row_count - expected_rows) / max(1, expected_rows)
1369
+ )
1370
+ score = col_overlap * 0.5 + row_align * 0.5
1371
+ return SQLReward(
1372
+ score=_clamp(score),
1373
+ step_reward=_clamp(score),
1374
+ feedback=f"Schema drift: col_overlap={col_overlap:.2f} row_align={row_align:.2f}",
1375
+ dimensions={"legacy_mode": True, "composite": _clamp(score)},
1376
+ partial_scores={"col_overlap": col_overlap, "row_align": row_align},
1377
+ )
1378
+ except sqlite3.Error as exc:
1379
+ return SQLReward(
1380
+ score=_clamp(0.0),
1381
+ step_reward=_clamp(0.0),
1382
+ feedback=f"SQL error: {exc}",
1383
+ dimensions={"legacy_mode": True},
1384
+ partial_scores={},
1385
+ )
1386
+ finally:
1387
+ test_conn.close()
1388
+
1389
+
1390
+ __all__ = [
1391
+ "grade_null_audit",
1392
+ "grade_type_repair",
1393
+ "grade_dedup_bug",
1394
+ "grade_fk_integrity",
1395
+ "grade_schema_drift",
1396
+ "compute_episode_score",
1397
+ ]