Skip to content

Commit 3023ded

Browse files
authored
feat(Bigtable): validate row order (#8228)
1 parent b30e7ac commit 3023ded

3 files changed

Lines changed: 33 additions & 7 deletions

File tree

Bigtable/src/ChunkFormatter.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace Google\Cloud\Bigtable;
1919

20+
use Google\ApiCore\ApiException;
2021
use Google\ApiCore\ArrayTrait;
2122
use Google\Cloud\Bigtable\Exception\BigtableDataOperationException;
2223
use Google\Cloud\Bigtable\V2\Client\BigtableClient as GapicClient;
@@ -25,6 +26,7 @@
2526
use Google\Cloud\Bigtable\V2\RowRange;
2627
use Google\Cloud\Bigtable\V2\RowSet;
2728
use Google\Protobuf\Internal\Message;
29+
use Google\Rpc\Code;
2830

2931
/**
3032
* Converts cell chunks into an easily digestable format. Please note this class
@@ -370,6 +372,23 @@ private function reset()
370372
private function commit()
371373
{
372374
$rowKey = $this->rowKey;
375+
if ($this->prevRowKey) {
376+
// Validate that row keys are in ascending order
377+
$cmp = strcmp($this->prevRowKey, $rowKey);
378+
if ($this->request->getReversed()) {
379+
$cmp *= -1;
380+
}
381+
if ($cmp >= 0) {
382+
throw new ApiException(
383+
sprintf(
384+
'last scanned key must be strictly %s. New last scanned key=%s',
385+
$this->request->getReversed() ? 'decreasing' : 'increasing',
386+
$rowKey
387+
),
388+
Code::INTERNAL
389+
);
390+
}
391+
}
373392
$this->reset();
374393
$this->prevRowKey = $rowKey;
375394
}

Bigtable/tests/Conformance/proxy/known_failures.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ _Retry_WithRoutingCookie
22
_Retry_WithRetryInfo
33
TestMutateRows_Generic_DeadlineExceeded
44
TestReadRow_Generic_DeadlineExceeded
5-
TestReadRows_NoRetry_OutOfOrderError
65
TestReadRows_Retry_StreamReset
76
TestReadRows_Retry_PausedScan
87
TestReadRows_Retry_LastScannedRow

Bigtable/tests/Conformance/proxy/src/ProxyService.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,19 +200,27 @@ public function ReadRows(GRPC\ContextInterface $ctx, Testproxy\ReadRowsRequest $
200200
'rowRanges' => $ranges,
201201
'filter' => $request->getFilter(),
202202
'rowsLimit' => $request->getRowsLimit(),
203+
'reversed' => $request->getReversed(),
203204
'timeoutMillis' => $this->getTimeoutMillis($config->getPerOperationTimeout()),
204205
]);
205206

206207
$rows = [];
207208
$rowCount = 0;
208209
$cancelAfterRows = $in->getCancelAfterRows();
209-
foreach ($stream as $key => $rowData) {
210-
$row = $this->arrayToRowProto($rowData);
211-
$row->setKey($key);
212-
$rows[] = $row;
213-
if ($cancelAfterRows && ++$rowCount >= $cancelAfterRows) {
214-
break;
210+
try {
211+
foreach ($stream as $key => $rowData) {
212+
$row = $this->arrayToRowProto($rowData);
213+
$row->setKey($key);
214+
$rows[] = $row;
215+
if ($cancelAfterRows && ++$rowCount >= $cancelAfterRows) {
216+
break;
217+
}
215218
}
219+
} catch (\Google\ApiCore\ApiException $e) {
220+
return $out->setStatus(new Status([
221+
'code' => $e->getCode(),
222+
'message' => $e->getMessage(),
223+
]));
216224
}
217225

218226
$out->setRows($rows);

0 commit comments

Comments
 (0)