internal/worker,govulncheck: add binary build time

This adds binary build time to the govulncheck bigquery schema. Binary
build time is used to compare the time it takes to build and scan a
binary with govulncheck to the time it takes to scan a package with
govulncheck in source mode.

Change-Id: Ie7bef9a30f45afd5a7f9e914dc3f42c3b0bf26eb
Reviewed-on: https://go-review.googlesource.com/c/pkgsite-metrics/+/518496
Reviewed-by: Jonathan Amsterdam <jba@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Zvonimir Pavlinovic <zpavlinovic@google.com>
Run-TryBot: Maceo Thompson <maceothompson@google.com>
diff --git a/internal/bigquery/bigquery.go b/internal/bigquery/bigquery.go
index 5f51c6f..238b32e 100644
--- a/internal/bigquery/bigquery.go
+++ b/internal/bigquery/bigquery.go
@@ -254,6 +254,11 @@
 	return c.client.Query(q).Read(ctx)
 }
 
+// NullFloat constructs a bq.NullFloat64
+func NullFloat(f float64) bq.NullFloat64 {
+	return bq.NullFloat64{Float64: f, Valid: true}
+}
+
 // NullString constructs a bq.NullString.
 func NullString(s string) bq.NullString {
 	return bq.NullString{StringVal: s, Valid: true}
diff --git a/internal/govulncheck/govulncheck.go b/internal/govulncheck/govulncheck.go
index 9a95278..cecd547 100644
--- a/internal/govulncheck/govulncheck.go
+++ b/internal/govulncheck/govulncheck.go
@@ -19,6 +19,8 @@
 	"strings"
 	"time"
 
+	bq "cloud.google.com/go/bigquery"
+
 	"golang.org/x/pkgsite-metrics/internal/bigquery"
 	"golang.org/x/pkgsite-metrics/internal/derrors"
 	"golang.org/x/pkgsite-metrics/internal/govulncheckapi"
@@ -139,10 +141,12 @@
 	ErrorCategory string    `bigquery:"error_category"`
 	CommitTime    time.Time `bigquery:"commit_time"`
 	ScanSeconds   float64   `bigquery:"scan_seconds"`
-	ScanMemory    int64     `bigquery:"scan_memory"`
-	ScanMode      string    `bigquery:"scan_mode"`
-	WorkVersion             // InferSchema flattens embedded fields
-	Vulns         []*Vuln   `bigquery:"vulns"`
+	// BinaryBuildSeconds is populated only in COMPARE - BINARY mode
+	BinaryBuildSeconds bq.NullFloat64 `bigquery:"build_seconds"`
+	ScanMemory         int64          `bigquery:"scan_memory"`
+	ScanMode           string         `bigquery:"scan_mode"`
+	WorkVersion                       // InferSchema flattens embedded fields
+	Vulns              []*Vuln        `bigquery:"vulns"`
 }
 
 // WorkVersion contains information that can be used to avoid duplicate work.
diff --git a/internal/worker/govulncheck_scan.go b/internal/worker/govulncheck_scan.go
index 49cbd66..9aaa7d4 100644
--- a/internal/worker/govulncheck_scan.go
+++ b/internal/worker/govulncheck_scan.go
@@ -260,6 +260,7 @@
 	}
 	if mode == ModeBinary {
 		row.ScanMode = "COMPARE - BINARY"
+		row.BinaryBuildSeconds = bigquery.NullFloat(result.Stats.BuildTime.Seconds())
 	} else {
 		row.ScanMode = "COMPARE - SOURCE"
 	}