This is the same problem as in http://drupal.org/node/359776 but references the error message produced by 6.x-2.0-beta3.
System config:
Drupal 6.9, Ubercart 2.0-beta3, Postgresql 8.3
Steps to reproduce:
In Store Administration/Orders, view an order then click Packages tab. Drupal shows the error (and "Create Packages" link does not show):
ERROR: function if(boolean, integer, bigint) does not exist
I believe two fixes are needed to make this work in MySQL and Postgresql.
1. The MySQL construct "IF(expr1,expr2,expr3)", e.g. "SELECT IF(1<2,'yes','no')", does not work in Postgresql. Instead I think the CASE operator is cross-compatible. I believe it is supported in both MySQL 5.0+ and Postgresql 7.4+.
Docs:
MySQL: http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html
Postgresql: http://www.postgresql.org/docs/8.0/interactive/functions-conditional.html
This involves the following change In shipping/uc_shipping/uc_shipping.admin.inc, line 48:
Change: IF(COUNT(pp.qty) = 0, 0, SUM(op.qty) / COUNT(pp.qty))
To: CASE WHEN COUNT(pp.qty) = 0 THEN 0 ELSE SUM(op.qty) / COUNT(pp.qty) END
2. A second change is needed for the UNSIGNED type. Postgresql does not natively have this type. I believe int_unsigned is more appropriate.
Here is the new query for packages (shipping/uc_shipping/uc_shipping.admin.inc, line 48):
$result = db_query("SELECT op.order_product_id, CASE WHEN COUNT(pp.qty) = 0 THEN 0 ELSE SUM(op.qty) / COUNT(pp.qty) END AS total, SUM(pp.qty) AS packaged FROM {uc_order_products} AS op LEFT JOIN {uc_packaged_products} AS pp ON op.order_product_id = pp.order_product_id WHERE op.order_id = %d AND op.data LIKE '%%%s%%' GROUP BY op.order_product_id HAVING SUM(pp.qty) IS NULL OR CAST(SUM(op.qty) / COUNT(pp.qty) AS int_unsigned) > SUM(pp.qty)", $order->order_id, 's:9:"shippable";s:1:"1";');
There is also a related problem in the shipments tab. This is also related to COUNT(pp.qty) being 0. To fix this in Postgresql we need a CASE operator to handle when COUNT(pp.qty) is 0 and we also need to change UNSIGNED to int_unsigned. This results in the following query (shipping/uc_shipping/uc_shipping.admin.inc, line 411):
$result = db_query("SELECT op.order_product_id, CAST(CASE WHEN COUNT(pp.qty) = 0 THEN 0 ELSE SUM(op.qty) / COUNT(pp.qty) END AS int_unsigned) AS total, SUM(pp.qty) AS packaged FROM {uc_order_products} AS op LEFT JOIN {uc_packaged_products} AS pp ON op.order_product_id = pp.order_product_id WHERE op.order_id = %d AND op.data LIKE '%%%s%%' GROUP BY op.order_product_id HAVING SUM(pp.qty) IS NULL OR CAST(SUM(op.qty) / COUNT(pp.qty) AS int_unsigned) > SUM(pp.qty)", $order->order_id, 's:9:"shippable";s:1:"1";');
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | shipping_pgsql.patch | 2.75 KB | Island Usurper |
| #2 | uc_shipping.pgsql_.patch | 2.67 KB | cha0s |
Comments
Comment #1
Island Usurper commentedThat text is hard to read. Can you edit your issue to use
or<code>tags, please? At least for the second issue.The problem with using int_unsigned is that it doesn't exist for MySQL. I'd really hate to use different queries for the different databases. Perhaps I was being too clever with these queries.
Comment #2
cha0s commentedDo we need the unsigned cast?
Comment #3
Island Usurper commentedNot when it's put that way.
However, the HAVING statements needed to be updated to use the CASE as well, I think. Committed this patch.