I consistently get the following PDOException when deleting a Role Assignment Product Feature on an Ubercart site running on PostgreSQL:

PDOException: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "role" LINE 2: WHERE (pfid IN ('6', '117', 'role', '<strong>SKU:</strong>... ^: DELETE FROM {uc_roles_products} WHERE (pfid IN (:db_condition_placeholder_0, :db_condition_placeholder_1, :db_condition_placeholder_2, :db_condition_placeholder_3)) ; Array ( [:db_condition_placeholder_0] => 6 [:db_condition_placeholder_1] => 117 [:db_condition_placeholder_2] => role [:db_condition_placeholder_3] => <strong>SKU:</strong> ONF-VLCMTGDLNS<br /><strong>Role:</strong> program facilitator<br /><strong>Expiration:</strong> 1 month(s)<br /><strong>Shippable:</strong> No<br /><strong>Multiply by quantity:</strong> No ) in uc_roles_feature_delete() (line 964 of /home/onf/public_html/sites/all/modules/ubercart/uc_roles/uc_roles.module).

Digging into this a bit, this is coming from this function:

function uc_roles_feature_delete($pfid) {
  db_delete('uc_roles_products')
    ->condition('pfid', $pfid)
    ->execute();
}

$pfid is apparently being passed an array of values instead of just the one value for the pfid, which results in an IN condition being passed, and PostgreSQL complains because the values are not all numeric. The values appear to be fields from the uc_product_features table (pfid, nid, fid and description). MySQL doesn't complain about the type difference (it just converts each value to numeric if necessary), but if there exists a Role Assignment feature whose pfid with the same id as the passed nid, it will be deleted in addition to the desired feature.

uc_roles_feature_delete is being called from this function:

function uc_product_feature_delete($pfid) {
  $feature = uc_product_feature_load($pfid);

  // Call the delete function for this product feature if it exists.
  $func = uc_product_feature_data($feature['fid'], 'delete');
  if (function_exists($func)) {
    $func($feature);
  }
  db_delete('uc_product_features')
    ->condition('pfid', $pfid)
    ->execute();

  return SAVED_DELETED;
}

The problem is that call to $func($feature), which is passing all of the product feature data to the function. If you're calling a function to delete a Product Feature, it makes sense that you're going to pass the id for the feature, not all of the data for it (particularly given that that's what uc_roles_feature_delete is expecting). I believe this call should be $func($pfid). After making this change, the deletion works correctly. Attached is a patch to make this change.

Comments

ben coleman’s picture

Issue summary: View changes
allartk’s picture

We had this error in some other modules like uc_coupons and uc_panes. Thanks for the fix!

tr’s picture

StatusFileSize
new1.51 KB

Nice catch, great error report. Sorry it took so long for this to come to my attention.

This issue also affects uc_file, which assumes it's getting the array not just the one value that uc_roles wants. This new patch takes care of both.

tr’s picture

Status: Needs review » Fixed

Committed.

  • TR committed baf3d62 on 7.x-3.x authored by Ben Coleman
    Issue #2235543 by Ben Coleman, TR: PDOException when deleting a Role...

  • TR committed 809f07b on 8.x-4.x
    D8 core change (https://www.drupal.org/node/2401615) broke uc_roles test...

  • TR committed dd2bcbc on 6.x-2.x authored by Ben Coleman
    Issue #2235543 by Ben Coleman, TR: PDOException when deleting a Role...

Status: Fixed » Closed (fixed)

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

Status: Closed (fixed) » Needs work

The last submitted patch, 3: 2235543.patch, failed testing.

tr’s picture

Status: Needs work » Closed (fixed)

Not sure why the testbot reopened this ...