While working with the update process today I think I found some inconsistencies with #582948: Improve safety of schema manipulation possibly. At first I thought it might be with db_change_field until I looked at the databse prior to updating. So here's my question

A D5 database was updated to D6.15 but apparently has bou' cou's of schema errors. for example the filter table. My D5->D6 filter table schema looks like this

format
module
delta
weight
fid

The fields are ok but there are no indexes.

In filter.install is this code

// Rename field 'delta' to 'name'.
  db_drop_unique_key('filter', 'fmd');
  db_drop_index('filter', 'list');
  db_change_field('filter', 'delta', 'name',
    array(
      'type' => 'varchar',
      'length' => 32,
      'not null' => TRUE,
      'default' => '',
      'description' => 'Name of the filter being referenced.',
    ),
    array(
      'unique keys' => array(
        'fmn' => array('format', 'module', 'name'),
      ),
      'indexes' => array(
        'list' => array('format', 'weight', 'module', 'name'),
      ),
    )
  );

In #582948: Improve safety of schema manipulation I'm not sure if unique_keys() were addressed, db_drop_index() was fixed I believe to ignore non-existent indexes. How would one check for a unique_key. where I've seen "unique keys" in mysql, it is a index but I've tried dropping a index to removed the key but that didn't go over too well either. shouldn't db_drop_unique_key() respond the same as db_drop_index() ?

I don't pretend to know mysql too well, my database of choice is the older multi-value databases such as universe by ibm, cache from inter-systems, and D3 from raining data. Guess my green screens are showing

Comments

Crell’s picture

Woah, old skool! :-)

Looking at the code, db_drop_unique_key() should behave the same as db_drop_index() now: After it runs, there is no unique key on that field and the return value indicates whether or not there was one to begin with. If that's not the case for some reason, can you reproduce it, preferably with a unit test?

ctmattice1’s picture

Crell, I'm not sure how to do a unit test on this.

This happens to me on update.php, have tried placing print_r(backtrace()) in several places to catch stuff but still haven't found the right function.

What is happening is on updating I run fine through filter_7002 update, tables are changed then it bombs at 7003, I have a array_pop error in update.php so I can't get the last completed. This has to do with the _session cookie and I use firefox 3.5, haven't tried in safari or IE to see if this is similar to the _session issue currently open (can't remember issue #).

I originally thought it was the comment.module update bombing due to field.module not being enabled, So I flipped system.install update_7002 to create 6056 and put update_7020 in at 7002 to get the field.module installed earlier. That took care of the field_bundle_* errors I was getting and manually tracing the sql tables to where I think the update appears to die at filter_7002 but could be the prior taxonomy update as well.

If you can give me any suggestion I'll see what I can come up with. I agree looking at the api it should work but pulling my hair out.

Crell’s picture

Component: database system » update system

Hm. I am just as confused as you are. Refiling over to the update system in case someone there can shed some light on the situation, as it seems to be localized to the update process. (That does have some issues at present.)

ctmattice1’s picture

Title: db_ functions question » was db_ functions question -> changing to db_change_field() FAILS
Component: update system » database system

Changing this back to database system. Changing subject for clarity

I added
print "7003 After change_field"; die(); into the function:

// Rename field 'delta' to 'name'.
  db_drop_unique_key('filter', 'fmd');
  db_drop_index('filter', 'list');
  db_change_field('filter', 'delta', 'name',
    array(
      'type' => 'varchar',
      'length' => 32,
      'not null' => TRUE,
      'default' => '',
      'description' => 'Name of the filter being referenced.',
    ),
    array(
      'unique keys' => array(
        'fmn' => array('format', 'module', 'name'),
      ),
      'indexes' => array(
        'list' => array('format', 'weight', 'module', 'name'),
      ),
    )
  );

To debug stepwise though it

Results with consistent repeat
____________________________________________________________

db_drop_unique_key() caused the die() - No unique key was in the table

->Stepped the die() function

db_drop_index caused the die() - There was a index, it got dropped

->Stepped the die() function

db_change_field() ran though the process and DID NOT DIE. Field value remains same.

Dropped the $keys_new argument. reloaded the old database and reran the process beginning again at db_drop_unique_key

process died as expected at starting step.

db_drop_unique_key - No unique key was in the table
db_drop_index - The 'list' index was dropped
db_change_field - The table name was changed.

added db_add_unique_key('filter', 'fmn', array('format', 'module','name'));

to see if this way would work. BOMBED

There is definitely a problem here when either a "unique key" or possibly when a serial field (such as format) is present but can't tell you which.

Here is the dump I was using for the filter table

--
-- Table structure for table `filters`
--

CREATE TABLE IF NOT EXISTS `filters` (
  `format` int(4) NOT NULL DEFAULT '0',
  `module` varchar(64) NOT NULL DEFAULT '',
  `delta` tinyint(2) NOT NULL DEFAULT '0',
  `weight` tinyint(2) NOT NULL DEFAULT '0',
  `fid` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`fid`),
  KEY `list` (`format`,`weight`,`module`,`delta`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=19 ;

--
-- Dumping data for table `filters`
--

INSERT INTO `filters` (`format`, `module`, `delta`, `weight`) VALUES
(4, 'urlfilter', 0, 0),
(2, 'filter', 1, 0),
(1, 'urlfilter', 0, 10),
(1, 'urlfilter', 0, 10),
(1, 'filter', 2, 1),
(1, 'interwiki', 0, 10),
(4, 'filter', 2, 1),
(5, 'textile', 0, 0),
(4, 'urlfilter', 0, 0),
(4, 'filter', 2, 1),
(5, 'textile', 0, 0),
(4, 'urlfilter', 0, 0),
(4, 'filter', 2, 1),
(5, 'textile', 0, 0),
(3, 'footnotes', 0, 10),
(3, 'filter', 2, 0);

The machine is vista, running xampp 1.7.1 with "Apache/2.2.11 (Win32) DAV/2 mod_ssl/2.2.11 OpenSSL/0.9.8i PHP/5.2.9"
MySQL is "Server version: 5.1.33-community"

ctmattice1’s picture

Title: was db_ functions question -> changing to db_change_field() FAILS » db_change_field() FAILS using $keys_new argument
Priority: Normal » Critical

Something is really WACKY. bumping to critical

Since I can not get db_change_field with the $keys_new argument to work, dropped trying.

In the update process there are three calls to db_add_unique_key()

First is in system.install called system_update_6055

It preforms flawlessly.

Second is in filters.install called filter_update_7003

It fails no matter what I try.

The third is down further on the list in system.install called system_update_7042 which I'm not sure if it would work or not as of yet.

Why is it that the first time db_add_unique_key() it works but fails on the second call to the function, could this be related to #690746: Text column type doesn't reliably hold serialized variables or #717902: Updated DB schema not available in module update functions. Also curiousity strikes me that it works consistently on install but not on a db alteration.

Please feel free to re-title,

ctmattice1’s picture

Priority: Critical » Minor

Found the issue.

It seems with "unique keys" when you add them if your not using all the columns (including the primary key) then the primary key has to be included or it fails. Be nice to document this could save someone else a bunch of time.

Crell’s picture

Hm. Weird. Can you roll a documentation patch for review? :-)

Status: Active » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.