Issue Details (XML | Word | Printable)

Key: MDL-11909
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Blocker Blocker
Assignee: Nicolas Connault
Reporter: Matt Campbell
Votes: 2
Watchers: 7
Operations

Add/Edit UI Mockup to this issue
If you were logged in you would be able to see more operations.
Moodle

assignment submissions can contain duplicates which causes problems during upgrade to new gradebook

Created: 26/Oct/07 12:53 AM   Updated: 16/Jul/08 04:13 PM
Component/s: Assignment, Gradebook
Affects Version/s: 1.9
Fix Version/s: 1.9, 2.0

File Attachments: 1. File grade_object.php (13 kB)
2. HTML File upg_20071025-1138.html (0.3 kB)

Environment: Debian Linux, PHP 4.4.4.8.4, MySQL 5.0.27

Database: MySQL
Participants: Karlene Clapp, Martin Dougiamas, Matt Campbell, Nicolas Connault, Paul Nijbakker, Petr Skoda (frankenstein) and Yu Zhang
Security Level: None
QA Assignee: Matt Campbell
Affected Branches: MOODLE_19_STABLE
Fixed Branches: MOODLE_19_STABLE, MOODLE_20_STABLE


 Description  « Hide
Testing upgrade from Moodle 1.8.2 (2007021520) to 1.9 Beta 2 (2007101500), get the error 'Found more than one record in fetch() !' when attempting to set up Assignment tables. I've attached the upgrade file.

Upgrade halts at this point and cannot proceed.



 All   Comments   Change History   Version Control      Sort Order: Ascending order - Click to sort in descending order
Matt Campbell added a comment - 26/Oct/07 01:25 AM
I turned debug on in /mod/assignment/upgrade.php and started this again, now get:

SELECT * FROM mdl_grade_grades WHERE itemid = '191' AND userid = '3751' ORDER BY id
Found more than one record in fetch() !

When I pull up mdl_grade_grades, I find two entries that meet this criteria.

I deleted the entry with the higher id and started again, got the error again - same itemid, different userid. Went into database and found several duplicates for itemid = 191, deleted the second entry on each duplicate.

Ran again, same error this time, but itemid = 190.

Continuing process - I'll comment back how it goes.

The only extra factor I can think of in this is that we ARE using GBPV2.


Matt Campbell added a comment - 26/Oct/07 09:49 PM
Only three courses out of over 700 had this issue, couldn't seem to find any factor that was unique just to them. Once I'd gone through all the mdl_grade_grades issues with the assignments, installation continued normally.

Yu Zhang added a comment - 29/Oct/07 11:28 AM
Hi Matt,

Are you able to provide a copy of your db before the upgrade to 1.9? That would help us to locate the problem... Also, are all the affected grade items assignments?

Cheers,

Yu


Matt Campbell added a comment - 29/Oct/07 09:16 PM
Problem was ONLY with assignments, all other graded activities went through just fine.

I've sent you an email for the copy of the database - please confirm that you have gotten the file.

Thanks,
Matt


Yu Zhang added a comment - 31/Oct/07 08:48 AM
Hi Matt, got your email, will take a look, cheers, Yu

Yu Zhang added a comment - 31/Oct/07 09:21 AM
I think most likely we are getting this from more than 1 record in assignment_submissions for the same assignment for the same user. This goes directly into grade_grades during upgrade. I had a similar report earlier, problem was in assignment as well. Currently there is no unique constraint for assignment_submissions nor grade_grades table. Should we at least enforce it in grade_grades db? And what should we do with Moodle 1.8 coming with multiple grades?

Petr Skoda (frankenstein) added a comment - 31/Oct/07 04:20 PM
Thanks for all info, I will try to add some code to prevent this type of problems...

Martin Dougiamas added a comment - 05/Nov/07 10:21 AM
There definitely should be a formal constraint on grade_grades ... Yu,can you add that?

Petr, can you look into the upgrade process and make it deal better with duplicates?


