when updating a D5 site running on postgres to D6, ubercart runs through the update procedure. Unfortunately there are a few bugs in 6000 updates, but fixed in later updates that critically break ubercart and deletes data.
1) Price / Cost / Weight within uc_order_products
db_change_field($ret, 'uc_order_products', 'cost', 'cost', array('type' => 'numeric', 'precision' => 10, 'scale' => 2, 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
db_change_field($ret, 'uc_order_products', 'price', 'price', array('type' => 'numeric', 'precision' => 10, 'scale' => 2, 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
This is set in update 6000, but will break in postgres (it won't create the fields)
Because of this, you'll get some strange things going on:
# ALTER TABLE {uc_order_products} DROP COLUMN qty_old
# ALTER TABLE {uc_order_products} RENAME cost TO cost_old
# Failed: ALTER TABLE {uc_order_products} ADD COLUMN cost numeric_unsigned(10, 2) default 0
# Failed: UPDATE {uc_order_products} SET cost = cost_old
# Failed: ALTER TABLE {uc_order_products} ALTER cost SET NOT NULL
# ALTER TABLE {uc_order_products} DROP COLUMN cost_old
You'll see, that since it fails to create the new column, it won't update it, and then it trashes the old column and you loose all data!
Suggested fix: put the fix in 6004 into 6000 for uc_order.install
Fix for the weight problem (unsigned values in postgres), put the fix in 6006 in 6000 for uc_order.install
2) uc_order billing_zone
This is interesting for international users. Sometimes the billing zone gets set to -1. If this is the case we need to check for it and make these values 0. Otherwise, the update will fail when the column is modified, causing ALL LOSS of billing_zone data!
3) uc_shipping.module
There is a change column for 'value' making it an unsigned int (10,2) This is fixed in in 6003, should apply it to 6000.
4) Checking for null values
Many of the columns will fail when being converted to 'NOT NULL' if there is a null value inside them. Suggest adding code checks to convert NULLs into '' or 0.
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | postgres_fail.patch | 3.46 KB | Island Usurper |
Comments
Comment #1
japerryFound another interesting break. oops typo:
Line 574 - 578 on uc_attribute.install:
db_change_field($ret, 'uc_attribute_options', 'aid', 'aid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
db_change_field($ret, 'uc_attribute_options', 'oid', 'oid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE));
if ($GLOBALS['db_type'] == 'pgsql') {
db_add_primary_key($ret, 'uc_attributes', array('oid'));
}
You'll notice on line 577 that should Say 'uc_attribute_options' NOT uc_attributes (there is no oid for uc_attributes!)
Comment #2
japerryTypo on uc_order.install for primary key:
# Failed: ALTER TABLE {uc_order_products} ADD PRIMARY KEY (order_products_id)
if ($GLOBALS['db_type'] == 'pgsql') {
db_add_primary_key($ret, 'uc_order_products', array('order_products_id'));
}
should say:
if ($GLOBALS['db_type'] == 'pgsql') {
db_add_primary_key($ret, 'uc_order_products', array('order_product_id'));
}
Comment #3
Island Usurper commentedSince the problem is the 'unsigned' => TRUE bit, that should just be taken out from the earlier updates. It should be alright to leave the later updates that do the same thing, just in case there are some people still on schema version 6001.
Comment #4
Island Usurper commentedAlso, tagged.
Comment #5
rszrama commented