MySQL: SHOW TABLES LIKE database.tablename doesn't work

Morbus Iff - July 25, 2008 - 02:43
Project:Drupal
Version:7.x-dev
Component:database system
Category:bug report
Priority:critical
Assigned:Unassigned
Status:duplicate
Description

Consider a shared multisite like so:

<?php
$db_prefix
= array(
 
'default'   => 'cf_primary.primary_',
 
'users'     => 'cf_shared.shared_',
 
'sessions'  => 'cf_shared.shared_',
 
'role'      => 'cf_shared.shared_',
 
'authmap'   => 'cf_shared.shared_',
 
'sequences' => 'cf_shared.shared_',
);
?>

And then, consider the code db_table_exists('cache_filter'). When run, it'll run the SQL SHOW TABLES LIKE 'cf_primary.primary_cache_filter' which is invalid for MySQL. What DOES work, on the other hand is SHOW TABLES FROM cf_primary LIKE 'cache_filter'. I propose that db_table_exists() becomes aware of a database name prefix (the stuff before a .). Note that the similar db_column_exists() DOES work already (SHOW COLUMNS FROM drupal_6.watchdog LIKE 'wid'; does what it's supposed to).

Comments from database experts?

#1

mooffie - September 12, 2008 - 12:45

#2

Crell - September 13, 2008 - 01:53

Isn't the database-in-table-name thing a MySQL-specific feature?

#3

Damien Tournoud - September 13, 2008 - 09:34

@Crell: Schemas in PostgreSQL work in a very similar manner.

See also: #294301: db_table_exists for multiple schemas database

#4

Crell - September 14, 2008 - 20:14

OK, but is that coincidence or an actual SQL standard? If a standard, we should support it where possible. If a limited extension, we should probably try to avoid relying on it unless we are able to abstract it for use on other database engines (the way the query builders abstract multi-insert and merge, for instance).

#5

webkenny - October 24, 2008 - 18:12

+1 This is an issue for us as well. In Drupal 5.x when running update.php in a multi-site configuration with prefixing. We get the following errors:

  • user warning: Table 'myprefix_cache_filter' already exists query: CREATE TABLE kenny_myprefix.myprefix_cache_filter ( cid varchar(255) NOT NULL default '', data longblob, expire int NOT NULL default '0', created int NOT NULL default '0', headers text, PRIMARY KEY (cid), INDEX expire (expire) ) /*!40100 DEFAULT CHARACTER SET UTF8 */ in /home/kenny/public_html/myprefix/includes/database.mysqli.inc on line 156.
  • user warning: Table 'myprefix_cache_menu' already exists query: CREATE TABLE kenny_myprefix.myprefix_cache_menu ( cid varchar(255) NOT NULL default '', data longblob, expire int NOT NULL default '0', created int NOT NULL default '0', headers text, PRIMARY KEY (cid), INDEX expire (expire) ) /*!40100 DEFAULT CHARACTER SET UTF8 */ in /home/kenny/public_html/myprefix/includes/database.mysqli.inc on line 156.
  • user warning: Table 'myprefix_cache_page' already exists query: CREATE TABLE kenny_myprefix.myprefix_cache_page ( cid varchar(255) BINARY NOT NULL default '', data longblob, expire int NOT NULL default '0', created int NOT NULL default '0', headers text, PRIMARY KEY (cid), INDEX expire (expire) ) /*!40100 DEFAULT CHARACTER SET UTF8 */ in /home/kenny/public_html/myprefix/includes/database.mysqli.inc on line 156.
  • user warning: Table 'myprefix_cache_content' already exists query: CREATE TABLE kenny_myprefix.myprefix_cache_content ( cid varchar(255) NOT NULL default '', data longblob, expire int NOT NULL default '0', created int NOT NULL default '0', headers text, PRIMARY KEY (cid), INDEX expire (expire) ) /*!40100 DEFAULT CHARACTER SET UTF8 */ in /home/kenny/public_html/myprefix/includes/database.mysqli.inc on line 156.

#6

seanburlington - October 25, 2008 - 10:12

SQL schemas are part of the SQL standard - seems like it would be useful to support this fully.

#7

c960657 - November 3, 2008 - 22:47

What about something like this? I haven't tested on PostgreSQL, but findTables() uses a similar approach.

AttachmentSizeStatusTest resultOperations
show-tables.patch4.66 KBIdleUnable to apply patch show-tables.patchView details | Re-test

#8

webkenny - November 5, 2008 - 15:09

What version is this patch for? Have you tested against 5 and 6 or is this 7 specific?

