Skip to content

Commit b1c7d34

Browse files
feat: (BigQuery) Add Remote Function support (#9177)
1 parent 493b705 commit b1c7d34

5 files changed

Lines changed: 143 additions & 1 deletion

File tree

BigQuery/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"erusev/parsedown": "^1.6",
1818
"google/cloud-storage": "^2.0",
1919
"google/cloud-bigquery-reservation": "^2.0",
20-
"nikic/php-parser": "^5.0"
20+
"nikic/php-parser": "^5.0",
21+
"google/cloud-bigquery-connection": "^2.1"
2122
},
2223
"suggest": {
2324
"google/cloud-storage": "Makes it easier to load data from Cloud Storage into BigQuery"

BigQuery/src/Dataset.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,22 @@ function (array $routine) {
510510
* ]);
511511
* ```
512512
*
513+
* ```
514+
* // Create a routine with remote function options.
515+
* $routine = $dataset->createRoutine('my_remote_udf', [
516+
* 'routineType' => 'SCALAR_FUNCTION',
517+
* 'language' => 'SQL',
518+
* 'remoteFunctionOptions' => [
519+
* 'endpoint' => 'https://us-east1-my_gcf_project.cloudfunctions.net/remote_add',
520+
* 'connection' => 'projects/project-id/locations/us/connections/connection-id',
521+
* 'maxBatchingRows' => '10',
522+
* 'userDefinedContext' => [
523+
* 'key' => 'value'
524+
* ]
525+
* ]
526+
* ]);
527+
* ```
528+
*
513529
* @see https://cloud.google.com/bigquery/docs/reference/rest/v2/routines/insert Insert Routines API documentation.
514530
*
515531
* @param string $id The routine ID.

BigQuery/src/Routine.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,20 @@ public function exists(array $options = [])
201201
* ]);
202202
* ```
203203
*
204+
* ```
205+
* // Update the routine with remote function options.
206+
* $routine->update([
207+
* 'remoteFunctionOptions' => [
208+
* 'endpoint' => 'https://us-east1-my_gcf_project.cloudfunctions.net/remote_add',
209+
* 'connection' => 'projects/project-id/locations/us/connections/connection-id',
210+
* 'maxBatchingRows' => '10',
211+
* 'userDefinedContext' => [
212+
* 'key' => 'value'
213+
* ]
214+
* ]
215+
* ]);
216+
* ```
217+
*
204218
* @see https://cloud.google.com/bigquery/docs/reference/rest/v2/routines/update Update Routines API documentation.
205219
* @param array $metadata The full routine resource with desired
206220
* modifications.

BigQuery/tests/System/ManageRoutinesTest.php

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

1818
namespace Google\Cloud\BigQuery\Tests\System;
1919

20+
use Google\Cloud\BigQuery\Connection\V1\Client\ConnectionServiceClient;
21+
use Google\Cloud\BigQuery\Connection\V1\CloudResourceProperties;
22+
use Google\Cloud\BigQuery\Connection\V1\Connection;
23+
use Google\Cloud\BigQuery\Connection\V1\CreateConnectionRequest;
24+
use Google\Cloud\BigQuery\Connection\V1\DeleteConnectionRequest;
2025
use Google\Cloud\BigQuery\Routine;
2126

2227
/**
@@ -133,4 +138,75 @@ public function testCreateAndDeleteRoutine()
133138

134139
$this->assertFalse($routine->exists());
135140
}
141+
142+
public function testCreateRemoteUdf()
143+
{
144+
$routineId = uniqid(self::TESTING_PREFIX);
145+
$connectionId = uniqid('udf_conn');
146+
147+
$connectionName = $this->createConnection($connectionId);
148+
149+
try {
150+
$routine = self::$dataset->createRoutine($routineId, [
151+
'routineType' => 'SCALAR_FUNCTION',
152+
'language' => 'SQL',
153+
'returnType' => [
154+
'typeKind' => 'STRING'
155+
],
156+
'remoteFunctionOptions' => [
157+
'endpoint' => 'https://us-east1-my_gcf_project.cloudfunctions.net/remote_add',
158+
'connection' => $connectionName,
159+
'maxBatchingRows' => '10',
160+
'userDefinedContext' => [
161+
'key' => 'value'
162+
]
163+
]
164+
]);
165+
166+
$this->assertTrue($routine->exists());
167+
168+
$info = $routine->info();
169+
$this->assertEquals('SCALAR_FUNCTION', $info['routineType']);
170+
$this->assertArrayHasKey('remoteFunctionOptions', $info);
171+
$this->assertEquals(
172+
'https://us-east1-my_gcf_project.cloudfunctions.net/remote_add',
173+
$info['remoteFunctionOptions']['endpoint']
174+
);
175+
176+
$routine->delete();
177+
} finally {
178+
$this->deleteConnection($connectionName);
179+
}
180+
}
181+
182+
private function createConnection($connectionId)
183+
{
184+
$projectId = self::$dataset->identity()['projectId'];
185+
$location = 'us';
186+
$parent = "projects/$projectId/locations/$location";
187+
188+
$connectionClient = new ConnectionServiceClient();
189+
190+
$connection = new Connection();
191+
$connection->setFriendlyName($connectionId);
192+
$connection->setCloudResource(new CloudResourceProperties());
193+
194+
$request = new CreateConnectionRequest();
195+
$request->setParent($parent);
196+
$request->setConnectionId($connectionId);
197+
$request->setConnection($connection);
198+
199+
$response = $connectionClient->createConnection($request);
200+
return $response->getName();
201+
}
202+
203+
private function deleteConnection($name)
204+
{
205+
$connectionClient = new ConnectionServiceClient();
206+
207+
$request = new DeleteConnectionRequest();
208+
$request->setName($name);
209+
210+
$connectionClient->deleteConnection($request);
211+
}
136212
}

BigQuery/tests/Unit/RoutineTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,41 @@ public function testUpdateWithMask()
209209
$this->assertEquals($expected, $res);
210210
}
211211

212+
public function testUpdateRemoteFunctionOptions()
213+
{
214+
$old = [
215+
'routineType' => 'SCALAR_FUNCTION',
216+
'definitionBody' => '',
217+
'language' => 'SQL'
218+
];
219+
220+
$new = [
221+
'remoteFunctionOptions' => [
222+
'endpoint' => 'https://us-east1-my_gcf_project.cloudfunctions.net/remote_add',
223+
'connection' => 'projects/project-id/locations/us/connections/connection-id',
224+
'maxBatchingRows' => '10',
225+
'userDefinedContext' => [
226+
'key' => 'value'
227+
]
228+
]
229+
];
230+
231+
$expected = $old + $new;
232+
233+
$this->connection->getRoutine($this->identity)
234+
->willReturn($old)
235+
->shouldBeCalledTimes(1);
236+
237+
$this->connection->updateRoutine($this->identity + $expected + ['retries' => 0])
238+
->shouldBeCalledTimes(1)
239+
->willReturn($expected);
240+
241+
$this->routine->___setProperty('connection', $this->connection->reveal());
242+
$res = $this->routine->update($new);
243+
244+
$this->assertEquals($expected, $res);
245+
}
246+
212247
public function testDelete()
213248
{
214249
$this->connection->deleteRoutine($this->identity + ['retries' => 0])

0 commit comments

Comments
 (0)