Skip to content

Commit

Permalink
MySqlDriver driver uses subqueries (#265)
Browse files Browse the repository at this point in the history
  • Loading branch information
smuuf authored and dg committed Oct 30, 2020
1 parent 8d2b91d commit fd0d57c
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 14 deletions.
14 changes: 10 additions & 4 deletions src/Database/Drivers/MySqlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class MySqlDriver implements Nette\Database\ISupplementalDriver
/** @var Nette\Database\Connection */
private $connection;

/** @var string */
private $version;


/**
* Driver options:
Expand All @@ -36,8 +39,8 @@ class MySqlDriver implements Nette\Database\ISupplementalDriver
public function initialize(Nette\Database\Connection $connection, array $options): void
{
$this->connection = $connection;
$charset = $options['charset']
?? (version_compare($connection->getPdo()->getAttribute(\PDO::ATTR_SERVER_VERSION), '5.5.3', '>=') ? 'utf8mb4' : 'utf8');
$this->version = $connection->getPdo()->getAttribute(\PDO::ATTR_SERVER_VERSION);
$charset = $options['charset'] ?? (version_compare($this->version, '5.5.3', '>=') ? 'utf8mb4' : 'utf8');
if ($charset) {
$connection->query('SET NAMES ?', $charset);
}
Expand Down Expand Up @@ -203,7 +206,10 @@ public function isSupported(string $item): bool
// MULTI_COLUMN_AS_OR_COND due to mysql bugs:
// - http://bugs.mysql.com/bug.php?id=31188
// - http://bugs.mysql.com/bug.php?id=35819
// and more.
return $item === self::SUPPORT_SELECT_UNGROUPED_COLUMNS || $item === self::SUPPORT_MULTI_COLUMN_AS_OR_COND;
// SUPPORT_SUBSELECT is slow before 5.7
// - http://mysqlserverteam.com/derived-tables-in-mysql-5-7/
return $item === self::SUPPORT_SELECT_UNGROUPED_COLUMNS
|| $item === self::SUPPORT_MULTI_COLUMN_AS_OR_COND
|| ($item === self::SUPPORT_SUBSELECT && version_compare($this->version, '5.7', '>='));
}
}
11 changes: 1 addition & 10 deletions tests/Database/Table/SqlBuilder.addWhere().phpt
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ test('?name', function () use ($context) {
test('test Selection as a parameter', function () use ($context) {
$sqlBuilder = new SqlBuilder('book', $context);
$sqlBuilder->addWhere('id', $context->table('book'));
Assert::equal(reformat([
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?))',
'SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book]))',
]), $sqlBuilder->buildSelectQuery());
Assert::equal(reformat(['SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book]))']), $sqlBuilder->buildSelectQuery());
});


Expand All @@ -50,7 +47,6 @@ test('test more Selection as a parameter', function () use ($context) {
$sqlBuilder->addWhere('id', $context->table('book'));
$sqlBuilder->addWhere('id', $context->table('book_tag')->select('book_id'));
Assert::equal(reformat([
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?)) AND (`id` IN (?))',
'SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book])) AND ([id] IN (SELECT [book_id] FROM [book_tag]))',
]), $sqlBuilder->buildSelectQuery());
});
Expand All @@ -60,7 +56,6 @@ test('test more Selection as one of more argument', function () use ($context) {
$sqlBuilder = new SqlBuilder('book', $context);
$sqlBuilder->addWhere('id ? AND id ?', $context->table('book')->where('id', 2), $context->table('book_tag')->select('book_id'));
Assert::equal(reformat([
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?) AND `id` IN (?))',
'SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book] WHERE ([id] = ?)) AND [id] IN (SELECT [book_id] FROM [book_tag]))',
]), $sqlBuilder->buildSelectQuery());
});
Expand All @@ -82,7 +77,6 @@ test('test Selection with parameters as a parameter', function () use ($context)
$sqlBuilder->addWhere('id', $context->table('book')->having('COUNT(:book_tag.tag_id) >', 1));
$schemaSupported = $context->getConnection()->getSupplementalDriver()->isSupported(ISupplementalDriver::SUPPORT_SCHEMA);
Assert::equal(reformat([
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?))',
'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]) > ?))',
]), $sqlBuilder->buildSelectQuery());
Assert::count(1, $sqlBuilder->getParameters());
Expand All @@ -93,7 +87,6 @@ test('test Selection with column as a parameter', function () use ($context) {
$sqlBuilder = new SqlBuilder('book', $context);
$sqlBuilder->addWhere('id', $context->table('book')->select('id'));
Assert::equal(reformat([
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?))',
'SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book]))',
]), $sqlBuilder->buildSelectQuery());
});
Expand All @@ -103,7 +96,6 @@ test('test multiple placeholder parameter', function () use ($context) {
$sqlBuilder = new SqlBuilder('book', $context);
$sqlBuilder->addWhere('id ? OR id ?', null, $context->table('book'));
Assert::equal(reformat([
'mysql' => 'SELECT * FROM `book` WHERE (`id` IS NULL OR `id` IN (?))',
'SELECT * FROM [book] WHERE ([id] IS NULL OR [id] IN (SELECT [id] FROM [book]))',
]), $sqlBuilder->buildSelectQuery());
});
Expand Down Expand Up @@ -176,7 +168,6 @@ test('tests NOT', function () use ($context) {
$sqlBuilder->addWhere('id NOT', null);
$sqlBuilder->addWhere('id NOT', $context->table('book')->select('id'));
Assert::equal(reformat([
'mysql' => 'SELECT * FROM `book` WHERE (`id` NOT IN (?)) AND (`id` IS NOT NULL) AND (`id` NOT IN (?))',
'SELECT * FROM [book] WHERE ([id] NOT IN (?)) AND ([id] IS NOT NULL) AND ([id] NOT IN (SELECT [id] FROM [book]))',
]), $sqlBuilder->buildSelectQuery());
});
Expand Down

0 comments on commit fd0d57c

Please sign in to comment.