Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 295813

select queries can fail in MySQL 8 for tables with reserved names

$
0
0

Problem/Motivation

We've come across this issue in #2978575-152: Mysql 8 Support on Drupal 7 where we're working on back-porting the MySQL 8 support implemented in D8 in #2966523: MySQL 8 Support. It seems the problem still exists in 8.9.x

Given a table with a name that's a reserved keyword in MySQL 8, certain SELECT queries can fail as the table name is automatically added as an alias in the SQL and is not escaped / quoted.

In D7 this surfaces in \DatabaseTemporaryQueryTestCase::testTemporaryQuery as that does a countQuery() on the system table (where "system" is reserved).

D8 doesn't have a system table, but the same query fails if we do create a table with a reserved name.

AFAICS this is no longer a problem in D9.x (perhaps because of #2986452: Database reserved keywords need to be quoted as per the ANSI standard ?).

I'll attach a patch with a very basic test that illustrates this in 8.9.x

It's also easy to reproduce manually:

mysql> CREATE TABLE `virtual` (`id` int);
$ drush ev "var_dump(db_select('virtual')->countQuery()->execute()->fetchField());"
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'virtual [error]
virtual) subquery' at line 5 in /path/to/drupal-8.x/core/lib/Drupal/Core/Database/Statement.php:59
Stack trace:
#0 /path/to/drupal-8.x/core/lib/Drupal/Core/Database/Statement.php(59): PDOStatement->execute(Array)
#1 /path/to/drupal-8.x/core/lib/Drupal/Core/Database/Connection.php(640): Drupal\Core\Database\Statement->execute(Array, Array)
#2 /path/to/drupal-8.x/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php(357): Drupal\Core\Database\Connection->query('SELECT COUNT(*)...', Array, Array)
#3 /path/to/drupal-8.x/core/lib/Drupal/Core/Database/Query/Select.php(510): Drupal\Core\Database\Driver\mysql\Connection->query('SELECT COUNT(*)...', Array, Array)
#4 phar:///opt/drush/drush-8.3.5.phar/commands/core/core.drush.inc(1178) : eval()'d code(1): Drupal\Core\Database\Query\Select->execute()

[...snip...]

Next Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for
the right syntax to use near 'virtual virtual) subquery' at line 5: SELECT COUNT(*) AS expression
FROM
(SELECT 1 AS expression
FROM
{virtual} virtual) subquery; Array
(
)
 in /path/to/drupal-8.x/core/lib/Drupal/Core/Database/Connection.php:701

I'm not sure why this alias is not automatically quoted as a reserved word; it may be because this particular way of constructing and executing a SelectQuery doesn't end up invoking \SelectQuery::__toString and therefore escapeAlias is not called. I'm not certain about that yet though.

Proposed resolution

Ensure that table aliases are escaped if they are reserved words (or perhaps ensure that reserved words are not used as aliases in the first place?).

Remaining tasks

Identify a solution, implement it, and backport it to D7.

User interface changes

n/a

API changes

n/a ?

Data model changes

n/a ?

Release notes snippet

tbc


Viewing all articles
Browse latest Browse all 295813

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>