Skip to content

Commit 3121900

Browse files
norbedg
authored andcommitted
SqlBuilder: Fixed condition with Selection as one of more argument (#200)
1 parent f7ce519 commit 3121900

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

src/Database/Table/SqlBuilder.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,8 @@ protected function addCondition($condition, array $params, array &$conditions, a
317317

318318
$replace = null;
319319
$placeholderNum = 0;
320-
foreach ($params as $arg) {
320+
while (count($params)) {
321+
$arg = array_shift($params);
321322
preg_match('#(?:.*?\?.*?){' . $placeholderNum . '}(((?:&|\||^|~|\+|-|\*|/|%|\(|,|<|>|=|(?<=\W|^)(?:REGEXP|ALL|AND|ANY|BETWEEN|EXISTS|IN|[IR]?LIKE|OR|NOT|SOME|INTERVAL))\s*)?(?:\(\?\)|\?))#s', $condition, $match, PREG_OFFSET_CAPTURE);
322323
$hasOperator = ($match[1][0] === '?' && $match[1][1] === 0) ? true : !empty($match[2][0]);
323324

@@ -353,8 +354,11 @@ protected function addCondition($condition, array $params, array &$conditions, a
353354

354355
if ($this->driver->isSupported(ISupplementalDriver::SUPPORT_SUBSELECT)) {
355356
$arg = null;
356-
$replace = $match[2][0] . '(' . $clone->getSql() . ')';
357-
$conditionsParameters = array_merge($conditionsParameters, $clone->getSqlBuilder()->getParameters());
357+
$subSelectPlaceholderCount = substr_count($clone->getSql(), '?');
358+
$replace = $match[2][0] . '(' . $clone->getSql() . (!$subSelectPlaceholderCount && count($clone->getSqlBuilder()->getParameters()) === 1 ? ' ?' : '') . ')';
359+
if (count($clone->getSqlBuilder()->getParameters())) {
360+
array_unshift($params, ...$clone->getSqlBuilder()->getParameters());
361+
}
358362
} else {
359363
$arg = [];
360364
foreach ($clone as $row) {

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ test(function () use ($context) { // test more Selection as a parameter
5656
});
5757

5858

59+
test(function () use ($context) { // test more Selection as one of more argument
60+
$sqlBuilder = new SqlBuilder('book', $context);
61+
$sqlBuilder->addWhere('id ? AND id ?', $context->table('book')->where('id', 2), $context->table('book_tag')->select('book_id'));
62+
Assert::equal(reformat([
63+
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?) AND `id` IN (?))',
64+
'SELECT * FROM [book] WHERE ([id] IN (SELECT [id] FROM [book] WHERE ([id] = ?)) AND [id] IN (SELECT [book_id] FROM [book_tag]))',
65+
]), $sqlBuilder->buildSelectQuery());
66+
});
67+
68+
5969
test(function () use ($context) { // test more ActiveRow as a parameter
6070
$sqlBuilder = new SqlBuilder('book', $context);
6171
$books = $context->table('book')->where('id', [1, 2])->fetchPairs('id');
@@ -73,7 +83,7 @@ test(function () use ($context) { // test Selection with parameters as a paramet
7383
$schemaSupported = $context->getConnection()->getSupplementalDriver()->isSupported(ISupplementalDriver::SUPPORT_SCHEMA);
7484
Assert::equal(reformat([
7585
'mysql' => 'SELECT * FROM `book` WHERE (`id` IN (?))',
76-
'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]) >))',
86+
'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]) > ?))',
7787
]), $sqlBuilder->buildSelectQuery());
7888
Assert::count(1, $sqlBuilder->getParameters());
7989
});

0 commit comments

Comments
 (0)