fix: fix rows returned when both start_index and page_size are provid… · googleapis/python-bigquery@45643a2
@@ -1682,6 +1682,78 @@ def test_result_with_start_index(self):
16821682tabledata_list_request[1]["query_params"]["maxResults"], page_size
16831683 )
168416841685+def test_result_with_start_index_multi_page(self):
1686+# When there are multiple pages of response and the user has set
1687+# start_index, we should supply start_index to the server in the first
1688+# request. However, in the subsequent requests, we will pass only
1689+# page_token but not start_index, because the server only allows one
1690+# of them.
1691+from google.cloud.bigquery.table import RowIterator
1692+1693+query_resource = {
1694+"jobComplete": True,
1695+"jobReference": {"projectId": self.PROJECT, "jobId": self.JOB_ID},
1696+"schema": {"fields": [{"name": "col1", "type": "STRING"}]},
1697+"totalRows": "7",
1698+ }
1699+1700+# Although the result has 7 rows, the response only returns 6, because
1701+# start_index is 1.
1702+tabledata_resource_1 = {
1703+"totalRows": "7",
1704+"pageToken": "page_token_1",
1705+"rows": [
1706+ {"f": [{"v": "abc"}]},
1707+ {"f": [{"v": "def"}]},
1708+ {"f": [{"v": "ghi"}]},
1709+ ],
1710+ }
1711+tabledata_resource_2 = {
1712+"totalRows": "7",
1713+"pageToken": None,
1714+"rows": [
1715+ {"f": [{"v": "jkl"}]},
1716+ {"f": [{"v": "mno"}]},
1717+ {"f": [{"v": "pqe"}]},
1718+ ],
1719+ }
1720+1721+connection = make_connection(
1722+query_resource, tabledata_resource_1, tabledata_resource_2
1723+ )
1724+client = _make_client(self.PROJECT, connection=connection)
1725+resource = self._make_resource(ended=True)
1726+job = self._get_target_class().from_api_repr(resource, client)
1727+1728+start_index = 1
1729+page_size = 3
1730+1731+result = job.result(page_size=page_size, start_index=start_index)
1732+1733+self.assertIsInstance(result, RowIterator)
1734+self.assertEqual(result.total_rows, 7)
1735+1736+rows = list(result)
1737+1738+self.assertEqual(len(rows), 6)
1739+self.assertEqual(len(connection.api_request.call_args_list), 3)
1740+1741+# First call has both startIndex and maxResults.
1742+tabledata_list_request_1 = connection.api_request.call_args_list[1]
1743+self.assertEqual(
1744+tabledata_list_request_1[1]["query_params"]["startIndex"], start_index
1745+ )
1746+self.assertEqual(
1747+tabledata_list_request_1[1]["query_params"]["maxResults"], page_size
1748+ )
1749+1750+# Second call only has maxResults.
1751+tabledata_list_request_2 = connection.api_request.call_args_list[2]
1752+self.assertFalse("startIndex" in tabledata_list_request_2[1]["query_params"])
1753+self.assertEqual(
1754+tabledata_list_request_2[1]["query_params"]["maxResults"], page_size
1755+ )
1756+16851757def test_result_error(self):
16861758from google.cloud import exceptions
16871759