#9

webkenny - November 5, 2008 - 21:20
Priority:normal» critical
Status:active» needs review

We utilize multi-site with prefixed database names quite a bit for our clients. We have further discovered that not only is this an issue with update.php and install profiles but anywhere in code where db_table_exists() is called. For example, even adding fields to a CCK type throws this ugly warning as does any install or uninstall hook where the function is referenced. For this reason, we have created two patches for the purposes of multi-site installation which cover mysql and mysqli connections.

Essentially, we are checking for the existence of periods in a prefix (indicating a call to another database) and we are using the native mysql functions to perform the correct query for MySQL which is "SHOW TABLES FROM [dbname] LIKE [table]" as the original issue creator points out.

We feel that the widespread use of Drupal 5 calls for this patch and encourage developers who work in Drupal 6 and 7 to address this accordingly to version.

These patches address the files: includes/database.mysqli.inc and includes/database.mysql.inc

The development of this patch was sponsored by CommonPlaces E-Solutions LLC.

AttachmentSizeStatusTest resultOperations
mysqli-multisitefix.patch673 bytesIdleFailed: Failed to apply patch.View details | Re-test
mysql-multisitefix.patch669 bytesIdleFailed: Failed to apply patch.View details | Re-test

#10

spatz4000 - November 6, 2008 - 14:03

What version is this patch for? Have you tested against 5 and 6 or is this 7 specific?

My guess is 7.x, because development takes place there and if needed things are back ported.

#11

Anonymous (not verified) - November 13, 2008 - 12:30
Status:needs review» needs work

The last submitted patch failed testing.

#12

webkenny - November 17, 2008 - 16:53
Status:needs work» needs review

Sorry for that. Our apologies. I created the patch in the wrong structure. I have re-attached the patches here and they have been created using the Submitting Patches guidelines in the handbook.

AttachmentSizeStatusTest resultOperations
mysqli-multisitefix.patch664 bytesIdleFailed: Failed to apply patch.View details | Re-test
mysql-multisitefix.patch661 bytesIdleFailed: Failed to apply patch.View details | Re-test

#13

System Message - November 17, 2008 - 17:20
Status:needs review» needs work

The last submitted patch failed testing.

#14

lilou - November 17, 2008 - 17:29

You need to reroll your patch againt CVS/HEAD (drupal 7)

#15

webkenny - November 17, 2008 - 18:56

The issue is that the patch attached is for Drupal 5. That was my error as I thought I had been clear in the issue comments. I have created an issue for 5, #335450: Using database prefix names fails in MySQL database. Multi-site configurations., and have requested that Drupal 7 developers look at this patch and roll it for the proper version so it may be back-ported. Thank you.

I have attached the files for your review below suffixed with D5 so the auto-tester doesn't pick them up.

AttachmentSizeStatusTest resultOperations
mysqli-multisitefix-D5.patch664 bytesIgnoredNoneNone
mysql-multisitefix-D5.patch661 bytesIgnoredNoneNone

#16

webkenny - November 17, 2008 - 18:56
Status:needs work» patch (to be ported)

Changing status.

#17

spatz4000 - November 17, 2008 - 19:05

You would be the D7 developer, unless someone else has the itch to scratch this will never be tested in D7, and thus never back ported to 6 and 5.

#18

spatz4000 - November 17, 2008 - 19:05
Status:patch (to be ported)» needs work

#19

Damien Tournoud - November 17, 2008 - 19:44
Status:needs work» needs review

As far as I understand this issue, we are still in CNR, for the patch in #7, that suggested a clever way to solve that issue for both MySQL and PostgreSQL.

#20

Damien Tournoud - November 25, 2008 - 19:21

About #7:
- we don't use aliases: please use count() instead of sizeof()
- replace the COUNT(*) queries, and replace it with by a db_query_range() on table

Otherwise, looks very good.

#21

c960657 - November 25, 2008 - 21:18

This patch addresses the points raised in #20 and adds some tests.

I didn't touch the Sqlite code. According to this, SQLite supports information schema almost but not completely.

AttachmentSizeStatusTest resultOperations
show-tables-2.patch7.58 KBIdlePassed: 7903 passes, 0 fails, 0 exceptionsView details | Re-test

#22

Damien Tournoud - December 20, 2008 - 18:52
Status:needs review» duplicate

We have come up with a more generic solution in #342503: Schema function findTables fails on postgres - wrong SQL. Could you help us test and validate it?

 
 

Drupal is a registered trademark of Dries Buytaert.