Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-85721

Subquestions of a qtype_multianswer question are unnecessarily duplicated when duplicating a quiz that uses them

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • None
    • 4.5.4, 4.5.5, 5.0, 5.1, 4.5.6
    • Backup, Questions
    • MOODLE_405_STABLE, MOODLE_500_STABLE, MOODLE_501_STABLE
    • MDL-85721_405_STABLE
    • MDL-85721_500_STABLE
    • MDL-85721_main
    • Hide

      These steps have 3 stages. First, we run through the reproduction steps without the fix in place, to generate some duplicate questions. Next, we apply the fix, and run the task the clean up the duplicates. Finally, we confirm no more duplicates are created.

      Stage 1

      1. On a fresh Moodle site, create a new course called "Course 1"
      2. Go to the course's question bank

      • On Moodle 4.5: Go to More > Question bank
      • On 5.0+, Go to More > Question bank, press the button to create the default question bank, and follow the link.

      3. Click "Create a new question" and select "Embedded answers (Cloze)".
      4. Give the question the name "Multianswer" and enter the following question text:

      <p>Complete the sentences with the correct European capital city.</p>
      <p>The capital of France is {1:MULTICHOICE:London~Madrid~=Paris~Rome}.</p>
      

      And save.

      4. In the database, confirm that there are now two elements in the table question, question_versions, question_bank_entries. One row in question_multianswer. One row in qtype_multichoice_options.
      5. In the question bank, expand the "Edit" menu for the "Multianswer" question and select "Edit question"
      5. Edit the question text, changing MULTICHOICE to SHORTANSWER and save.
      6. In the database, Confirm that there are now four rows in the table question and question_versions, still two rows in the table question_bank_entries, two rows in question_multianswer, one row in qtype_shortanswer_options, but the row in qtype_multichoice_options has been deleted.
      7. On the course page, turn editing mode on and add a new quiz called "Multianswer quiz".
      8. Enter the quiz, go to the "Questions" tab, and select "Add" > "From question bank"
      9. Select the question from the question bank

      • On 4.5, change the category filter to the "Default for Course 1 question bank" category and apply filters
      • On 5.0+, click "Switch banks" and select the course question bank.

      10. Check the checkbox next to the "Multianswer" question and add it to the quiz.
      11. On the course page, select the action menu next to the quiz and select "Duplicate"
      12. Confirm the quiz is duplicated.
      13. In the database confirm there is an additional record in each of the question, question_versions and question_bank_entries tables.
      14. On the course page, select the action menu next to the quiz and select "Duplicate" again.
      15. Confirm the quiz is duplicated again.
      16. In the database confirm there is are 2 additional records (on top of the additional one from step 13) in each of the question, question_versions and question_bank_entries tables.

      Stage 2

      17. Apply the fix for the version of Moodle you are testing, and run the upgrade.
      18. Run the cron, or the ad-hoc task runner: `php admin/cli/adhoc_task.php --execute`
      19. Confirm that the `qtype_multianswer\task\cleanup_duplicate_subquestions` task is run, an reports that it found 1 subquestion with duplicates.
      20. In the database confirm the additional records from steps 13 and 16 are now gone.

      Stage 3.

      21. On the course page, select the action menu next to the quiz and select "Duplicate" again.
      22. Confirm the quiz is duplicated again.
      23. In the database confirm there are no additional records in each of the question, question_versions and question_bank_entries tables.

      Show
      These steps have 3 stages. First, we run through the reproduction steps without the fix in place, to generate some duplicate questions. Next, we apply the fix, and run the task the clean up the duplicates. Finally, we confirm no more duplicates are created. Stage 1 1. On a fresh Moodle site, create a new course called "Course 1" 2. Go to the course's question bank On Moodle 4.5: Go to More > Question bank On 5.0+, Go to More > Question bank, press the button to create the default question bank, and follow the link. 3. Click "Create a new question" and select "Embedded answers (Cloze)". 4. Give the question the name "Multianswer" and enter the following question text: <p>Complete the sentences with the correct European capital city.< /p > <p>The capital of France is {1:MULTICHOICE:London~Madrid~=Paris~Rome}.< /p > And save. 4. In the database, confirm that there are now two elements in the table question, question_versions, question_bank_entries. One row in question_multianswer. One row in qtype_multichoice_options. 5. In the question bank, expand the "Edit" menu for the "Multianswer" question and select "Edit question" 5. Edit the question text, changing MULTICHOICE to SHORTANSWER and save. 6. In the database, Confirm that there are now four rows in the table question and question_versions, still two rows in the table question_bank_entries, two rows in question_multianswer, one row in qtype_shortanswer_options, but the row in qtype_multichoice_options has been deleted. 7. On the course page, turn editing mode on and add a new quiz called "Multianswer quiz". 8. Enter the quiz, go to the "Questions" tab, and select "Add" > "From question bank" 9. Select the question from the question bank On 4.5, change the category filter to the "Default for Course 1 question bank" category and apply filters On 5.0+, click "Switch banks" and select the course question bank. 10. Check the checkbox next to the "Multianswer" question and add it to the quiz. 11. On the course page, select the action menu next to the quiz and select "Duplicate" 12. Confirm the quiz is duplicated. 13. In the database confirm there is an additional record in each of the question, question_versions and question_bank_entries tables. 14. On the course page, select the action menu next to the quiz and select "Duplicate" again. 15. Confirm the quiz is duplicated again. 16. In the database confirm there is are 2 additional records (on top of the additional one from step 13) in each of the question, question_versions and question_bank_entries tables. Stage 2 17. Apply the fix for the version of Moodle you are testing, and run the upgrade. 18. Run the cron, or the ad-hoc task runner: `php admin/cli/adhoc_task.php --execute` 19. Confirm that the `qtype_multianswer\task\cleanup_duplicate_subquestions` task is run, an reports that it found 1 subquestion with duplicates. 20. In the database confirm the additional records from steps 13 and 16 are now gone. Stage 3. 21. On the course page, select the action menu next to the quiz and select "Duplicate" again. 22. Confirm the quiz is duplicated again. 23. In the database confirm there are no additional records in each of the question, question_versions and question_bank_entries tables.
    • Hide

      Code verified against automated checks.

      Checked MDL-85721 using repository: https://github.com/marxjohnson/moodle.git

      More information about this report

      Built on: Fri Jun 13 08:48:22 UTC 2025

      Show
      Code verified against automated checks. Checked MDL-85721 using repository: https://github.com/marxjohnson/moodle.git MOODLE_405_STABLE (0 errors / 0 warnings) [branch: MDL-85721_405_STABLE | CI Job ] MOODLE_500_STABLE (0 errors / 0 warnings) [branch: MDL-85721_500_STABLE | CI Job ] main (0 errors / 0 warnings) [branch: MDL-85721_main | CI Job ] More information about this report Built on: Fri Jun 13 08:48:22 UTC 2025
    • Show
      Launching automatic jobs for branch MDL-85721 _405_STABLE https://ci.moodle.org/view/Testing/job/DEV.02%20-%20Developer-requested%20PHPUnit/19684/ PHPUnit (sqlsrv) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/67308/ Behat (NonJS - boost and classic) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/67309/ Behat (Firefox - boost) Launching automatic jobs for branch MDL-85721 _500_STABLE https://ci.moodle.org/view/Testing/job/DEV.02%20-%20Developer-requested%20PHPUnit/19685/ PHPUnit (sqlsrv) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/67310/ Behat (NonJS - boost and classic) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/67311/ Behat (Firefox - boost) Launching automatic jobs for branch MDL-85721 _main https://ci.moodle.org/view/Testing/job/DEV.02%20-%20Developer-requested%20PHPUnit/19686/ PHPUnit (sqlsrv) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/67312/ Behat (NonJS - boost and classic) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/67313/ Behat (Firefox - boost) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/67314/ Behat (Firefox - classic) https://ci.moodle.org/view/Testing/job/DEV.01%20-%20Developer-requested%20Behat/67315/ App tests (stable app version) Built on: Thu Jun 12 20:25:20 UTC 2025

      On Friday after an error when restoring a course we found out we have some multianswer questions with an insane amount of subquestions.

      SELECT parent, COUNT(*) as howmany
      FROM {question}
      WHERE parent > 0
      GROUP BY parent
      HAVING howmany > 1
      

      returned lines with counts above 10000, peaking with 41990 !!!

      Investigating where this comes from we were able to indentify an error, which is still present in the current 5.1dev (Build: 20250605):

      Steps to reproduce

      • In an empty vanilla Moodle (using 5.1dev (Build: 20250605) but already present in 4.5)
      • create an multianswer (embedded - cloze) question:

      <p>Complete the sentences with the correct European capital city.</p>
      <p>The capital of France is {1:MULTICHOICE:London~Madrid~=Paris~Rome}.</p>
      

      And save.

      • Confirmt that there are now two elements in the table question, question_versions, question_bank_entries. One row in question_multianswer. One row in qtype_multichoice_options.
      • Edit the question changing MULTICHOICE to SHORTANSWER and save.
      • Confirm that there are now four rows in the table question and question_versions, still two rows in the table question_bank_entries, two rows in question_multianswer, one row in qtype_shortanswer_options and - surprisingly - no row anymore in the table qtype_multichoice_options.
      • Create a quiz activity and add this question to the quiz.
      • Duplicate the quiz.
      • Confirm that contrary to what expected, a new record was created in each of the tables question, question_versions, question_bank_entries.
      • Duplicate the quiz activity a second time
      • Confirm that this time two new records were created in each of the tables question, question_versions, question_bank_entries.

      From now on, each time the quiz activity is duplicated, the number of new records created in these three tables will carry on growing exponentially.

      Analysis

      With the Xdebug we traced down the creation of the new question to line 700 of backup/utils/dbops/restore_dbops.class.php:

      $matchqid = $questioncache[$question->questionhash];
      

      For the multichoice subquestion from v1 of the question the hash does not match and this triggers the creation of a new question.

      I am not sure yet why and if this is a regression caused by MDL-83541, could it be related to the fact that the entry in qtype_multichoice_options is removed when editing the question and changing its type, although the questions still exists as v1?

            marxjohnson Mark Johnson
            ManeggiaP Paola Maneggia
            Paola Maneggia Paola Maneggia
            Votes:
            3 Vote for this issue
            Watchers:
            11 Start watching this issue

              Created:
              Updated:

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0 minutes
                0m
                Logged:
                Time Spent - 1 minute
                1m

                  Error rendering 'clockify-timesheets-time-tracking-reports:timer-sidebar'. Please contact your Jira administrators.