From 68575baff3e75bf540104c7eddae80a047b90a0a 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 ba757e6d44e..9694851a77f 100644 --- a/question/engine/datalib.php +++ b/question/engine/datalib.php @@ -400,8 +400,8 @@ SELECT {$fields} 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 @@ -438,8 +438,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 @@ -547,8 +547,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 @@ -609,8 +609,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()} @@ -926,10 +926,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 @@ -971,15 +972,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 )";