Skip to content

Commit e950379

Browse files
authored
fix(Spanner): Making DML returning samples consistent with other languages (#1785)
1 parent 8ba72af commit e950379

10 files changed

+194
-109
lines changed

spanner/src/create_database.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ function create_database(string $instanceId, string $databaseId): void
5050
SingerId INT64 NOT NULL,
5151
FirstName STRING(1024),
5252
LastName STRING(1024),
53-
SingerInfo BYTES(MAX)
53+
SingerInfo BYTES(MAX),
54+
FullName STRING(2048) AS
55+
(ARRAY_TO_STRING([FirstName, LastName], " ")) STORED
5456
) PRIMARY KEY (SingerId)',
5557
'CREATE TABLE Albums (
5658
SingerId INT64 NOT NULL,

spanner/src/delete_dml_returning.php

+13-11
Original file line numberDiff line numberDiff line change
@@ -40,24 +40,26 @@ function delete_dml_returning(string $instanceId, string $databaseId): void
4040

4141
$transaction = $database->transaction();
4242

43-
// DML returning sql delete query
43+
// Delete records from SINGERS table satisfying a particular condition and
44+
// returns the SingerId and FullName column of the deleted records using
45+
// 'THEN RETURN SingerId, FullName'. It is also possible to return all columns
46+
// of all the deleted records by using 'THEN RETURN *'.
47+
4448
$result = $transaction->execute(
45-
'DELETE FROM Singers WHERE FirstName = @firstName '
46-
. 'THEN RETURN *',
47-
[
48-
'parameters' => [
49-
'firstName' => 'Melissa',
50-
]
51-
]
49+
"DELETE FROM Singers WHERE FirstName = 'Alice' "
50+
. 'THEN RETURN SingerId, FullName',
5251
);
5352
foreach ($result->rows() as $row) {
5453
printf(
55-
'Row (%s, %s, %s) deleted' . PHP_EOL,
54+
'%d %s.' . PHP_EOL,
5655
$row['SingerId'],
57-
$row['FirstName'],
58-
$row['LastName']
56+
$row['FullName']
5957
);
6058
}
59+
printf(
60+
'Deleted row(s) count: %d' . PHP_EOL,
61+
$result->stats()['rowCountExact']
62+
);
6163
$transaction->commit();
6264
}
6365
// [END spanner_delete_dml_returning]

spanner/src/insert_dml_returning.php

+16-10
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,30 @@ function insert_dml_returning(string $instanceId, string $databaseId): void
3838
$instance = $spanner->instance($instanceId);
3939
$database = $instance->database($databaseId);
4040

41-
// DML returning sql insert query
41+
// Insert records into SINGERS table and returns the generated column
42+
// FullName of the inserted records using ‘THEN RETURN FullName’. It is also
43+
// possible to return all columns of all the inserted records by using
44+
// ‘THEN RETURN *’.
45+
4246
$sql = 'INSERT INTO Singers (SingerId, FirstName, LastName) '
43-
. "VALUES (12, 'Melissa', 'Garcia'), "
44-
. "(13, 'Russell', 'Morales'), "
45-
. "(14, 'Jacqueline', 'Long'), "
46-
. "(15, 'Dylan', 'Shaw') "
47-
. 'THEN RETURN *';
47+
. "VALUES (12, 'Melissa', 'Garcia'), "
48+
. "(13, 'Russell', 'Morales'), "
49+
. "(14, 'Jacqueline', 'Long'), "
50+
. "(15, 'Dylan', 'Shaw') "
51+
. 'THEN RETURN FullName';
4852

4953
$transaction = $database->transaction();
5054
$result = $transaction->execute($sql);
5155
foreach ($result->rows() as $row) {
5256
printf(
53-
'Row (%s, %s, %s) inserted' . PHP_EOL,
54-
$row['SingerId'],
55-
$row['FirstName'],
56-
$row['LastName']
57+
'%s inserted.' . PHP_EOL,
58+
$row['FullName'],
5759
);
5860
}
61+
printf(
62+
'Inserted row(s) count: %d' . PHP_EOL,
63+
$result->stats()['rowCountExact']
64+
);
5965
$transaction->commit();
6066
}
6167
// [END spanner_insert_dml_returning]

