summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorDavid Rothstein <drothstein@gmail.com>2015-05-04 23:13:51 -0400
committerDavid Rothstein <drothstein@gmail.com>2015-05-04 23:13:51 -0400
commitebc5d852d5386e0aebbc4a816242dced46b3946e (patch)
treef1d26cf7244b78696d45ce4a2acb419ad9514a88 /includes
parentedf23f2041761ad55d3cd38057f757bc68acfa5a (diff)
downloadbrdo-ebc5d852d5386e0aebbc4a816242dced46b3946e.tar.gz
brdo-ebc5d852d5386e0aebbc4a816242dced46b3946e.tar.bz2
Issue #1003788 by stefan.r, Alan D., JimmyAx, Josh Waihi, john_brown, twistor, bellHead, bzrudi71, pwolanin, gaas, wiifm, robhardwick, gngn: PostgreSQL PDOException: Invalid text representation when attempting to load an entity with a string or non-scalar ID
Diffstat (limited to 'includes')
-rw-r--r--includes/common.inc18
-rw-r--r--includes/entity.inc34
2 files changed, 52 insertions, 0 deletions
diff --git a/includes/common.inc b/includes/common.inc
index a80792e32..b7b9562d4 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -7138,6 +7138,23 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
}
/**
+ * Retrieves the type for every field in a table schema.
+ *
+ * @param $table
+ * The name of the table from which to retrieve type information.
+ *
+ * @return
+ * An array of types, keyed by field name.
+ */
+function drupal_schema_field_types($table) {
+ $table_schema = drupal_get_schema($table);
+ foreach ($table_schema['fields'] as $field_name => $field_info) {
+ $field_types[$field_name] = isset($field_info['type']) ? $field_info['type'] : NULL;
+ }
+ return $field_types;
+}
+
+/**
* Retrieves a list of fields from a table schema.
*
* The returned list is suitable for use in an SQL query.
@@ -7761,6 +7778,7 @@ function entity_get_info($entity_type = NULL) {
// Prepare entity schema fields SQL info for
// DrupalEntityControllerInterface::buildQuery().
if (isset($entity_info[$name]['base table'])) {
+ $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]['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 27434d048..62359a94a 100644
--- a/includes/entity.inc
+++ b/includes/entity.inc
@@ -183,6 +183,11 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
}
}
+ // Ensure integer entity IDs are valid.
+ if (!empty($ids)) {
+ $this->cleanIds($ids);
+ }
+
// 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.
@@ -224,6 +229,35 @@ class DrupalDefaultEntityController implements DrupalEntityControllerInterface {
}
/**
+ * Ensures integer entity IDs are 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 array $ids
+ * The entity IDs to verify. Non-integer IDs are removed from this array if
+ * the entity type requires IDs to be integers.
+ */
+ protected function cleanIds(&$ids) {
+ $entity_info = entity_get_info($this->entityType);
+ if (isset($entity_info['base table field types'])) {
+ $id_type = $entity_info['base table field types'][$this->idKey];
+ if ($id_type == 'serial' || $id_type == 'int') {
+ $ids = array_filter($ids, array($this, 'filterId'));
+ $ids = array_map('intval', $ids);
+ }
+ }
+ }
+
+ /**
+ * Callback for array_filter that removes non-integer IDs.
+ */
+ protected function filterId($id) {
+ return is_numeric($id) && $id == (int) $id;
+ }
+
+ /**
* Builds the query to load the entity.
*
* This has full revision support. For entities requiring special queries,