This is a PostgreSQL database specific error caused by the way PostgreSQL handles CAPS. The full error message is this:

PDOException: SQLSTATE[42703]: Undefined column: 7 ERROR: column "ISO4217Number" does not exist: CREATE INDEX "currency_ISO4217Number_idx"

The way to fix this is not to use CAPS when creating the index in currency/currency/currency.install (line 62):

From: 'ISO4217Number' => array('ISO4217Number'),
To: 'iso4217number' => array('iso4217number'),

I hope this helps,

Pimmy

CommentFileSizeAuthor
#6 currency_2007388_6.patch283 bytesXano
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Xano’s picture

Noted. We can't just change column name capitalization without checking for consequences first, though.

Pimmy’s picture

Yep, you're absolutely right - so far this simple fix doesnt show side effects.

Will let you know if I notice anything.

Xano’s picture

Any updates on this?

Xano’s picture

Issue summary: View changes
Status: Active » Closed (won't fix)

Closing due to lack of response.

bendiy’s picture

Status: Closed (won't fix) » Needs work
Parent issue: » #1600670: Cannot query Postgres database that has column names with capital letters

We've got some open patches over at #1600670: Cannot query Postgres database that has column names with capital letters that address this issue in core. I've tried to avoid renaming columns and instead, double quote them.

If you aren't going to fix this (which is fine because this is really a core issue), can we get a note on the project page or in a README.txt that PostgreSQL is not supported?

Xano’s picture

Status: Needs work » Needs review
FileSize
283 bytes
cmonnow’s picture

Rather than exclude PostgreSQL users I would make exceptions. There are a lot of modules that have to workaround PostgreSQL's Drupal-specific bugs (that persist due to its much smaller user base). [Aside: A lot of contrib modules use long field names making the use of PostgreSQL indexing impossible without core hacks or module customisation).]

Pimmy's solution will work in most circumstances since most mySQL setups ignore case but there may be rare version/OS exceptions or use of other databases I'm unfamiliar with (I haven't gone through all the schemas). The name of the array ($name) can stay the same (and will work independently of Drupal as part of the concatenated index name in the pgsql database) but the column name ($field) needs to be lower-cased since PostgreSQL will always ignore upper-case letters when creating column names that haven't been double-quoted (as in our case).

This causes a problem with pgsql since the pgsql-tailored schema functions force double quotes around field names when creating indexes.

 protected function _createIndexSql($table, $name, $fields) {
    $query = 'CREATE INDEX "' . $this->prefixNonTable($table, $name, 'idx') . '" ON {' . $table . '} (';
    $query .= $this->_createKeySql($fields) . ')';
    return $query;
  }

refers to:

  protected function _createKeySql($fields) {
    $return = array();
    foreach ($fields as $field) {
      if (is_array($field)) {
        $return[] = 'substr(' . $field[0] . ', 1, ' . $field[1] . ')';
      }
      else {
        $return[] = '"' . $field . '"';
      }
    }
    return implode(', ', $return);
  }

and as you can see $return[] = '"' . $field . '"' is the cause of heartache in this module and previously in others as well (e.g. mollom).

The best solution is for everyone to ignore uppercase letters in Drupal database names (which is more work) but if you want to make a special case for pgsql rather than venture into the unknown perhaps you can add a simple workaround:

e.g.

In currency_schema() function:

$ISO4217Number_field_name = (db_driver() == "pgsql") ? "iso4217number" : "ISO4217Number"; 

can be added to the top of the function to check the database in use and use the lower-case form only for pgsql.

Then redefine indexes in the schema as so:


    'indexes' => array(
      'ISO4217Number' => array($ISO4217Number_field_name),
    ),

I imagine if there were any problems they would be seen at install/uninstall (whether the indexes work is another issue).

nicobot’s picture

I'm also having issues with Postgres support for Currency, the columns ISO4217Code an ISO4217Number are not loaded from DB, and thus, we cannot customize some currencies.

My temporary solution was to implement a module that only has this:


/**
 * Implements hook_schema_alter().
 */
function currency_postgres_schema_alter(&$schema) {
  $schema['currency']['export']['object factory'] = 'currency_postgres_mapping';
}

/**
 * Adapts fields loaded from Database to work along with the camelcase definition
 * of the schema.
 *
 * @param $schema
 * @param $data
 *
 * @return \stdClass|string
 */
function currency_postgres_mapping($schema, $data) {
  $data->ISO4217Code = $data->iso4217code;
  $data->ISO4217Number = $data->iso4217number;
  return _ctools_export_unpack_object($schema, $data, 'Currency');
}