diff --git a/BigQuery/src/BigQueryClient.php b/BigQuery/src/BigQueryClient.php index c8713355fb53..87ca2ca00fb4 100644 --- a/BigQuery/src/BigQueryClient.php +++ b/BigQuery/src/BigQueryClient.php @@ -437,19 +437,28 @@ public function runQuery(JobConfigurationInterface $query, array $options = []) $response = $this->connection->query($statelessArgs); + $jobId = $response['jobReference']['jobId'] ?? ''; + $jobInfo = ['jobReference' => $response['jobReference'] ?? []]; + if (isset($response['statistics'])) { + $jobInfo['statistics'] = $response['statistics']; + } + if ($response['jobComplete'] ?? false) { + // This is to keep it consistent with the response from a non stateless query + $jobInfo['status']['state'] = Job::DONE; return new QueryResults( $this->connection, - '', + $jobId, $this->projectId, $response, $this->mapper, - $this->createJob([], ''), // create an empty job + $this->createJob($jobInfo, $jobId), $queryResultsOptions ); } - $job = $this->createJob($response, $response['jobReference']['jobId']); + $jobInfo['status']['state'] = null; + $job = $this->createJob($jobInfo, $jobId); } else { $job = $this->startQuery($query, $options); } diff --git a/BigQuery/src/Job.php b/BigQuery/src/Job.php index 23b0baddd072..c07b6f1b45e8 100644 --- a/BigQuery/src/Job.php +++ b/BigQuery/src/Job.php @@ -33,6 +33,7 @@ class Job use JobWaitTrait; const MAX_RETRIES = PHP_INT_MAX; + const DONE = 'DONE'; /** * @var ConnectionInterface Represents a connection to BigQuery. @@ -266,7 +267,7 @@ function () use ($options) { */ public function isComplete(array $options = []) { - return $this->info($options)['status']['state'] === 'DONE'; + return $this->info($options)['status']['state'] === self::DONE; } /** diff --git a/BigQuery/tests/Unit/BigQueryClientTest.php b/BigQuery/tests/Unit/BigQueryClientTest.php index 6ffa79b16b67..1a2153cb19ea 100644 --- a/BigQuery/tests/Unit/BigQueryClientTest.php +++ b/BigQuery/tests/Unit/BigQueryClientTest.php @@ -182,6 +182,56 @@ public function testRunQueryStateless() $this->assertTrue($queryResults->isComplete()); } + public function testRunQueryStatelessWithPagination() + { + $client = $this->getClient(); + $query = $client->query(self::QUERY_STRING); + + $this->connection->query(Argument::allOf( + Argument::withEntry('projectId', self::PROJECT_ID), + Argument::withEntry('query', self::QUERY_STRING), + Argument::withEntry('jobCreationMode', 'JOB_CREATION_OPTIONAL') + )) + ->willReturn([ + 'jobComplete' => true, + 'jobReference' => [ + 'jobId' => self::JOB_ID, + 'projectId' => self::PROJECT_ID + ], + 'schema' => [ + 'fields' => [ + ['name' => 'col1', 'type' => 'STRING'] + ] + ], + 'rows' => [ + ['f' => [['v' => 'val1']]] + ], + 'pageToken' => 'next-page-token' + ]) + ->shouldBeCalledTimes(1); + + $this->connection->getQueryResults(Argument::allOf( + Argument::withEntry('projectId', self::PROJECT_ID), + Argument::withEntry('jobId', self::JOB_ID), + Argument::withEntry('pageToken', 'next-page-token') + )) + ->willReturn([ + 'jobComplete' => true, + 'rows' => [ + ['f' => [['v' => 'val2']]] + ] + ]) + ->shouldBeCalledTimes(1); + + $client->___setProperty('connection', $this->connection->reveal()); + $results = $client->runQuery($query); + $rows = iterator_to_array($results); + + $this->assertCount(2, $rows); + $this->assertEquals('val1', $rows[0]['col1']); + $this->assertEquals('val2', $rows[1]['col1']); + } + public function testRunQueryJobQueryEndpointReturnsAJob() { $client = $this->getClient();