spanner/src/pg_create_database.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ function pg_create_database(string $instanceId, string $databaseId): void
6161
SingerId bigint NOT NULL PRIMARY KEY,
6262
FirstName varchar(1024),
6363
LastName varchar(1024),
64-
SingerInfo bytea
64+
SingerInfo bytea,
65+
FullName character varying(2048) GENERATED
66+
ALWAYS AS (FirstName || \' \' || LastName) STORED
6567
)';
6668

6769
$table2Query = 'CREATE TABLE Albums (

spanner/src/pg_delete_dml_returning.php

+13-11
Original file line numberDiff line numberDiff line change
@@ -40,24 +40,26 @@ function pg_delete_dml_returning(string $instanceId, string $databaseId): void
4040

4141
$transaction = $database->transaction();
4242

43-
// DML returning postgresql delete query
43+
// Delete records from SINGERS table satisfying a particular condition and
44+
// returns the SingerId and FullName column of the deleted records using
45+
// ‘RETURNING SingerId, FullName’. It is also possible to return all columns
46+
// of all the deleted records by using ‘RETURNING *’.
47+
4448
$result = $transaction->execute(
45-
'DELETE FROM singers WHERE firstname = $1 '
46-
. 'RETURNING *',
47-
[
48-
'parameters' => [
49-
'p1' => 'Melissa',
50-
]
51-
]
49+
"DELETE FROM Singers WHERE FirstName = 'Alice' "
50+
. 'RETURNING SingerId, FullName',
5251
);
5352
foreach ($result->rows() as $row) {
5453
printf(
55-
'Row (%s, %s, %s) deleted' . PHP_EOL,
54+
'%d %s.' . PHP_EOL,
5655
$row['singerid'],
57-
$row['firstname'],
58-
$row['lastname']
56+
$row['fullname']
5957
);
6058
}
59+
printf(
60+
'Deleted row(s) count: %d' . PHP_EOL,
61+
$result->stats()['rowCountExact']
62+
);
6163
$transaction->commit();
6264
}
6365
// [END spanner_postgresql_delete_dml_returning]

spanner/src/pg_insert_dml_returning.php

+17-11
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,30 @@ function pg_insert_dml_returning(string $instanceId, string $databaseId): void
3939
$instance = $spanner->instance($instanceId);
4040
$database = $instance->database($databaseId);
4141

42-
// DML returning postgresql insert query
43-
$sql = 'INSERT INTO singers (singerid, firstname, lastname) '
44-
. "VALUES (16, 'Melissa', 'Garcia'), "
45-
. "(17, 'Russell', 'Morales'), "
46-
. "(18, 'Jacqueline', 'Long'), "
47-
. "(19, 'Dylan', 'Shaw') "
48-
. 'RETURNING *';
42+
// Insert records into SINGERS table and returns the generated column
43+
// FullName of the inserted records using ‘RETURNING FullName’. It is also
44+
// possible to return all columns of all the inserted records by using
45+
// ‘RETURNING *’.
46+
47+
$sql = 'INSERT INTO Singers (Singerid, FirstName, LastName) '
48+
. "VALUES (12, 'Melissa', 'Garcia'), "
49+
. "(13, 'Russell', 'Morales'), "
50+
. "(14, 'Jacqueline', 'Long'), "
51+
. "(15, 'Dylan', 'Shaw') "
52+
. 'RETURNING FullName';
4953

5054
$transaction = $database->transaction();
5155
$result = $transaction->execute($sql);
5256
foreach ($result->rows() as $row) {
5357
printf(
54-
'Row (%s, %s, %s) inserted' . PHP_EOL,
55-
$row['singerid'],
56-
$row['firstname'],
57-
$row['lastname']
58+
'%s inserted.' . PHP_EOL,
59+
$row['fullname'],
5860
);
5961
}
62+
printf(
63+
'Inserted row(s) count: %d' . PHP_EOL,
64+
$result->stats()['rowCountExact']
65+
);
6066
$transaction->commit();
6167
}
6268
// [END spanner_postgresql_insert_dml_returning]

spanner/src/pg_update_dml_returning.php

+14-15
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,24 @@ function pg_update_dml_returning(string $instanceId, string $databaseId): void
4040

4141
$transaction = $database->transaction();
4242

