From 2ab686ee714eb9c171d841489d67a976a9f05338 Mon Sep 17 00:00:00 2001 From: Eloy Lafuente Date: Sun, 21 Mar 2010 19:36:50 +0000 Subject: [PATCH] MDL-21868 mssql generator - improve integer meta type detection + test --- lib/ddl/mssql_sql_generator.php | 22 ++++++++++++++++++++++ lib/ddl/simpletest/testddl.php | 13 +++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/ddl/mssql_sql_generator.php b/lib/ddl/mssql_sql_generator.php index 4dfdaa93e02..57ee52bde80 100644 --- a/lib/ddl/mssql_sql_generator.php +++ b/lib/ddl/mssql_sql_generator.php @@ -321,6 +321,28 @@ class mssql_sql_generator extends sql_generator { $typechanged = false; } + /// If the new field (and old) specs are for integer, let's be a bit more specific diferentiating + /// types of integers. Else, some combinations can cause things like MDL-21868 + if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER && $oldmetatype == 'I') { + if ($xmldb_field->getLength() > 9) { // Convert our new lenghts to detailed meta types + $newmssqlinttype = 'I8'; + } else if ($xmldb_field->getLength() > 4) { + $newmssqlinttype = 'I'; + } else { + $newmssqlinttype = 'I2'; + } + if ($metac->type == 'bigint') { // Convert current DB type to detailed meta type (our metatype is not enough!) + $oldmssqlinttype = 'I8'; + } else if ($metac->type == 'smallint') { + $oldmssqlinttype = 'I2'; + } else { + $oldmssqlinttype = 'I'; + } + if ($newmssqlinttype != $oldmssqlinttype) { // Compare new and old meta types + $typechanged = true; // Change in meta type means change in type at all effects + } + } + /// Detect if we are changing the length of the column, not always necessary to drop defaults /// if only the length changes, but it's safe to do it always if ($xmldb_field->getLength() == $oldlength) { diff --git a/lib/ddl/simpletest/testddl.php b/lib/ddl/simpletest/testddl.php index d4b7500e64f..ae9d6da126b 100755 --- a/lib/ddl/simpletest/testddl.php +++ b/lib/ddl/simpletest/testddl.php @@ -815,14 +815,23 @@ class ddl_test extends UnitTestCase { $this->assertEqual($columns['grade']->meta_type, 'N'); //TODO: chek the rest of attributes - // change integer field from 10 to 6 + // change integer field from 10 to 2 $field = new xmldb_field('userid'); - $field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $field->set_attributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); $dbman->change_field_precision($table, $field); $columns = $DB->get_columns('test_table1'); $this->assertEqual($columns['userid']->meta_type, 'I'); //TODO: chek the rest of attributes + // change the column from integer (2) to integer (6) (forces change of type in some DBs) + $field = new xmldb_field('userid'); + $field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, null, null, null); + $dbman->change_field_precision($table, $field); + // column is integer 6 null default null now + $columns = $DB->get_columns('test_table1'); + $this->assertEqual($columns['userid']->meta_type, 'I'); + //TODO: chek the rest of attributes + // insert one record with 6-digit field $record = new object(); $record->course = 10;