storage/db: ListUploads shouldn't return empty uploads

The Uploads table gets an entry when a user or the server aborts an
upload in mid-upload. The Records table is cleaned up by the
transaction, but the Uploads entry is left behind.

The optimized query that is used for the perf.golang.org homepage did
not properly exclude these uploads that have no records.

Change-Id: I8322af5946c233e5cb4b15bf57d9487bcd1e6423
Reviewed-on: https://go-review.googlesource.com/39051
Run-TryBot: Quentin Smith <quentin@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/storage/db/db.go b/storage/db/db.go
index a53931e..ea0b603 100644
--- a/storage/db/db.go
+++ b/storage/db/db.go
@@ -597,7 +597,7 @@
 	}
 	if len(sql) == 0 {
 		// Optimize empty query.
-		query += " FROM (SELECT UploadID, (SELECT COUNT(*) FROM Records r WHERE r.UploadID = u.UploadID) AS rCount FROM Uploads u ORDER BY u.Day DESC, u.Seq DESC, u.UploadID DESC"
+		query += " FROM (SELECT UploadID, (SELECT COUNT(*) FROM Records r WHERE r.UploadID = u.UploadID) AS rCount FROM Uploads u WHERE rCount > 0 ORDER BY u.Day DESC, u.Seq DESC, u.UploadID DESC"
 		if limit != 0 {
 			query += fmt.Sprintf(" LIMIT %d", limit)
 		}
diff --git a/storage/db/db_test.go b/storage/db/db_test.go
index 76b8adf..bbc1d9d 100644
--- a/storage/db/db_test.go
+++ b/storage/db/db_test.go
@@ -345,7 +345,7 @@
 	db, cleanup := dbtest.NewDB(t)
 	defer cleanup()
 
-	for i := 0; i < 9; i++ {
+	for i := -1; i < 9; i++ {
 		u, err := db.NewUpload(context.Background())
 		if err != nil {
 			t.Fatalf("NewUpload: %v", err)
@@ -381,11 +381,11 @@
 		limit       int
 		want        []result
 	}{
-		{"", nil, 0, []result{{9, "19700101.9"}, {8, "19700101.8"}, {7, "19700101.7"}, {6, "19700101.6"}, {5, "19700101.5"}, {4, "19700101.4"}, {3, "19700101.3"}, {2, "19700101.2"}, {1, "19700101.1"}}},
-		{"", nil, 2, []result{{9, "19700101.9"}, {8, "19700101.8"}}},
-		{"j:5", nil, 0, []result{{1, "19700101.9"}, {1, "19700101.8"}, {1, "19700101.7"}, {1, "19700101.6"}}},
-		{"i:5", nil, 0, []result{{6, "19700101.6"}}},
-		{"i:5", []string{"i", "missing"}, 0, []result{{6, "19700101.6"}}},
+		{"", nil, 0, []result{{9, "19700101.10"}, {8, "19700101.9"}, {7, "19700101.8"}, {6, "19700101.7"}, {5, "19700101.6"}, {4, "19700101.5"}, {3, "19700101.4"}, {2, "19700101.3"}, {1, "19700101.2"}}},
+		{"", nil, 2, []result{{9, "19700101.10"}, {8, "19700101.9"}}},
+		{"j:5", nil, 0, []result{{1, "19700101.10"}, {1, "19700101.9"}, {1, "19700101.8"}, {1, "19700101.7"}}},
+		{"i:5", nil, 0, []result{{6, "19700101.7"}}},
+		{"i:5", []string{"i", "missing"}, 0, []result{{6, "19700101.7"}}},
 		{"not:found", nil, 0, nil},
 	}
 
@@ -408,8 +408,8 @@
 						if err != nil {
 							t.Fatalf("cannot parse upload ID %q", res.id)
 						}
-						if v != fmt.Sprintf("%d", uploadNum-1) {
-							t.Errorf(`i = %q, want "%d"`, v, uploadNum-1)
+						if v != fmt.Sprintf("%d", uploadNum-2) {
+							t.Errorf(`i = %q, want "%d"`, v, uploadNum-2)
 						}
 					default:
 						t.Errorf("unexpected label %q", k)