43-
// DML returning postgresql update query
43+
// Update MarketingBudget column for records satisfying a particular
44+
// condition and returns the modified MarketingBudget column of the updated
45+
// records using ‘RETURNING MarketingBudget’. It is also possible to return
46+
// all columns of all the updated records by using ‘RETURNING *’.
47+
4448
$result = $transaction->execute(
45-
'UPDATE singers SET lastname = $1 WHERE singerid = $2 RETURNING *',
46-
[
47-
'parameters' => [
48-
'p1' => 'Missing',
49-
'p2' => 16,
50-
]
51-
]
49+
'UPDATE Albums '
50+
. 'SET MarketingBudget = MarketingBudget * 2 '
51+
. 'WHERE SingerId = 1 and AlbumId = 1'
52+
. 'RETURNING MarketingBudget'
5253
);
5354
foreach ($result->rows() as $row) {
54-
printf(
55-
'Row with singerid %s updated to (%s, %s, %s)' . PHP_EOL,
56-
$row['singerid'],
57-
$row['singerid'],
58-
$row['firstname'],
59-
$row['lastname']
60-
);
55+
printf('MarketingBudget: %s' . PHP_EOL, $row['marketingbudget']);
6156
}
57+
printf(
58+
'Updated row(s) count: %d' . PHP_EOL,
59+
$result->stats()['rowCountExact']
60+
);
6261
$transaction->commit();
6362
}
6463
// [END spanner_postgresql_update_dml_returning]

spanner/src/update_dml_returning.php

+14-16
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,24 @@ function update_dml_returning(string $instanceId, string $databaseId): void
4040

4141
$transaction = $database->transaction();
4242

43-
// DML returning sql update query
43+
// Update MarketingBudget column for records satisfying a particular
44+
// condition and returns the modified MarketingBudget column of the updated
45+
// records using ‘THEN RETURN MarketingBudget’. It is also possible to return
46+
// all columns of all the updated records by using ‘THEN RETURN *’.
47+
4448
$result = $transaction->execute(
45-
'UPDATE Singers SET LastName = @lastName '
46-
. 'WHERE SingerId = @singerId THEN RETURN *',
47-
[
48-
'parameters' => [
49-
'lastName' => 'Missing',
50-
'singerId' => 12,
51-
]
52-
]
49+
'UPDATE Albums '
50+
. 'SET MarketingBudget = MarketingBudget * 2 '
51+
. 'WHERE SingerId = 1 and AlbumId = 1 '
52+
. 'THEN RETURN MarketingBudget'
5353
);
5454
foreach ($result->rows() as $row) {
55-
printf(
56-
'Row with SingerId %s updated to (%s, %s, %s)' . PHP_EOL,
57-
$row['SingerId'],
58-
$row['SingerId'],
59-
$row['FirstName'],
60-
$row['LastName']
61-
);
55+
printf('MarketingBudget: %s' . PHP_EOL, $row['MarketingBudget']);
6256
}
57+
printf(
58+
'Updated row(s) count: %d' . PHP_EOL,
59+
$result->stats()['rowCountExact']
60+
);
6361
$transaction->commit();
6462
}
6563
// [END spanner_update_dml_returning]

spanner/test/spannerPgTest.php

+60-20
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ public function testCreateDatabase()
6868
{
6969
$output = $this->runFunctionSnippet('pg_create_database');
7070
self::$lastUpdateDataTimestamp = time();
71-
$expected = sprintf('Created database %s with dialect POSTGRESQL on instance %s',
72-
self::$databaseId, self::$instanceId);
71+
$expected = sprintf(
72+
'Created database %s with dialect POSTGRESQL on instance %s',
73+
self::$databaseId,
74+
self::$instanceId
75+
);
7376

7477
$this->assertStringContainsString($expected, $output);
7578
}
@@ -111,8 +114,12 @@ public function testCreateTableCaseSensitivity()
111114
self::$instanceId, self::$databaseId, $tableName
112115
]);
113116
self::$lastUpdateDataTimestamp = time();
114-
$expected = sprintf('Created %s table in database %s on instance %s',
115-
$tableName, self::$databaseId, self::$instanceId);
117+
$expected = sprintf(
118+
'Created %s table in database %s on instance %s',
119+
$tableName,
120+
self::$databaseId,
121+
self::$instanceId
122+
);
116123

117124
$this->assertStringContainsString($expected, $output);
118125
}
@@ -181,8 +188,9 @@ public function testPartitionedDml()
181188
$op->pollUntilComplete();
182189