Petr Skoda (frankenstein) added a comment - 06/Nov/07 04:01 PM
assigning back to Yu, I can not find anything wrong and do not have data to replicate, thanks

Karlene Clapp added a comment - 07/Nov/07 12:17 AM
I had this exact issue and after manually deleting several of the duplicates, I wrote a patch in the lib/grade/grade_object.php file to delete the duplicates as it finds them. It's kind of a hack, but it has worked each time I've done an upgrade and prevents the constant stopping during the assignment module upgrade. I have attached the file. Each line I added has a comment with "KC".

Note: I used a global variable to store the $sql, but I'm sure there's a better way. This was just a quick fix, but you get the idea.

These are the two functions that were changed:

/**

  • Factory method - uses the parameters to retrieve matching instance from the DB.
  • @static final protected
  • @return mixed object insatnce or false if not found
    */
    function fetch_helper($table, $classname, $params) {
    // we have to do use this hack because of the incomplete OOP implementation in PHP4
    // in PHP5 we could do it much better
    if ($instances = grade_object::fetch_all_helper($table, $classname, $params)) {

if (count($instances) > 1) { // we should not tolerate any errors here - problems might appear later global $sql_delete; //KC added echo $sql_delete; //KC added $result_delete = mysql_query($sql_delete) or die(mysql_error()); //KC instead of saying there's an error, it deletes the duplicate and continues //error('Found more than one record in fetch() !'); }
return reset($instances);
} else { return false; }
}

/**
* Factory method - uses the parameters to retrieve all matching instances from the DB.
* @static final protected
* @return mixed array of object instances or false if not found
*/
function fetch_all_helper($table, $classname, $params) {
// we have to do use this hack because of the incomplete OOP implementation in PHP4
// in PHP5 we could do it much better
$instance = new $classname();

$classvars = (array)$instance;
$params = (array)$params;

$wheresql = array();

// remove incorrect params
foreach ($params as $var=>$value) {
if (!in_array($var, $instance->required_fields) and !array_key_exists($var, $instance->optional_fields)) { continue; }
if (is_null($value)) { $wheresql[] = " $var IS NULL "; } else { $value = addslashes($value); $wheresql[] = " $var = '$value' "; }
}

if (empty($wheresql)) { $wheresql = ''; } else { $wheresql = implode("AND", $wheresql); }

if ($datas = get_records_select($table, $wheresql, 'id')) {

$result = array();
foreach($datas as $data) { $instance = new $classname(); grade_object::set_properties($instance, $data); $result[$instance->id] = $instance; }

global $sql_delete; //KC added
//Added by KC 10/11/07 to fix upgrade duplication issue
$sql_delete = "Delete from mdl_" . $table . " where $wheresql LIMIT 1";

return $result;

} else { return false; } }
}


Yu Zhang added a comment - 08/Nov/07 09:49 AM
Hi guys,

I have tried to artificially add duplicate assignment_submission in 1.8, and tried an upgrade. Upgrade was fine, so I agree with Petr that this bit is not broken. To help us reproduce this problem we would really appreciate a copy of 1.8 dump with broken upgrades, so we can see what is going on. Please feel free to email me yu@moodle.com

Thanks,

Yu


Yu Zhang added a comment - 08/Nov/07 10:07 AM
I have put a unique constraint userid-itemid on grade_grades table.

Yu Zhang added a comment - 12/Nov/07 11:06 AM
I think this should no longer be a problem with key constraints in the db. Would still be nice if someone can post a broken db so we can see how it's broken. Cheers.

Matt Campbell added a comment - 20/Nov/07 11:08 PM
Yu, just thought I'd let you know that this is now working successfully, with both the database backup I encountered this issue with and more recent backups. I think the unique constraint may have taken care of it.

Thanks,
Matt


Paul Nijbakker added a comment - 16/Jul/08 03:16 PM
This problem still persists see http://tracker.moodle.org/browse/MDL-14124