From 12ed4706557d978b0f43c3b8ab8cf454ebb590ac Mon Sep 17 00:00:00 2001 From: Angie Byron <webchick@24967.no-reply.drupal.org> Date: Sat, 30 Jan 2010 02:56:32 +0000 Subject: [PATCH] #522786 by stormsweeper: Fixed PostgreSQL numeric check needs to happen after precision check in schema generation. --- includes/database/pgsql/schema.inc | 7 ++-- modules/simpletest/tests/schema.test | 54 ++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/includes/database/pgsql/schema.inc b/includes/database/pgsql/schema.inc index 578c074bb89c..d2e837d1e719 100644 --- a/includes/database/pgsql/schema.inc +++ b/includes/database/pgsql/schema.inc @@ -147,9 +147,6 @@ protected function createFieldSql($name, $spec) { if ($spec['type'] == 'serial') { unset($spec['not null']); } - if (!empty($spec['unsigned'])) { - $sql .= " CHECK ($name >= 0)"; - } if (in_array($spec['type'], array('varchar', 'char', 'text')) && isset($spec['length'])) { $sql .= '(' . $spec['length'] . ')'; @@ -158,6 +155,10 @@ protected function createFieldSql($name, $spec) { $sql .= '(' . $spec['precision'] . ', ' . $spec['scale'] . ')'; } + if (!empty($spec['unsigned'])) { + $sql .= " CHECK ($name >= 0)"; + } + if (isset($spec['not null']) && $spec['not null']) { $sql .= ' NOT NULL'; } diff --git a/modules/simpletest/tests/schema.test b/modules/simpletest/tests/schema.test index 637bc0b6fcfe..dbc8154a2bce 100644 --- a/modules/simpletest/tests/schema.test +++ b/modules/simpletest/tests/schema.test @@ -139,4 +139,58 @@ class SchemaTestCase extends DrupalWebTestCase { $node_fake_index = Database::getConnection()->schema()->indexExists('node', 'node_not_exists'); $this->assertFalse($node_fake_index, t('Fake index does not exists')); } + + /** + * Tests creating unsigned columns and data integrity thereof. + */ + function testUnsignedColumns() { + // First create the table with just a serial column. + $table_name = 'unsigned_table'; + $table_spec = array( + 'fields' => array('serial_column' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE)), + 'primary key' => array('serial_column'), + ); + $ret = array(); + db_create_table($ret, $table_name, $table_spec); + + // Now set up columns for the other types. + $types = array('int', 'float', 'numeric'); + foreach ($types as $type) { + $column_spec = array('type' => $type, 'unsigned'=> TRUE); + if ($type == 'numeric') { + $column_spec += array('precision' => 10, 'scale' => 0); + } + $column_name = $type . '_column'; + $table_spec['fields'][$column_name] = $column_spec; + db_add_field($ret, $table_name, $column_name, $column_spec); + } + + // Finally, check each column and try to insert invalid values into them. + foreach($table_spec['fields'] as $column_name => $column_spec) { + $this->assertTrue(db_column_exists($table_name, $column_name), t('Unsigned @type column was created.', array('@type' => $column_spec['type']))); + $this->assertFalse($this->tryUnsignedInsert($table_name, $column_name), t('Unsigned @type column rejected a negative value.', array('@type' => $column_spec['type']))); + } + } + + /** + * Tries to insert a negative value into columns defined as unsigned. + * + * @param $table_name + * The table to insert + * @param $column_name + * The column to insert + * @return + * TRUE if the insert succeeded, FALSE otherwise + */ + function tryUnsignedInsert($table_name, $column_name) { + try { + db_insert($table_name) + ->fields(array($column_name => -1)) + ->execute(); + return TRUE; + } + catch (Exception $e) { + return FALSE; + } + } } -- GitLab