fix(stats): guard daily mileage source selection marking

This commit is contained in:
lingniu
2026-07-08 14:45:46 +08:00
parent bc2071ef42
commit 67aa521dd9
3 changed files with 85 additions and 6 deletions

View File

@@ -118,7 +118,15 @@ func ProjectDailyMileage(ctx context.Context, exec Execer, vin string, statDate
); err != nil {
return err
}
_, err := exec.ExecContext(ctx, markSelectedSourceSQL, vin, statDate, string(protocol))
_, err := exec.ExecContext(ctx, markSelectedSourceSQL,
vin,
statDate,
string(protocol),
maxSelectedDailyMileageKM,
vin,
statDate,
string(protocol),
)
return err
}
@@ -221,11 +229,31 @@ ON DUPLICATE KEY UPDATE
const markSelectedSourceSQL = `
UPDATE vehicle_daily_mileage_source s
JOIN vehicle_daily_mileage m
ON m.vin = s.vin
AND m.stat_date = s.stat_date
AND m.protocol = s.protocol
AND m.trusted_source_key = s.source_key
JOIN (
SELECT
s2.source_key,
s2.vin,
s2.stat_date,
s2.protocol
FROM vehicle_daily_mileage_source s2
LEFT JOIN vehicle_data_source ds
ON ds.protocol = s2.protocol AND ds.source_ip = s2.source_ip
WHERE s2.vin = ?
AND s2.stat_date = ?
AND s2.protocol = ?
AND s2.quality_status = '` + QualityOK + `'
AND s2.daily_mileage_km BETWEEN 0 AND ?
AND COALESCE(ds.enabled, 1) = 1
ORDER BY COALESCE(ds.trust_priority, 100),
s2.sample_count DESC,
s2.latest_event_time DESC,
s2.source_key ASC
LIMIT 1
) selected_source
ON selected_source.source_key = s.source_key
AND selected_source.vin = s.vin
AND selected_source.stat_date = s.stat_date
AND selected_source.protocol = s.protocol
SET s.is_selected = 1
WHERE s.vin = ? AND s.stat_date = ? AND s.protocol = ?
`

View File

@@ -119,4 +119,27 @@ func TestProjectDailyMileageSelectsCandidateAndMarksSource(t *testing.T) {
if !strings.Contains(markSelected, "UPDATE vehicle_daily_mileage_source s") || !strings.Contains(markSelected, "SET s.is_selected = 1") {
t.Fatalf("mark query should flag the elected source: %s", markSelected)
}
if strings.Contains(markSelected, "JOIN vehicle_daily_mileage m") {
t.Fatalf("mark query should not rejoin final mileage for candidate selection: %s", markSelected)
}
for _, want := range []string{
"JOIN (",
"SELECT",
"s2.source_key",
"s2.quality_status = '" + QualityOK + "'",
"s2.daily_mileage_km BETWEEN 0 AND",
"COALESCE(ds.enabled, 1) = 1",
"ORDER BY COALESCE(ds.trust_priority, 100)",
"LIMIT 1",
} {
if !strings.Contains(markSelected, want) {
t.Fatalf("mark query missing %q: %s", want, markSelected)
}
}
if len(exec.calls[2].args) != 7 {
t.Fatalf("mark query args = %d, want 7", len(exec.calls[2].args))
}
if got := exec.calls[2].args[3]; got != maxSelectedDailyMileageKM {
t.Fatalf("mark query max mileage arg = %#v, want %d", got, maxSelectedDailyMileageKM)
}
}