Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 52d72e1

Browse files
smuufdg
authored andcommittedOct 29, 2020
MySqlDriver driver uses subqueries (#265)
1 parent 698037e commit 52d72e1

File tree

2 files changed

+11
-14
lines changed

2 files changed

+11
-14
lines changed
 

‎src/Database/Drivers/MySqlDriver.php

+10-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ class MySqlDriver implements Nette\Database\ISupplementalDriver
2727
/** @var Nette\Database\Connection */
2828
private $connection;
2929

30+
/** @var string */
31+
private $version;
32+
3033

3134
/**
3235
* Driver options:
@@ -36,8 +39,8 @@ class MySqlDriver implements Nette\Database\ISupplementalDriver
3639
public function initialize(Nette\Database\Connection $connection, array $options): void
3740
{
3841
$this->connection = $connection;
39-
$charset = $options['charset']
40-
?? (version_compare($connection->getPdo()->getAttribute(\PDO::ATTR_SERVER_VERSION), '5.5.3', '>=') ? 'utf8mb4' : 'utf8');
42+
$this->version = $connection->getPdo()->getAttribute(\PDO::ATTR_SERVER_VERSION);
43+
$charset = $options['charset'] ?? (version_compare($this->version, '5.5.3', '>=') ? 'utf8mb4' : 'utf8');
4144
if ($charset) {
4245
$connection->query('SET NAMES ?', $charset);
4346
}
@@ -203,7 +206,10 @@ public function isSupported(string $item): bool
203206
// MULTI_COLUMN_AS_OR_COND due to mysql bugs:
204207
// - http://bugs.mysql.com/bug.php?id=31188
205208
// - http://bugs.mysql.com/bug.php?id=35819
206-
// and more.
207-
return $item === self::SUPPORT_SELECT_UNGROUPED_COLUMNS || $item === self::SUPPORT_MULTI_COLUMN_AS_OR_COND;
209+
// SUPPORT_SUBSELECT is slow before 5.7
210+
// - http://mysqlserverteam.com/derived-tables-in-mysql-5-7/
211+
return $item === self::SUPPORT_SELECT_UNGROUPED_COLUMNS
212+
|| $item === self::SUPPORT_MULTI_COLUMN_AS_OR_COND
213+
|| ($item === self::SUPPORT_SUBSELECT && version_compare($this->version, '5.7', '>='));
208214
}
209215
}

‎tests/Database/Table/SqlBuilder.addWhere().phpt

+1-10
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ test('?name', function () use ($context) {
3838
test('test Selection as a parameter', function () use ($context) {
3939
$sqlBuilder = new SqlBuilder('book', $context);
4040
$sqlBuilder->addWhere('id', $context->table('book'));
41-
Assert::equal(reformat([
42-
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?))',
43-
'SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book]))',
44-
]), $sqlBuilder->buildSelectQuery());
41+
Assert::equal(reformat(['SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book]))']), $sqlBuilder->buildSelectQuery());
4542
});
4643

4744

@@ -50,7 +47,6 @@ test('test more Selection as a parameter', function () use ($context) {
5047
$sqlBuilder->addWhere('id', $context->table('book'));
5148
$sqlBuilder->addWhere('id', $context->table('book_tag')->select('book_id'));
5249
Assert::equal(reformat([
53-
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?)) AND (`id` IN (?))',
5450
'SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book])) AND ([id] IN (SELECT [book_id] FROM [book_tag]))',
5551
]), $sqlBuilder->buildSelectQuery());
5652
});
@@ -60,7 +56,6 @@ test('test more Selection as one of more argument', function () use ($context) {
6056
$sqlBuilder = new SqlBuilder('book', $context);
6157
$sqlBuilder->addWhere('id ? AND id ?', $context->table('book')->where('id', 2), $context->table('book_tag')->select('book_id'));
6258
Assert::equal(reformat([
63-
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?) AND `id` IN (?))',
6459
'SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book] WHERE ([id] = ?)) AND [id] IN (SELECT [book_id] FROM [book_tag]))',
6560
]), $sqlBuilder->buildSelectQuery());
6661
});
@@ -82,7 +77,6 @@ test('test Selection with parameters as a parameter', function () use ($context)
8277
$sqlBuilder->addWhere('id', $context->table('book')->having('COUNT(:book_tag.tag_id) >', 1));
8378
$schemaSupported = $context->getConnection()->getSupplementalDriver()->isSupported(ISupplementalDriver::SUPPORT_SCHEMA);
8479
Assert::equal(reformat([
85-
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?))',
8680
'SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book] LEFT JOIN ' . ($schemaSupported ? '[public].[book_tag] ' : '') . '[book_tag] ON [book].[id] = [book_tag].[book_id] HAVING COUNT([book_tag].[tag_id]) > ?))',
8781
]), $sqlBuilder->buildSelectQuery());
8882
Assert::count(1, $sqlBuilder->getParameters());
@@ -93,7 +87,6 @@ test('test Selection with column as a parameter', function () use ($context) {
9387
$sqlBuilder = new SqlBuilder('book', $context);
9488
$sqlBuilder->addWhere('id', $context->table('book')->select('id'));
9589
Assert::equal(reformat([
96-
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?))',
9790
'SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book]))',
9891
]), $sqlBuilder->buildSelectQuery());
9992
});
@@ -103,7 +96,6 @@ test('test multiple placeholder parameter', function () use ($context) {
10396
$sqlBuilder = new SqlBuilder('book', $context);
10497
$sqlBuilder->addWhere('id ? OR id ?', null, $context->table('book'));
10598
Assert::equal(reformat([
106-
'mysql' => 'SELECT * FROM `book` WHERE (`id` IS NULL OR `id` IN (?))',
10799
'SELECT * FROM [book] WHERE ([id] IS NULL OR [id] IN (SELECT [id] FROM [book]))',
108100
]), $sqlBuilder->buildSelectQuery());
109101
});
@@ -176,7 +168,6 @@ test('tests NOT', function () use ($context) {
176168
$sqlBuilder->addWhere('id NOT', null);
177169
$sqlBuilder->addWhere('id NOT', $context->table('book')->select('id'));
178170
Assert::equal(reformat([
179-
'mysql' => 'SELECT * FROM `book` WHERE (`id` NOT IN (?)) AND (`id` IS NOT NULL) AND (`id` NOT IN (?))',
180171
'SELECT * FROM [book] WHERE ([id] NOT IN (?)) AND ([id] IS NOT NULL) AND ([id] NOT IN (SELECT [id] FROM [book]))',
181172
]), $sqlBuilder->buildSelectQuery());
182173
});

0 commit comments

Comments
 (0)
Please sign in to comment.