If you delete submissions, some submissions end up with missing early fields, with only later fields showing up. I traced the problem to webform_get_submissions() in webform_submissions.inc. It makes the assumption that rows returned by the query will be grouped by sid, but this assumption doesn't always hold true. MySQL can return the rows out of order once submissions have been deleted and others have been edited. I was able to fix it by using:

if (!isset($submissions[$row->sid])) {

in place of:

if ($row->sid != $previous) {

in the while loop. The existing logic was overwriting the old entry in $submissions whenever data rows were encountered out-of-order with respect to $sid.

If you want to try to reproduce the original problem, try working with a database with a single webform and a lot of fields, put in a couple hundred submissions, delete a few, and then edit a dozen or so, then add a few new submissions. The result of doing that in my case was mangled download data for a dozen or so submissions. I think MySQL was choosing to execute the query via table scan on webform_submitted_data, and there were rows out of sid order in there.

Comments

shane birley’s picture

It would appear this may be happening with version 2.1.3 on Drupal 5 as well.

Herman Hiddema’s picture

I'm seeing the same thing. The table view works fine, but the downloaded csv file is missing data.

quicksketch’s picture

Status: Active » Fixed

I've fixed this with a different approach, simply ordering the results during the SQL query. I think it is like you said, editing the submissions causes rows to be moved out of order, so they don't come out in the order Webform was expecting.

  if (is_array($header)) {
    $query .= tablesort_sql($header);
    if (!isset($header[0]['sort'])) {
      $query .= ', sid ASC';
    }
    $query .= ', cid ASC, no ASC';
  }
  else {
    $query .= ' ORDER BY sid ASC, cid ASC, no ASC';
  }

The fix is in the latest development version and I'll include it in the 2.2 release.

pje’s picture

Glad it's being fixed. I'm curious, though; why order the results? Clearly MySQL thinks it's faster to return them out of order, and they're all going into the same array anyway, so the actual order doesn't matter a bit. All that's needed is to not erase partial entries... and it's a lot less code, too. Or is there some drawback to using isset() on arrays?

quicksketch’s picture

The ordering allows the if ($row->sid != $previous) { logic to work correctly. Although your approach of if (!isset($submissions[$row->sid])) { would work in most situations, there could be some weirdness where a submission was partially updated, causing the newer part of the submission to not be added after the older part was already loaded into the $submissions array.

So in short, yes it'd be faster to not order the results at all, but in most situations the results would make more sense if they were ordered by the way they were submitted.

pje’s picture

What do you mean by "partially updated"? Do you mean, if it was being updated while the data was being loaded?

Anonymous’s picture

Status: Fixed » Closed (fixed)

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