183190
$db->runTransaction(function (Transaction $t) {
184-
$t->executeUpdate('INSERT INTO users (id, name, active)'
185-
. ' VALUES ($1, $2, $3), ($4, $5, $6)',
191+
$t->executeUpdate(
192+
'INSERT INTO users (id, name, active)'
193+
. ' VALUES ($1, $2, $3), ($4, $5, $6)',
186194
[
187195
'parameters' => [
188196
'p1' => 1,
@@ -192,7 +200,8 @@ public function testPartitionedDml()
192200
'p5' => 'Bruce',
193201
'p6' => false,
194202
]
195-
]);
203+
]
204+
);
196205
$t->commit();
197206
});
198207

@@ -370,40 +379,71 @@ public function testDmlReturningInsert()
370379
{
371380
$output = $this->runFunctionSnippet('pg_insert_dml_returning');
372381

373-
$expectedOutput = sprintf('Row (16, Melissa, Garcia) inserted');
382+
$expectedOutput = sprintf('Melissa Garcia inserted');
374383
$this->assertStringContainsString($expectedOutput, $output);
375384

376-
$expectedOutput = sprintf('Row (17, Russell, Morales) inserted');
377-
$this->assertStringContainsString('Russell', $output);
385+
$expectedOutput = sprintf('Russell Morales inserted');
386+
$this->assertStringContainsString($expectedOutput, $output);
378387

379-
$expectedOutput = sprintf('Row (18, Jacqueline, Long) inserted');
380-
$this->assertStringContainsString('Jacqueline', $output);
388+
$expectedOutput = sprintf('Jacqueline Long inserted');
389+
$this->assertStringContainsString($expectedOutput, $output);
390+
391+
$expectedOutput = sprintf('Dylan Shaw inserted');
392+
$this->assertStringContainsString($expectedOutput, $output);
381393

382-
$expectedOutput = sprintf('Row (19, Dylan, Shaw) inserted');
383-
$this->assertStringContainsString('Dylan', $output);
394+
$expectedOutput = sprintf('Inserted row(s) count: 4');
395+
$this->assertStringContainsString($expectedOutput, $output);
384396
}
385397

386398
/**
387-
* @depends testDmlReturningInsert
399+
* @depends testDmlWithParams
388400
*/
389401
public function testDmlReturningUpdate()
390402
{
403+
$db = self::$instance->database(self::$databaseId);
404+
$db->runTransaction(function (Transaction $t) {
405+
$t->update('Albums', [
406+
'albumid' => 1,
407+
'singerid' => 1,
408+
'marketingbudget' => 1000
409+
]);
410+
$t->commit();
411+
});
412+
391413
$output = $this->runFunctionSnippet('pg_update_dml_returning');
392414

393-
$expectedOutput = sprintf(
394-
'Row with singerid 16 updated to (16, Melissa, Missing)'
395-
);
415+
$expectedOutput = sprintf('MarketingBudget: 2000');
416+
$this->assertStringContainsString($expectedOutput, $output);
417+
418+
$expectedOutput = sprintf('Updated row(s) count: 1');
396419
$this->assertStringContainsString($expectedOutput, $output);
397420
}
398421

399422
/**
400-
* @depends testDmlReturningUpdate
423+
* @depends testDmlWithParams
401424
*/
402425
public function testDmlReturningDelete()
403426
{
427+
$db = self::$instance->database(self::$databaseId);
428+
429+
// Deleting the foreign key dependent entry in the Albums table
430+
// before deleting the required row(row which has firstName = Alice)
431+
// in the sample.
432+
$db->runTransaction(function (Transaction $t) {
433+
$spanner = new SpannerClient(['projectId' => self::$projectId]);
434+
$keySet = $spanner->keySet([
435+
'keys' => [[1, 1]]
436+
]);
437+
$t->delete('Albums', $keySet);
438+
$t->commit();
439+
});
440+
404441
$output = $this->runFunctionSnippet('pg_delete_dml_returning');
405442

406-
$expectedOutput = sprintf('Row (16, Melissa, Missing) deleted');
443+
$expectedOutput = sprintf('1 Alice Henderson');
444+
$this->assertStringContainsString($expectedOutput, $output);
445+
446+
$expectedOutput = sprintf('Deleted row(s) count: 1');
407447
$this->assertStringContainsString($expectedOutput, $output);
408448
}
409449

0 commit comments

Comments
 (0)