internal/postgres: sort symbols to prevent deadlocks

Before inserting into symbols, package_symbols and documentation_symbols,
sort to prevent deadlocks.

For golang/go#37102

Change-Id: Ibcf5e6bc9f30320499ea0ea28db4a67f3a67d4e8
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/304509
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
diff --git a/internal/postgres/symbol.go b/internal/postgres/symbol.go
index 5a15de1..4700db1 100644
--- a/internal/postgres/symbol.go
+++ b/internal/postgres/symbol.go
@@ -8,6 +8,7 @@
 	"context"
 	"database/sql"
 	"fmt"
+	"sort"
 
 	"github.com/lib/pq"
 	"golang.org/x/pkgsite/internal"
@@ -105,10 +106,17 @@
 	// Get the difference between the documentation_symbols for this package,
 	// and the ones that already exist in the documentation_symbols table. Only
 	// insert rows that do not already exist.
+	//
+	// Sort first to prevent deadlocks.
+	var docIDs []int
+	for docID := range docIDToPkgsymIDs {
+		docIDs = append(docIDs, docID)
+	}
+	sort.Ints(docIDs)
 	var values []interface{}
-	for docID, pkgsymIDSet := range docIDToPkgsymIDs {
+	for _, docID := range docIDs {
 		gotSet := gotDocIDToPkgsymIDs[docID]
-		for pkgsymID := range pkgsymIDSet {
+		for pkgsymID := range docIDToPkgsymIDs[docID] {
 			if !gotSet[pkgsymID] {
 				values = append(values, docID, pkgsymID)
 			}
@@ -182,8 +190,16 @@
 		return nil, err
 	}
 
+	// Sort to prevent deadlocks.
+	var paths []string
+	for path := range pathToDocIDToDoc {
+		paths = append(paths, path)
+	}
+	sort.Strings(paths)
+
 	var packageSymbols []interface{}
-	for path, docs := range pathToDocIDToDoc {
+	for _, path := range paths {
+		docs := pathToDocIDToDoc[path]
 		pathID := pathToID[path]
 		if pathID == 0 {
 			return nil, fmt.Errorf("pathID cannot be 0: %q", path)
@@ -268,6 +284,7 @@
 		return nil, err
 	}
 
+	sort.Strings(names)
 	var values []interface{}
 	for _, name := range names {
 		if _, ok := nameToID[name]; !ok {