diff --git a/includes/common.inc b/includes/common.inc index f61d1eb0..1ac1a237 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -7878,6 +7878,7 @@ function entity_get_info($entity_type = NULL) { $entity_info[$name]['base table field types'] = drupal_schema_field_types($entity_info[$name]['base table']); $entity_info[$name]['schema_fields_sql']['base table'] = drupal_schema_fields_sql($entity_info[$name]['base table']); if (isset($entity_info[$name]['revision table'])) { + $entity_info[$name]['revision table field types'] = drupal_schema_field_types($entity_info[$name]['revision table']); $entity_info[$name]['schema_fields_sql']['revision table'] = drupal_schema_fields_sql($entity_info[$name]['revision table']); } } diff --git a/includes/entity.inc b/includes/entity.inc index e80ce3b8..97aa532b 100644 --- a/includes/entity.inc +++ b/includes/entity.inc @@ -188,6 +188,11 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface { $this->cleanIds($ids); } + // Ensure integer revision ID is valid. + if (!empty($revision_id)) { + $revision_id = $this->cleanRevisionId($revision_id); + } + // Load any remaining entities from the database. This is the case if $ids // is set to FALSE (so we load all entities), if there are any ids left to // load, if loading a revision, or if $conditions was passed without $ids. @@ -250,6 +255,31 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface { } } + /** + * Ensures integer entity revision ID is valid. + * + * The identifier sanitization provided by this method has been introduced + * as Drupal used to rely on the database to facilitate this, which worked + * correctly with MySQL but led to errors with other DBMS such as PostgreSQL. + * + * @param int $id + * The entity ID revision to verify. Non-integer ID are removed from this + * array if the entity type requires ID to be integer. + * + * @return int|bool + * The passed in ID if it is valid, FALSE otherwise. + */ + protected function cleanRevisionId($id) { + $entity_info = entity_get_info($this->entityType); + if (isset($entity_info['revision table field types'])) { + $id_type = $entity_info['revision table field types'][$this->idKey]; + if ($id_type == 'serial' || $id_type == 'int') { + return $this->filterId($id) ? $id : FALSE; + } + } + return $id; + } + /** * Callback for array_filter that removes non-integer IDs. */ @@ -287,6 +317,11 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface { $query->addTag($this->entityType . '_load_multiple'); + // Ensure integer revision ID is valid. + if (!empty($revision_id)) { + $revision_id = $this->cleanRevisionId($revision_id); + } + if ($revision_id) { $query->join($this->revisionTable, 'revision', "revision.{$this->idKey} = base.{$this->idKey} AND revision.{$this->revisionKey} = :revisionId", array(':revisionId' => $revision_id)); }