diff --git a/core/core.services.yml b/core/core.services.yml index e2939e9..a8fe133 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -763,6 +763,9 @@ services: arguments: ['@database'] tags: - { name: backend_overridable } + pgsql.entity.query.sql: + class: Drupal\Core\Entity\Query\Sql\pgsql\QueryFactory + arguments: ['@database'] entity.query.null: class: Drupal\Core\Entity\Query\Null\QueryFactory entity.query.keyvalue: diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/EntityQuery/Condition.php b/core/lib/Drupal/Core/Database/Driver/mysql/EntityQuery/Condition.php deleted file mode 100644 index 9f58021..0000000 --- a/core/lib/Drupal/Core/Database/Driver/mysql/EntityQuery/Condition.php +++ /dev/null @@ -1,22 +0,0 @@ -escapeField($condition['real_field']) . ') ' . $condition['operator'] . ' ('; - $condition['where_args'] = []; - - $n = 1; - // Only use the array values in case an associative array is passed as an - // argument following similar pattern in - // \Drupal\Core\Database\Connection::expandArguments(). - foreach ($condition['value'] as $value) { - $condition['where'] .= 'LOWER(:value' . $n . '),'; - $condition['where_args'][':value' . $n] = $value; - $n++; - } - $condition['where'] = trim($condition['where'], ','); - $condition['where'] .= ')'; - } - } - -} diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/EntityQuery/Condition.php b/core/lib/Drupal/Core/Database/Driver/sqlite/EntityQuery/Condition.php deleted file mode 100644 index e59eb05..0000000 --- a/core/lib/Drupal/Core/Database/Driver/sqlite/EntityQuery/Condition.php +++ /dev/null @@ -1,22 +0,0 @@ -connection->escapeField($string); + } + + /** + * {@inheritdoc} + */ public function getArguments(PlaceholderInterface $queryPlaceholder = NULL) { if (!isset($queryPlaceholder)) { $queryPlaceholder = $this; diff --git a/core/lib/Drupal/Core/Database/Query/SelectExtender.php b/core/lib/Drupal/Core/Database/Query/SelectExtender.php index f85aac4..cca68c7 100644 --- a/core/lib/Drupal/Core/Database/Query/SelectExtender.php +++ b/core/lib/Drupal/Core/Database/Query/SelectExtender.php @@ -210,6 +210,14 @@ public function escapeLike($string) { return $this->query->escapeLike($string); } + /** + * {@inheritdoc} + */ + public function escapeField($string) { + $this->query->escapeField($string); + return $this; + } + public function getArguments(PlaceholderInterface $queryPlaceholder = NULL) { return $this->query->getArguments($queryPlaceholder); } diff --git a/core/lib/Drupal/Core/Database/Query/SelectInterface.php b/core/lib/Drupal/Core/Database/Query/SelectInterface.php index bfb7db6..6b87014 100644 --- a/core/lib/Drupal/Core/Database/Query/SelectInterface.php +++ b/core/lib/Drupal/Core/Database/Query/SelectInterface.php @@ -141,6 +141,18 @@ public function &getUnion(); public function escapeLike($string); /** + * Escapes a field name string. + * + * Force all field names to be strictly alphanumeric-plus-underscore. + * For some database drivers, it may also wrap the field name in + * database-specific escape characters. + * + * @return + * The sanitized field name string. + */ + public function escapeField($string); + + /** * Compiles and returns an associative array of the arguments for this prepared statement. * * @param $queryPlaceholder @@ -632,4 +644,5 @@ public function __clone(); * The called object. */ public function forUpdate($set = TRUE); + } diff --git a/core/lib/Drupal/Core/Entity/Query/ConditionFundamentals.php b/core/lib/Drupal/Core/Entity/Query/ConditionFundamentals.php index 195479d..b93e192 100644 --- a/core/lib/Drupal/Core/Entity/Query/ConditionFundamentals.php +++ b/core/lib/Drupal/Core/Entity/Query/ConditionFundamentals.php @@ -37,14 +37,26 @@ protected $query; /** + * List of potential namespaces of the classes belonging to this condition. + * + * @var array + */ + protected $namespaces = array(); + + /** * Constructs a Condition object. * * @param string $conjunction * The operator to use to combine conditions: 'AND' or 'OR'. + * @param QueryInterface $query + * The entity query this condition belongs to. + * @param array $namespaces + * List of potential namespaces of the classes belonging to this condition. */ - public function __construct($conjunction, QueryInterface $query) { + public function __construct($conjunction, QueryInterface $query, $namespaces = []) { $this->conjunction = $conjunction; $this->query = $query; + $this->namespaces = $namespaces; } /** diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Condition.php b/core/lib/Drupal/Core/Entity/Query/Sql/Condition.php index 3e71e56..1ee2c3d 100644 --- a/core/lib/Drupal/Core/Entity/Query/Sql/Condition.php +++ b/core/lib/Drupal/Core/Entity/Query/Sql/Condition.php @@ -7,7 +7,6 @@ namespace Drupal\Core\Entity\Query\Sql; -use Drupal\Core\Database\Database; use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Database\Query\Condition as SqlCondition; use Drupal\Core\Entity\Query\ConditionBase; @@ -90,13 +89,8 @@ public function notExists($field, $langcode = NULL) { * @see \Drupal\Core\Database\Query\ConditionInterface::condition() */ public static function translateCondition(&$condition, SelectInterface $sql_query, $case_sensitive) { - // There is nothing to do for IN () queries except for PostgreSQL for which - // the condition arguments need to have case lowered to support not case - // sensitive fields. + // // There is nothing we can do for IN (). if (is_array($condition['value'])) { - $entityQueryCondition = Database::getConnection()->getDriverClass('EntityQuery\\Condition'); - $entityQueryCondition::translateCondition($condition, $case_sensitive); - return; } diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/ConditionAggregate.php b/core/lib/Drupal/Core/Entity/Query/Sql/ConditionAggregate.php index 584a883..9db67ea 100644 --- a/core/lib/Drupal/Core/Entity/Query/Sql/ConditionAggregate.php +++ b/core/lib/Drupal/Core/Entity/Query/Sql/ConditionAggregate.php @@ -11,6 +11,7 @@ use Drupal\Core\Entity\Query\ConditionAggregateBase; use Drupal\Core\Entity\Query\ConditionAggregateInterface; use Drupal\Core\Database\Query\Condition as SqlCondition; +use Drupal\Core\Entity\Query\QueryBase; /** * Defines the aggregate condition for sql based storage. @@ -39,7 +40,8 @@ public function compile($conditionContainer) { else { $type = ((strtoupper($this->conjunction) == 'OR') || ($condition['operator'] == 'IS NULL')) ? 'LEFT' : 'INNER'; $field = $tables->addField($condition['field'], $type, $condition['langcode']); - Condition::translateCondition($condition, $sql_query, $tables->isFieldCaseSensitive($condition['field'])); + $condition_class = QueryBase::getClass($this->namespaces, 'Condition'); + $condition_class::translateCondition($condition, $sql_query, $tables->isFieldCaseSensitive($condition['field'])); $function = $condition['function']; $placeholder = ':db_placeholder_' . $conditionContainer->nextPlaceholder(); $conditionContainer->having("$function($field) {$condition['operator']} $placeholder", array($placeholder => $condition['value'])); diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php b/core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php index c76a773..1d5a16e 100644 --- a/core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php +++ b/core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php @@ -52,7 +52,8 @@ public function prepare() { * Implements \Drupal\Core\Entity\Query\QueryAggregateInterface::conditionAggregateGroupFactory(). */ public function conditionAggregateGroupFactory($conjunction = 'AND') { - return new ConditionAggregate($conjunction, $this); + $class = static::getClass($this->namespaces, 'ConditionAggregate'); + return new $class($conjunction, $this, $this->namespaces); } /** diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/pgsql/Condition.php b/core/lib/Drupal/Core/Entity/Query/Sql/pgsql/Condition.php new file mode 100644 index 0000000..5d61eab --- /dev/null +++ b/core/lib/Drupal/Core/Entity/Query/Sql/pgsql/Condition.php @@ -0,0 +1,35 @@ +escapeField($condition['real_field']) . ') ' . $condition['operator'] . ' ('; + $condition['where_args'] = []; + + $n = 1; + // Only use the array values in case an associative array is passed as an + // argument following similar pattern in + // \Drupal\Core\Database\Connection::expandArguments(). + foreach ($condition['value'] as $value) { + $condition['where'] .= 'LOWER(:value' . $n . '),'; + $condition['where_args'][':value' . $n] = $value; + $n++; + } + $condition['where'] = trim($condition['where'], ','); + $condition['where'] .= ')'; + return; + } + parent::translateCondition($condition, $sql_query, $case_sensitive); + } +} diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/pgsql/QueryFactory.php b/core/lib/Drupal/Core/Entity/Query/Sql/pgsql/QueryFactory.php new file mode 100644 index 0000000..fb43f13 --- /dev/null +++ b/core/lib/Drupal/Core/Entity/Query/Sql/pgsql/QueryFactory.php @@ -0,0 +1,30 @@ +