From 6bce418d282bbb2d96d537fcaaf40f5ce76d34c4 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 8 Jan 2014 18:22:20 +0000 Subject: [PATCH] MDL-43246 question engine: avoid order-by id. This was breaking with oracle master/master replication. Fortunately all the places that needed to be changed were private to datalib.php. There is still some ordering by id there, but only places where we want a consitent, rather than meaningful, order, so that is OK. The queries changed by this patch all have subqueries in aggregate queries that pull out the latest step for a question_attempt. Those queries used to look for MAX(id) but now they look for MAX(sequencenumber). This is equivalent (for databases where ids always increase with time, except for auto-saved steps. In the past, an auto-saved step might have been considered latest. Now the latest step will always be one that has been properly processed. You can aruge that this change is an improvement. Anyway, it is a moot point. All these queries are only used in reports which are run on completed attempts, where there will not be any autosaved data. --- question/engine/datalib.php | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/question/engine/datalib.php b/question/engine/datalib.php index 110012c7675..27287f36c85 100644 --- a/question/engine/datalib.php +++ b/question/engine/datalib.php @@ -390,8 +390,8 @@ SELECT qas.userid FROM {$qubaids->from_question_attempts('qa')} -JOIN {question_attempt_steps} qas ON - qas.id = {$this->latest_step_for_qa_subquery()} +JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id + AND qas.sequencenumber = {$this->latest_step_for_qa_subquery()} WHERE {$qubaids->where()} AND @@ -428,8 +428,8 @@ SELECT COUNT(1) AS numattempts FROM {$qubaids->from_question_attempts('qa')} -JOIN {question_attempt_steps} qas ON - qas.id = {$this->latest_step_for_qa_subquery()} +JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id + AND qas.sequencenumber = {$this->latest_step_for_qa_subquery()} JOIN {question} q ON q.id = qa.questionid WHERE @@ -537,8 +537,8 @@ SELECT 1 FROM {$qubaids->from_question_attempts('qa')} -JOIN {question_attempt_steps} qas ON - qas.id = {$this->latest_step_for_qa_subquery()} +JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id + AND qas.sequencenumber = {$this->latest_step_for_qa_subquery()} JOIN {question} q ON q.id = qa.questionid WHERE @@ -599,8 +599,8 @@ SELECT COUNT(1) AS numaveraged FROM {$qubaids->from_question_attempts('qa')} -JOIN {question_attempt_steps} qas ON - qas.id = {$this->latest_step_for_qa_subquery()} +JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id + AND qas.sequencenumber = {$this->latest_step_for_qa_subquery()} WHERE {$qubaids->where()} @@ -914,10 +914,11 @@ ORDER BY // NULL total into a 0. return "SELECT COALESCE(SUM(qa.maxmark * qas.fraction), 0) FROM {question_attempts} qa - JOIN {question_attempt_steps} qas ON qas.id = ( - SELECT MAX(summarks_qas.id) - FROM {question_attempt_steps} summarks_qas - WHERE summarks_qas.questionattemptid = qa.id + JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id + AND qas.sequencenumber = ( + SELECT MAX(summarks_qas.sequencenumber) + FROM {question_attempt_steps} summarks_qas + WHERE summarks_qas.questionattemptid = qa.id ) WHERE qa.questionusageid = $qubaid HAVING COUNT(CASE @@ -958,15 +959,15 @@ ORDER BY {$alias}qas.userid FROM {$qubaids->from_question_attempts($alias . 'qa')} - JOIN {question_attempt_steps} {$alias}qas ON - {$alias}qas.id = {$this->latest_step_for_qa_subquery($alias . 'qa.id')} + JOIN {question_attempt_steps} {$alias}qas ON {$alias}qas.questionattemptid = {$alias}qa.id + AND {$alias}qas.sequencenumber = {$this->latest_step_for_qa_subquery($alias . 'qa.id')} WHERE {$qubaids->where()} ) $alias", $qubaids->from_where_params()); } protected function latest_step_for_qa_subquery($questionattemptid = 'qa.id') { return "( - SELECT MAX(id) + SELECT MAX(sequencenumber) FROM {question_attempt_steps} WHERE questionattemptid = $questionattemptid )";