internal/postgres: remove a fully retracted module from search

If all the versions of a module have been retracted, remove it
from the search_documents table so it doesn't appear in search.

Also remove it from the imports_unique table so it doesn't contribute
to the imported-by counts of other modules.

For golang/go#47590

Change-Id: I76a6e33a1291abe4a19f1b3521c9dc8ebed4f110
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/341591
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/internal/postgres/insert_module.go b/internal/postgres/insert_module.go
index ef71c46..f406ca8 100644
--- a/internal/postgres/insert_module.go
+++ b/internal/postgres/insert_module.go
@@ -660,13 +660,19 @@
 			return nil
 		}
 		if lmv.GoodVersion == "" {
-			// TODO(golang/go#44710): once we are confident that
-			// latest_module_versions is accurate and up to date, we can assume
-			// that a missing GoodVersion should mean that there are no good
-			// versions remaining, and we should remove the current module from
+			// A missing GoodVersion means that there are no good versions
+			// remaining, and we should remove the current module from
 			// search_documents.
-			log.Debugf(ctx, "ReInsertLatestVersion(%q): no good version", modulePath)
-			return nil
+			if err := deleteModuleOrPackagesInModuleFromSearchDocuments(ctx, tx, modulePath, nil); err != nil {
+				return err
+			}
+			if _, err := tx.Exec(ctx, `
+				DELETE FROM imports_unique
+				WHERE from_module_path = $1
+			`, modulePath); err != nil {
+				return err
+			}
+			log.Debugf(ctx, "ReInsertLatestVersion(%q): no good version; removed from search_documents and imports_unique", modulePath)
 		}
 		// Is the latest good version in search_documents?
 		var x int
diff --git a/internal/postgres/insert_module_test.go b/internal/postgres/insert_module_test.go
index 28e4ce4..0bac9bb 100644
--- a/internal/postgres/insert_module_test.go
+++ b/internal/postgres/insert_module_test.go
@@ -694,16 +694,20 @@
 	check := func(wantVersion string, wantImports []string) {
 		t.Helper()
 		var gotVersion, gotSynopsis string
-		if err := testDB.db.QueryRow(ctx, `
+		err := testDB.db.QueryRow(ctx, `
 			SELECT version, synopsis
 			FROM search_documents
 			WHERE module_path = 'm.com/a'
 			AND package_path = 'm.com/a/pkg'
-		`).Scan(&gotVersion, &gotSynopsis); err != nil {
+		`).Scan(&gotVersion, &gotSynopsis)
+		if errors.Is(err, sql.ErrNoRows) {
+			gotVersion = ""
+			gotSynopsis = ""
+		} else if err != nil {
 			t.Fatal(err)
 		}
 		if gotVersion != wantVersion && gotSynopsis != wantVersion {
-			t.Fatalf("got version %s, synopsis %q, want %s for both", gotVersion, gotSynopsis, wantVersion)
+			t.Fatalf("got version %q, synopsis %q, want %q for both", gotVersion, gotSynopsis, wantVersion)
 		}
 
 		gotImports, err := testDB.db.CollectStrings(ctx, `
@@ -736,4 +740,9 @@
 	// The search_documents and imports_unique tables should go back to v1.1.0.
 	insert("v1.3.0", 400, nil, "retract v1.2.0")
 	check("v1.1.0", imports1)
+
+	// Now a still higher version comes along that retracts everything. The
+	// module should no longer be in search_documents or imports_unique.
+	insert("v1.4.0", 200, nil, "retract [v1.0.0, v1.4.0]")
+	check("", nil)
 }