We're just coming to the end of migrating our Drupal sites from 6 to 7 and have encountered issues relating to the use of cross database queries (MySQL), hyphens and reserved words in SQL queries in Drupal 7 that did not exist in Drupal 6.

Due to the size of our database and complexity of our system, it is impractical to re-work our databases to comply with the way the database layer works in Drupal 7 (although long term cleaning up some column/table names would be beneficial).

Having read through the code and various issues, I can see we are not the only people to have come across this issue.

On reflection, it seems that there are some issues with the use of the DatabaseConnection escapeAlias, escapeField and escapeTable methods, and the methods themselves. These three methods work on the basis of *filtering* the names based on restrictions imposed by Drupal. I generally believe this kind of filtering is a mistake, especially as the three supported databases have a mechanism for handling this - i.e. quoted identifiers.

The issues are compounded in my opinion by the fact that the database layer does not inform the developer when it performs such filtering. Specifically when the database layer performs this kind of filtering, it means the module developer has done something that is unsupported, hence the database layer should throw an exception and refuse to do anything at all - the developer could rapidly fix the issue and all would be well.

Practically speaking, we would not be able to work with that, so I've had to patch the database layer to quote all identifiers using the database specific quote character. The attached patch does this for MySQL, pgSQL and SQLite.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Kevin Rogers’s picture

Here's an updated version of the patch which fixes several issues:

  • Only support periods when escaping for MySQL as other databases don't understand them
  • Ensure orderBy and groupBy fields are automatically quoted too
  • Remove restriction on orderBy fields in PgSQL, as orderBy fields are now quoted automatically
eneko1907’s picture

Im still going through this patch (much needed),

I think I spotted one typo, introduced on the includes/database/select.inc tweaks: 'hasAnyTags' by 'hasAnyTag' around line 599 or so

nevermind about the typo, this must be a diff between my stable and the dev. target. difference exists, but not due to this patch..

eneko1907’s picture

This patch works for my use case, THANKS!

We query external databases that may not follow long-standing database conventions. For example, many table column labels may have all sort of non standard characters. Specifically, what triggered my interest in the patch was to deal well with the " " blanks in column names. Those blanks are currently ignored by Drupal, and the resulting (select) query fails. OK, unclear still? I query an external database table that has a column on called DISCHARGE RATE, Drupal converts this in the process to DISCHARGERATE, but of course, such column does not exist in the external table, query fails. boo.

Incidentally, we use of the Dave Reid's contrib schema_reference to expose external databases to Drupal via field, then use other custom modules to produce all sort of queries.

Your patch works for me in this very specific case: i did not run a full suite of tests against other characters, 'creative' table names, other databases such as pgsql or sqllite.

One thing, I am working with stable, so I adapted the change at includes/database/mysql/database.inc (which was rejected).. It seems in dev, there is extra checks in the line of code on the line 92. What I did is use the escapeTable in the corresponding line, that did the trick. (and flushing some caches, just in case)

    $this->query('CREATE TEMPORARY TABLE {' . $this->escapeTable($tablename) . '} Engine=MEMORY ' . $query, $args, $options);

Thanks for the patch -- I may add more cases as I encounter them to verify that this works in more cases.

scorchio’s picture

Version: 7.x-dev » 8.0.x-dev

We've just found this issue with my colleagues when we were trying to define / use a new entity type. I've triggered it fairly easily by doing to following:

  1. Use ECK to create a new entity type.
  2. Add a new property with a machine name which is a reserved word - in our case, it was "show" and enable it.
  3. Try to add a new entity with the type just created - it will fail with the PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 message.

As far as I can see, this is still an issue in D8, so I've bumped the version.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

joachim’s picture

Status: Active » Closed (duplicate)