Skip to content

Commit c6cba9f

Browse files
authored
fix: avoid consuming pending null values when merging (#286)
* test: add test for string array with pending null * fix: avoid consuming pending null values when merging * test: match implementation to test names Co-authored-by: larkee <[email protected]>
1 parent 9dfd527 commit c6cba9f

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

google/cloud/spanner_v1/streamed.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,17 @@ def _merge_array(lhs, rhs, type_):
258258
lhs.append(first)
259259
else:
260260
last = lhs.pop()
261-
try:
262-
merged = _merge_by_type(last, first, element_type)
263-
except Unmergeable:
261+
if last.HasField("null_value"):
264262
lhs.append(last)
265263
lhs.append(first)
266264
else:
267-
lhs.append(merged)
265+
try:
266+
merged = _merge_by_type(last, first, element_type)
267+
except Unmergeable:
268+
lhs.append(last)
269+
lhs.append(first)
270+
else:
271+
lhs.append(merged)
268272
return Value(list_value=ListValue(values=(lhs + rhs)))
269273

270274

@@ -284,13 +288,17 @@ def _merge_struct(lhs, rhs, type_):
284288
lhs.append(first)
285289
else:
286290
last = lhs.pop()
287-
try:
288-
merged = _merge_by_type(last, first, candidate_type)
289-
except Unmergeable:
291+
if last.HasField("null_value"):
290292
lhs.append(last)
291293
lhs.append(first)
292294
else:
293-
lhs.append(merged)
295+
try:
296+
merged = _merge_by_type(last, first, candidate_type)
297+
except Unmergeable:
298+
lhs.append(last)
299+
lhs.append(first)
300+
else:
301+
lhs.append(merged)
294302
return Value(list_value=ListValue(values=lhs + rhs))
295303

296304

tests/unit/test_streamed.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,11 +336,11 @@ def test__merge_chunk_array_of_string(self):
336336
FIELDS = [self._make_array_field("name", element_type_code=TypeCode.STRING)]
337337
streamed._metadata = self._make_result_set_metadata(FIELDS)
338338
streamed._pending_chunk = self._make_list_value([u"A", u"B", u"C"])
339-
chunk = self._make_list_value([None, u"D", u"E"])
339+
chunk = self._make_list_value([u"D", u"E"])
340340

341341
merged = streamed._merge_chunk(chunk)
342342

343-
expected = self._make_list_value([u"A", u"B", u"C", None, u"D", u"E"])
343+
expected = self._make_list_value([u"A", u"B", u"CD", u"E"])
344344
self.assertEqual(merged, expected)
345345
self.assertIsNone(streamed._pending_chunk)
346346

@@ -352,11 +352,25 @@ def test__merge_chunk_array_of_string_with_null(self):
352352
FIELDS = [self._make_array_field("name", element_type_code=TypeCode.STRING)]
353353
streamed._metadata = self._make_result_set_metadata(FIELDS)
354354
streamed._pending_chunk = self._make_list_value([u"A", u"B", u"C"])
355-
chunk = self._make_list_value([u"D", u"E"])
355+
chunk = self._make_list_value([None, u"D", u"E"])
356356

357357
merged = streamed._merge_chunk(chunk)
358358

359-
expected = self._make_list_value([u"A", u"B", u"CD", u"E"])
359+
expected = self._make_list_value([u"A", u"B", u"C", None, u"D", u"E"])
360+
self.assertEqual(merged, expected)
361+
self.assertIsNone(streamed._pending_chunk)
362+
363+
def test__merge_chunk_array_of_string_with_null_pending(self):
364+
from google.cloud.spanner_v1 import TypeCode
365+
366+
iterator = _MockCancellableIterator()
367+
streamed = self._make_one(iterator)
368+
FIELDS = [self._make_array_field("name", element_type_code=TypeCode.STRING)]
369+
streamed._metadata = self._make_result_set_metadata(FIELDS)
370+
streamed._pending_chunk = self._make_list_value([u"A", u"B", u"C", None])
371+
chunk = self._make_list_value([u"D", u"E"])
372+
merged = streamed._merge_chunk(chunk)
373+
expected = self._make_list_value([u"A", u"B", u"C", None, u"D", u"E"])
360374
self.assertEqual(merged, expected)
361375
self.assertIsNone(streamed._pending_chunk)
362376

0 commit comments

Comments
 (0)