internal/{worker,postgres}: check current module for alternative

When reconciling the contents of search_documents when we insert a
module, consider whether the version currently being processed is
alternative.

Previously, we didn't consider the current module because we only
checked the DB, and the status code for the current module hasn't been
inserted yet.

Change-Id: Ibeb02d7f56341119e2bf4f20f148b345b2b82828
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/341868
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 253fe6e..49fbda6 100644
--- a/internal/postgres/insert_module.go
+++ b/internal/postgres/insert_module.go
@@ -640,7 +640,9 @@
 // ReInsertLatestVersion checks that the latest good version matches the version
 // in search_documents. If it doesn't, it inserts the latest good version into
 // search_documents and imports_unique.
-func (db *DB) ReInsertLatestVersion(ctx context.Context, modulePath string) (err error) {
+// The version and status arguments should come from the module currently being fetched.
+// They are used to determine if the module is alternative.
+func (db *DB) ReInsertLatestVersion(ctx context.Context, modulePath, version string, status int) (err error) {
 	defer derrors.WrapStack(&err, "ReInsertLatestVersion(%q)", modulePath)
 
 	return db.db.Transact(ctx, sql.LevelRepeatableRead, func(tx *database.DB) error {
@@ -657,9 +659,17 @@
 			log.Debugf(ctx, "ReInsertLatestVersion(%q): no latest-version info", modulePath)
 			return nil
 		}
-		alt, err := isAlternativeModulePath(ctx, tx, modulePath)
-		if err != nil {
-			return err
+		// Determine if this is an alternative module. The
+		// isAlternativeModulePath function checks the DB, but at the time
+		// ReInsertLatestVersion is called, we haven't added the current module
+		// version's status to the DB, so we use the version and status
+		// arguments.
+		alt := version == lmv.CookedVersion && status == derrors.ToStatus(derrors.AlternativeModule)
+		if !alt {
+			alt, err = isAlternativeModulePath(ctx, tx, modulePath)
+			if err != nil {
+				return err
+			}
 		}
 		if alt || lmv.GoodVersion == "" {
 			// A missing GoodVersion means that there are no good versions
diff --git a/internal/postgres/insert_module_test.go b/internal/postgres/insert_module_test.go
index 66233bf..2f5fbac 100644
--- a/internal/postgres/insert_module_test.go
+++ b/internal/postgres/insert_module_test.go
@@ -640,7 +640,7 @@
 		}); err != nil {
 			t.Fatal(err)
 		}
-		if err := testDB.ReInsertLatestVersion(ctx, modulePath); err != nil {
+		if err := testDB.ReInsertLatestVersion(ctx, modulePath, version, status); err != nil {
 			t.Fatal(err)
 		}
 	}
diff --git a/internal/worker/fetch.go b/internal/worker/fetch.go
index f4e83f4..8d74be0 100644
--- a/internal/worker/fetch.go
+++ b/internal/worker/fetch.go
@@ -115,18 +115,16 @@
 		return ft.Status, ft.ResolvedVersion, ft.Error
 	}
 
-	// Check if the latest good version of the module is not the one in search_documents,
-	// and insert it there and in imports_unique if so.
-	if lmv == nil || lmv.CookedVersion != ft.ResolvedVersion {
-		if err := f.DB.ReInsertLatestVersion(ctx, modulePath); err != nil {
-			log.Error(ctx, err)
-			if ft.Status != http.StatusInternalServerError {
-				ft.Error = err
-				ft.Status = http.StatusInternalServerError
-			}
-			// Do not return an error here, because we want to insert into
-			// module_version_states below.
+	// Make sure the latest version of the module is the one in search_documents
+	// and imports_unique.
+	if err := f.DB.ReInsertLatestVersion(ctx, modulePath, ft.ResolvedVersion, ft.Status); err != nil {
+		log.Error(ctx, err)
+		if ft.Status != http.StatusInternalServerError {
+			ft.Error = err
+			ft.Status = http.StatusInternalServerError
 		}
+		// Do not return an error here, because we want to insert into
+		// module_version_states below.
 	}
 
 	// Update the module_version_states table with the new status of
@@ -370,6 +368,7 @@
 	if err := db.DeleteModule(ctx, ft.ModulePath, ft.ResolvedVersion); err != nil {
 		return err
 	}
+
 	// Update the latest good version for this module, because deleting this
 	// version may have changed it.
 	if err := db.UpdateLatestGoodVersion(ctx, ft.ModulePath); err != nil {