diff --git a/core/lib/Drupal/Core/Config/Entity/Query/Condition.php b/core/lib/Drupal/Core/Config/Entity/Query/Condition.php index 6764d01ea6eab259f60fadd0bbaf3d8c97a4e891..23971eafc28f025c45516ef5a48b0c260c62c82d 100644 --- a/core/lib/Drupal/Core/Config/Entity/Query/Condition.php +++ b/core/lib/Drupal/Core/Config/Entity/Query/Condition.php @@ -154,6 +154,13 @@ protected function matchArray(array $condition, array $data, array $needs_matchi * TRUE when matches else FALSE. */ protected function match(array $condition, $value) { + // "IS NULL" and "IS NOT NULL" conditions can also deal with array values, + // so we return early for them to avoid problems. + if (in_array($condition['operator'], ['IS NULL', 'IS NOT NULL'], TRUE)) { + $should_be_set = $condition['operator'] === 'IS NOT NULL'; + return $should_be_set === isset($value); + } + if (isset($value)) { // We always want a case-insensitive match. if (!is_bool($value)) { @@ -183,15 +190,11 @@ protected function match(array $condition, $value) { return strpos($value, $condition['value']) !== FALSE; case 'ENDS_WITH': return substr($value, -strlen($condition['value'])) === (string) $condition['value']; - case 'IS NOT NULL': - return TRUE; - case 'IS NULL': - return FALSE; default: throw new QueryException('Invalid condition operator.'); } } - return $condition['operator'] === 'IS NULL'; + return FALSE; } } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityQueryTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityQueryTest.php index 87ba10480ff7f038a8bda6bee43a6fb8c7dec8ad..56050a7dc40d18307e95e5a42d205814ed87fa71 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityQueryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityQueryTest.php @@ -572,6 +572,33 @@ public function testDotted() { ->condition('*.level1.level2', 41) ->execute(); $this->assertResults([]); + // Make sure that "IS NULL" and "IS NOT NULL" work correctly with + // array-valued fields/keys. + $all = ['1', '2', '3', '4', '5']; + $this->queryResults = $this->factory->get('config_query_test') + ->exists('array.level1.level2') + ->execute(); + $this->assertResults($all); + $this->queryResults = $this->factory->get('config_query_test') + ->exists('array.level1') + ->execute(); + $this->assertResults($all); + $this->queryResults = $this->factory->get('config_query_test') + ->exists('array') + ->execute(); + $this->assertResults($all); + $this->queryResults = $this->factory->get('config_query_test') + ->notExists('array.level1.level2') + ->execute(); + $this->assertResults([]); + $this->queryResults = $this->factory->get('config_query_test') + ->notExists('array.level1') + ->execute(); + $this->assertResults([]); + $this->queryResults = $this->factory->get('config_query_test') + ->notExists('array') + ->execute(); + $this->assertResults([]); } /**