Skip to content

Commit

Permalink
Use IN() / NOT IN() when possible
Browse files Browse the repository at this point in the history
resolves  #2937
  • Loading branch information
brandonkelly committed Jun 2, 2018
1 parent 1e132be commit 0d7b726
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- `craft\helpers\StringHelper::asciiCharMap()` now has `$flat` and `$language` arguments.
- Craft no longer saves new versions of entries when absolutely nothing changed about them in the save request. ([#2923](https://github.com/craftcms/cms/issues/2923))
- `minVersionRequired` is no longer enforced on a plugin when updating it if was coming from a `dev-` branch.
- Improved the performance of element queries when a lot of values were passed into a param, such as `id`, by using `IN()` and `NOT IN()` conditions when possible. ([#2937](https://github.com/craftcms/cms/pull/2937))

### Deprecated
- Deprecated the `customAsciiCharMappings` config setting. (Any corrections to ASCII char mappings should be submitted to [Stringy](https://github.com/danielstjules/Stringy).)
Expand Down
23 changes: 23 additions & 0 deletions src/helpers/Db.php
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,9 @@ public static function parseParam(string $column, $value, string $defaultOperato
$condition = [$glue];
$isMysql = Craft::$app->getDb()->getIsMysql();

$inVals = [];
$notInVals = [];

foreach ($value as $val) {
self::_normalizeEmptyValue($val);
$operator = self::_parseParamOperator($val, $defaultOperator);
Expand Down Expand Up @@ -522,9 +525,29 @@ public static function parseParam(string $column, $value, string $defaultOperato
}
}

// ['or', 1, 2, 3] => IN (1, 2, 3)
if ($glue == 'or' && $operator === '=') {
$inVals[] = $val;
continue;
}

// ['and', '!=1', '!=2', '!=3'] => NOT IN (1, 2, 3)
if ($glue == 'and' && $operator === '!=') {
$notInVals[] = $val;
continue;
}

$condition[] = [$operator, $column, $val];
}

if (!empty($inVals)) {
$condition[] = ['in', $column, $inVals];
}

if (!empty($notInVals)) {
$condition[] = ['not in', $column, $notInVals];
}

return $condition;
}

Expand Down

0 comments on commit 0d7b726

Please # to comment.