Skip to content

Commit a77268f

Browse files
committed
docs(search): state that omitted match maps decode nil, and test it
The runtime omits primary_key, data and metadata from a match that has none, so json.Unmarshal leaves those maps nil. The doc comments said "Empty", which reads as an allocated empty map and hides that assigning into one panics. Say nil explicitly and assert it in the test: len == 0 also passes for an allocated empty map, so it did not pin down what a caller receives.
1 parent 759445e commit a77268f

2 files changed

Lines changed: 27 additions & 8 deletions

File tree

search.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ type SearchRequest struct {
3939
}
4040

4141
// SearchMatch is a single document matched by Search.
42+
//
43+
// The runtime omits primary_key, data and metadata from a match that has
44+
// none, so PrimaryKey, Data and Metadata are nil rather than empty in that
45+
// case. Reading from a nil map is safe and reports no entries; assigning into
46+
// one panics, so allocate before writing.
4247
type SearchMatch struct {
4348
// Dataset is the dataset the match was found in.
4449
Dataset string `json:"dataset"`
@@ -51,14 +56,16 @@ type SearchMatch struct {
5156
// to a single match.
5257
Matches map[string][]any `json:"matches"`
5358

54-
// PrimaryKey identifies the matched row. Empty when the dataset declares
55-
// no primary key.
59+
// PrimaryKey identifies the matched row. Nil when the dataset declares no
60+
// primary key.
5661
PrimaryKey map[string]any `json:"primary_key"`
5762

58-
// Data holds any AdditionalColumns that were requested.
63+
// Data holds any AdditionalColumns that were requested. Nil when none were
64+
// requested.
5965
Data map[string]any `json:"data"`
6066

61-
// Metadata holds extra per-match metadata the runtime attached.
67+
// Metadata holds extra per-match metadata the runtime attached. Nil when
68+
// it attached none.
6269
Metadata map[string]any `json:"metadata"`
6370
}
6471

search_test.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,23 @@ func TestSearchResponseDecoding(t *testing.T) {
173173
t.Errorf("Metadata[chunk] = %v, want 2", first.Metadata["chunk"])
174174
}
175175

176-
// The runtime omits data, primary_key, and metadata when they are empty.
176+
// The runtime omits data, primary_key, and metadata from a match that has
177+
// none, and an absent JSON key leaves the map nil. Assert nil rather than
178+
// len == 0, which would also pass for an allocated empty map and so would
179+
// not pin down what a caller actually receives.
177180
second := resp.Results[1]
178-
if len(second.PrimaryKey) != 0 || len(second.Data) != 0 || len(second.Metadata) != 0 {
179-
t.Errorf("omitted fields should decode empty, got PrimaryKey=%v Data=%v Metadata=%v",
180-
second.PrimaryKey, second.Data, second.Metadata)
181+
if second.PrimaryKey != nil {
182+
t.Errorf("omitted primary_key should decode nil, got %v", second.PrimaryKey)
183+
}
184+
if second.Data != nil {
185+
t.Errorf("omitted data should decode nil, got %v", second.Data)
186+
}
187+
if second.Metadata != nil {
188+
t.Errorf("omitted metadata should decode nil, got %v", second.Metadata)
189+
}
190+
// A nil map is still safe to read, which is what the doc comment promises.
191+
if got := second.PrimaryKey["id"]; got != nil {
192+
t.Errorf("reading a nil PrimaryKey should yield nil, got %v", got)
181193
}
182194
}
183195

0 commit comments

Comments
 (0)