fix(bigquery): empty slice instead of nil slice for primitive repeated fields (#7315)

diff --git a/bigquery/integration_test.go b/bigquery/integration_test.go
index 95c3a51..239aea0 100644
--- a/bigquery/integration_test.go
+++ b/bigquery/integration_test.go
@@ -24,6 +24,7 @@
 	"math/big"
 	"net/http"
 	"os"
+	"reflect"
 	"sort"
 	"strings"
 	"testing"
@@ -2527,6 +2528,37 @@
 	}
 }
 
+func TestIntegration_QueryEmptyArrays(t *testing.T) {
+	if client == nil {
+		t.Skip("Integration tests skipped")
+	}
+	ctx := context.Background()
+
+	q := client.Query("SELECT ARRAY<string>[] as a, ARRAY<STRUCT<name string>>[] as b")
+	it, err := q.Read(ctx)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for {
+		vals := map[string]Value{}
+		if err := it.Next(&vals); err != nil {
+			if errors.Is(err, iterator.Done) {
+				break
+			}
+		}
+
+		valueOfA := reflect.ValueOf(vals["a"])
+		if testutil.Equal(vals["a"], nil) || valueOfA.IsNil() {
+			t.Fatalf("expected empty string array to not return nil, but found %v %v %T", valueOfA, vals["a"], vals["a"])
+		}
+
+		valueOfB := reflect.ValueOf(vals["b"])
+		if testutil.Equal(vals["b"], nil) || valueOfB.IsNil() {
+			t.Fatalf("expected empty struct array to not return nil, but found %v %v %T", valueOfB, vals["b"], vals["b"])
+		}
+	}
+}
+
 // This test can be merged with the TestIntegration_QueryParameters as soon as support for explicit typed query parameter lands.
 // To test timestamps with different formats, we need to be able to specify the type explicitly.
 func TestIntegration_TimestampFormat(t *testing.T) {
diff --git a/bigquery/iterator.go b/bigquery/iterator.go
index 9d177d1..942be42 100644
--- a/bigquery/iterator.go
+++ b/bigquery/iterator.go
@@ -140,8 +140,12 @@
 // See https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#numeric-type
 // for more on NUMERIC.
 //
-// A repeated field corresponds to a slice or array of the element type. A STRUCT
-// type (RECORD or nested schema) corresponds to a nested struct or struct pointer.
+// A repeated field corresponds to a slice or array of the element type. BigQuery translates
+// NULL arrays into an empty array, so we follow that behavior.
+// See https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#array_nulls
+// for more about NULL and empty arrays.
+//
+// A STRUCT type (RECORD or nested schema) corresponds to a nested struct or struct pointer.
 // All calls to Next on the same iterator must use the same struct type.
 //
 // It is an error to attempt to read a BigQuery NULL value into a struct field,
diff --git a/bigquery/value.go b/bigquery/value.go
index c178f8b..5c0165f 100644
--- a/bigquery/value.go
+++ b/bigquery/value.go
@@ -82,6 +82,9 @@
 			}
 			v = vs
 		}
+		if f.Repeated && (v == nil || reflect.ValueOf(v).IsNil()) {
+			v = []Value{}
+		}
 
 		m[f.Name] = v
 	}
diff --git a/bigquery/value_test.go b/bigquery/value_test.go
index 7211835..024f680 100644
--- a/bigquery/value_test.go
+++ b/bigquery/value_test.go
@@ -825,10 +825,12 @@
 		{Name: "i", Type: IntegerFieldType},
 		{Name: "f", Type: FloatFieldType},
 		{Name: "b", Type: BooleanFieldType},
-		{Name: "n", Type: RecordFieldType, Schema: ns},
+		{Name: "sn", Type: StringFieldType, Repeated: true},
+		{Name: "r", Type: RecordFieldType, Schema: ns},
 		{Name: "rn", Type: RecordFieldType, Schema: ns, Repeated: true},
 	}
 	in := []Value{"x", 7, 3.14, true,
+		[]Value{"a", "b"},
 		[]Value{1, 2},
 		[]Value{[]Value{3, 4}, []Value{5, 6}},
 	}
@@ -837,11 +839,12 @@
 		t.Fatal(err)
 	}
 	want := map[string]Value{
-		"s": "x",
-		"i": 7,
-		"f": 3.14,
-		"b": true,
-		"n": map[string]Value{"x": 1, "y": 2},
+		"s":  "x",
+		"i":  7,
+		"f":  3.14,
+		"b":  true,
+		"sn": []Value{"a", "b"},
+		"r":  map[string]Value{"x": 1, "y": 2},
 		"rn": []Value{
 			map[string]Value{"x": 3, "y": 4},
 			map[string]Value{"x": 5, "y": 6},
@@ -857,8 +860,9 @@
 		"i":  nil,
 		"f":  nil,
 		"b":  nil,
-		"n":  nil,
-		"rn": nil,
+		"sn": []Value{},
+		"r":  nil,
+		"rn": []Value{},
 	}
 	var vm2 valueMap
 	if err := vm2.Load(in, schema); err != nil {