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";');

Comments

Island Usurper’s picture

That 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.

cha0s’s picture

Assigned: Unassigned » cha0s
Status: Active » Needs review
StatusFileSize
new2.67 KB

Do we need the unsigned cast?

Island Usurper’s picture

Status: Needs review » Fixed
StatusFileSize
new2.75 KB

Not 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.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.