MDL-46682 auth/db: Increase of chunk size and update change.
authorAdrian Greeve <adrian@moodle.com>
Wed, 6 Jul 2016 01:48:37 +0000 (09:48 +0800)
committerAdrian Greeve <adrian@moodle.com>
Wed, 6 Jul 2016 08:41:51 +0000 (16:41 +0800)
The update query was not checking the mnet auth id and could
have been updating the wrong entry.

auth/db/auth.php

index e9c21ec..b1fa091 100644 (file)
@@ -303,19 +303,19 @@ class auth_plugin_db extends auth_plugin_base {
             // Find obsolete users.
             if (count($userlist)) {
                 $remove_users = array();
-                // Oracle IN clause is limited to 1000 parameters. We need to chunk the SQL.
-                $userlistchunks = array_chunk($userlist , 999);
+                // All the drivers can cope with chunks of 10,000. See line 4491 of lib/dml/tests/dml_est.php
+                $userlistchunks = array_chunk($userlist , 10000);
                 foreach($userlistchunks as $userlistchunk) {
                     list($notin_sql, $params) = $DB->get_in_or_equal($userlistchunk, SQL_PARAMS_NAMED, 'u', false);
                     $params['authtype'] = $this->authtype;
-                    $sql = "SELECT u.*
+                    $sql = "SELECT u.id, u.username
                           FROM {user} u
                          WHERE u.auth=:authtype AND u.deleted=0 AND u.mnethostid=:mnethostid $suspendselect AND u.username $notin_sql";
                     $params['mnethostid'] = $CFG->mnet_localhost_id;
                     $remove_users = $remove_users + $DB->get_records_sql($sql, $params);
                 }
             } else {
-                $sql = "SELECT u.*
+                $sql = "SELECT u.id, u.username
                           FROM {user} u
                          WHERE u.auth=:authtype AND u.deleted=0 AND u.mnethostid=:mnethostid $suspendselect";
                 $params = array();
@@ -366,14 +366,15 @@ class auth_plugin_db extends auth_plugin_base {
             // Only go ahead if we actually have fields to update locally.
             if (!empty($updatekeys)) {
                 $update_users = array();
-                // Oracle IN clause is limited to 1000 parameters. We need to chunk the SQL.
-                $userlistchunks = array_chunk($userlist , 999);
+                // All the drivers can cope with chunks of 10,000. See line 4491 of lib/dml/tests/dml_est.php
+                $userlistchunks = array_chunk($userlist , 10000);
                 foreach($userlistchunks as $userlistchunk) {
                     list($in_sql, $params) = $DB->get_in_or_equal($userlistchunk, SQL_PARAMS_NAMED, 'u', true);
                     $params['authtype'] = $this->authtype;
+                    $params['mnethostid'] = $CFG->mnet_localhost_id;
                     $sql = "SELECT u.id, u.username
                           FROM {user} u
-                         WHERE u.auth=:authtype AND u.deleted=0 AND u.username {$in_sql}";
+                         WHERE u.auth = :authtype AND u.deleted = 0 AND u.mnethostid = :mnethostid AND u.username {$in_sql}";
                     $update_users = $update_users + $DB->get_records_sql($sql, $params);
                 }