Skip to content

Commit

Permalink
Add compatibility layer to SQL scan queries
Browse files Browse the repository at this point in the history
Scanning SQL queries will be forbidden in Tarantool 3.0 by default [1].
To use them, `SEQSCAN` keyword must be specified before space name. One
may also set `compat.sql_seq_scan_default` to `"old"`, but implicit
scanning will be forbidden in future versions nonetheless.

1. tarantool/tarantool@7764882
  • Loading branch information
DifferentialOrange authored and rybakit committed Jun 8, 2023
1 parent 31f9880 commit 6ae236b
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 7 deletions.
10 changes: 9 additions & 1 deletion examples/protocol/execute.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@
[':email2' => 'bar@example.com']
);

$result3 = $client->executeQuery('SELECT * FROM users WHERE "email" = ?', 'foo@example.com');
/**
* SEQSCAN keyword is explicitly allowing to use seqscan:
* https://github.com/tarantool/tarantool/commit/77648827326ad268ec0ffbcd620c2371b65ef2b4
* It was introduced in Tarantool 2.11.0-rc1. If compat.sql_seq_scan_default set to "new"
* (default value since 3.0), query returns error when trying to scan without keyword.
*/
$seqScan = server_version_at_least('2.11.0-rc1', $client) ? 'SEQSCAN' : '';
$result3 = $client->executeQuery("SELECT * FROM $seqScan users WHERE \"email\" = ?", 'foo@example.com');

$result4 = $client->executeQuery('SELECT * FROM users WHERE "id" IN (?, ?)', 1, 2);

printf("Result 1: %s\n", json_encode([$result1->count(), $result1->getAutoincrementIds()]));
Expand Down
9 changes: 8 additions & 1 deletion examples/protocol/prepare.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@
}
$stmt->close();

$result = $client->executeQuery('SELECT COUNT("id") AS "cnt" FROM users');
/**
* SEQSCAN keyword is explicitly allowing to use seqscan:
* https://github.com/tarantool/tarantool/commit/77648827326ad268ec0ffbcd620c2371b65ef2b4
* It was introduced in Tarantool 2.11.0-rc1. If compat.sql_seq_scan_default set to "new"
* (default value since 3.0), query returns error when trying to scan without keyword.
*/
$seqScan = server_version_at_least('2.11.0-rc1', $client) ? 'SEQSCAN' : '';
$result = $client->executeQuery("SELECT COUNT(\"id\") AS \"cnt\" FROM $seqScan users");

printf("Result: %s\n", json_encode($result[0]));

Expand Down
24 changes: 20 additions & 4 deletions tests/Integration/Requests/ExecuteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@
*/
final class ExecuteTest extends TestCase
{
private function provideSeqScan() : string
{
/**
* SEQSCAN keyword is explicitly allowing to use seqscan:
* https://github.com/tarantool/tarantool/commit/77648827326ad268ec0ffbcd620c2371b65ef2b4
* It was introduced in Tarantool 2.11.0-rc1. If compat.sql_seq_scan_default set to "new"
* (default value since 3.0), query returns error when trying to scan without keyword.
*/
return $this->tarantoolVersionSatisfies('>=2.11.0-rc1') ? 'SEQSCAN' : '';
}

/**
* @sql DROP TABLE IF EXISTS exec_update
* @sql CREATE TABLE exec_update (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(50))
Expand All @@ -47,7 +58,8 @@ public function testExecuteInsertsRows() : void

public function testExecuteFetchesAllRows() : void
{
$response = $this->client->execute('SELECT * FROM exec_query');
$seqScan = self::provideSeqScan();
$response = $this->client->execute("SELECT * FROM $seqScan exec_query");

self::assertSame([[1, 'A'], [2, 'B']], $response->getBodyField(Keys::DATA));
}
Expand Down Expand Up @@ -94,7 +106,8 @@ public function testExecuteUpdateUpdatesRow() : void

public function testExecuteQueryFetchesAllRows() : void
{
$result = $this->client->executeQuery('SELECT * FROM exec_query');
$seqScan = self::provideSeqScan();
$result = $this->client->executeQuery("SELECT * FROM $seqScan exec_query");

self::assertSame([[1, 'A'], [2, 'B']], $result->getData());
self::assertSame(2, $result->count());
Expand Down Expand Up @@ -155,7 +168,8 @@ public function testSqlQueryResultHoldsMetadata() : void
{
$client = ClientBuilder::createFromEnv()->build();

$response = $client->executeQuery('SELECT * FROM exec_query');
$seqScan = self::provideSeqScan();
$response = $client->executeQuery("SELECT * FROM $seqScan exec_query");

self::assertSame([[
Keys::METADATA_FIELD_NAME => 'ID',
Expand All @@ -178,7 +192,9 @@ public function testSqlQueryResultHoldsExtendedMetadata() : void
$client->execute('SET SESSION "sql_full_metadata" = true');

$tableName = $this->resolvePlaceholders('%target_method%');
$response = $client->executeQuery("SELECT id, name as full_name FROM $tableName");

$seqScan = self::provideSeqScan();
$response = $client->executeQuery("SELECT id, name as full_name FROM $seqScan $tableName");

self::assertSame([[
Keys::METADATA_FIELD_NAME => 'ID',
Expand Down
14 changes: 13 additions & 1 deletion tests/Integration/Requests/PrepareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@
*/
final class PrepareTest extends TestCase
{
private function provideSeqScan() : string
{
/**
* SEQSCAN keyword is explicitly allowing to use seqscan:
* https://github.com/tarantool/tarantool/commit/77648827326ad268ec0ffbcd620c2371b65ef2b4
* It was introduced in Tarantool 2.11.0-rc1. If compat.sql_seq_scan_default set to "new"
* (default value since 3.0), query returns error when trying to scan without keyword.
*/
return $this->tarantoolVersionSatisfies('>=2.11.0-rc1') ? 'SEQSCAN' : '';
}

public function testPreparePreparesSqlStatement() : void
{
[$preparedCountBefore] = $this->client->evaluate('return box.info.sql().cache.stmt_count');
Expand Down Expand Up @@ -73,7 +84,8 @@ public function testExecuteUpdateUpdatesRows() : void
$insertResult1 = $stmt->executeUpdate(1, 'foo');
$insertResult2 = $stmt->executeUpdate([':name' => 'bar'], [':id' => 2]);

$selectResult = $this->client->executeQuery('SELECT * FROM prepare_execute ORDER BY id');
$seqScan = self::provideSeqScan();
$selectResult = $this->client->executeQuery("SELECT * FROM $seqScan prepare_execute ORDER BY id");

try {
self::assertSame(1, $insertResult1->count());
Expand Down

0 comments on commit 6ae236b

Please sign in to comment.