Update 6162 changes nodewords' schema field id from varchar to int and makes it NOT NULL, just as it should be.

The problem here is that all contents of the field are lost, if one of the records of the table has this field empty (the previous schema version sadly permitted that).

It runs the following:

    * DROP INDEX {nodewords}_nodewords_type_id_idx
    * ALTER TABLE {nodewords} DROP CONSTRAINT {nodewords}_nodewords_type_id_name_key
    * ALTER TABLE {nodewords} RENAME "type" TO "type_old"
    * ALTER TABLE {nodewords} ADD COLUMN type smallint CHECK (type >= 0) default 0
    * UPDATE {nodewords} SET type = CAST(type_old AS smallint)
    * ALTER TABLE {nodewords} ALTER type SET NOT NULL
    * ALTER TABLE {nodewords} DROP COLUMN type_old
    * ALTER TABLE {nodewords} RENAME "id" TO "id_old"
    * ALTER TABLE {nodewords} ADD COLUMN id smallint CHECK (id >= 0) default 0

At this point the query failed, as our table had, for some reason, one record that had this field as empty:

    * Failed: UPDATE {nodewords} SET id = CAST(id_old AS smallint)
    * ALTER TABLE {nodewords} ALTER id SET NOT NULL

Further down, the old id's are dropped even though the update above failed, and as a result, all id values are lost:

    * ALTER TABLE {nodewords} DROP COLUMN id_old
    * CREATE INDEX {nodewords}_nodewords_type_id_idx ON {nodewords} (type, id)

Finally, the following constraint cannot be added, as the values are still all zeros and thus not meet the uniqueness criteria:

    * Failed: ALTER TABLE {nodewords} ADD CONSTRAINT {nodewords}_nodewords_type_id_name_key UNIQUE (type,id,name)

Our DB is PostgreSQL 8.3. The exact relevant error message is: warning: pg_query() [function.pg-query]: Query failed: ERROR: invalid input syntax for integer: "" in /var/www2/testi_l/includes/database.pgsql.inc on line 139..

MySQL might be more permissive here, potentially substituting zero for an empty string, but even then this is a potential problem, if there are more empty records than just one. They're not that common: we had one empty string among nearly 3,000 records, but if there is even one, update 6162 brings disastrous results.

Comments

damienmckenna’s picture

Issue tags: +v6.x-1.12 blocker

Tagging.

AlexisWilke’s picture

If I'm correct the old id's were strings and they cannot that easily be converted to integers. (not just with a CAST)

dave reid’s picture

Status: Active » Postponed (maintainer needs more info)

But the strings should be integers as strings. Does you happen to have a backup or .sql file of your metatag tables from before you updated? If they don't contain any sensitive data, please attach them to this issue so we can test.

AlexisWilke’s picture

Dave,

I think the problem is mainly from the default entries. An empty string (id = '') is not converted to zero (0) with PostgreSQL. Looking at one of my old DB backup, all the old entries were numbers.

   96 | High quality software development to your specifications. Contact us for more info and see how we will handle your software needs.                                                                        | default    |     | description
   97 | software,development                                                                                                                                                                                      | default    |     | keywords

Now, I could not see the change 6162, if it was in nodewords.install (since it is changing {nodewords} that's where I'd expect to find it.)

So I guess this entry could be closed? Although if you want to fix the table before doing the change of the id column type, you'd do something like this:

UPDATE {nodewords} SET id = '0' WHERE id = '';

It feels like I've already mentioned that somewhere...

Thank you.
Alexis

Addition:

Ah! change 6164 says this:

$ret[] = update_sql("UPDATE {nodewords} set id = '0' WHERE id = '' OR id IS NULL");

So I think this is fixed already. 8-)

quicksketch’s picture

Status: Postponed (maintainer needs more info) » Closed (duplicate)

I've provided a patch to fix this issue in #681490: Update 6162 Fails When Upgrading Directly From 6.x-1.0 to 6.x-1.11. The "fix" is only included in the 2.x branch at this point, so it needs to be re-rolled into the 1.x branch. The new patch uses the simple solution suggested by AlexisWilke.