The attached test is written and so far only tested for SQLite. Even so, some methods are not yet tested and some could use more. And yet, this is more testing of Schema API than we have now (which is zero).

Comments

chx’s picture

StatusFileSize
new9.49 KB

Now, this fixes a bug in mysql schema.inc (sorry for the many whitespace cleanups, the fix is === null instead of ==) and with the strict mode patch i submitted it actually passes with mysql as well. Strict mode at http://drupal.org/node/303054

fgm’s picture

Status: Needs review » Needs work

As you said, it doesn't pass without the MySQL strict fix. However, IMHO the problem is not with the test but with the DB API.

What happens is that you start with:

   $table_specification = array(
      'fields' => array(
        'id'  => array(
          'type' => 'int',
          'not null' => TRUE,
          'default' => NULL,
        ),
        'test'  => array(
          'type' => 'int',
          'not null' => TRUE,
        ),
      ),
    );

but then when the table is created in MySQL, the NULL default on field "id" is not passed during creation. And you get a field "id" like "`test` int(11) NOT NULL", without a default, although the test requests a NULL default. This comes from DatabaseSchema_mysql->createFieldSql(), which tests for:

    if (isset($spec['default'])) {
      if (is_string($spec['default'])) {
        $spec['default'] = "'" . $spec['default'] . "'";
      }
      $sql .= ' DEFAULT ' . $spec['default'];
    }

which causes it to ignore NULL defaults. The problem could be removed by using something stricter like:

    if (array_key_exists('default', $spec)) {
      if (is_string($spec['default'])) {
        $spec['default'] = "'" . $spec['default'] . "'";
      } elseif (is_null($spec['default'])) {
        $spec['default'] = 'NULL';
      }
     
      $sql .= ' DEFAULT ' . $spec['default'];
    }

Now, if you use this, the table creation is simply rejected, and the test cannot proceed to the subsequent errors. OTOH, I suppose it may break other code elsewhere which uses such DDL, and which should probably be fixed.

The test itself, though, has another potential problem: if db_create_table fails, none of the subsequent tests can proceed, so it might make more sense to drop out of the test if the initial table creation fails. When testing interactively, this is not an issue, but since each test is costly, for automated testing it could make more sense to fail early than to let a full series of failure happen. But this is more a policy than a technical issue, and I'm not (yet ?) aware of the policy choices in that regard.

chx’s picture

Status: Needs work » Needs review
StatusFileSize
new9.56 KB

Oh so my little test already caught two MySQL schema bugs? That's good! Enrolled the default NULL fix and changed the test table definiton not to have a default NULL on a NOT NULL column (what I was thinking??)

fgm’s picture

Out of sheer curiosity, why did you replace is_null($spec['default']) by !isset($spec['default']) ?

It seems to give the same result in this specific case, although it is maybe a bit harder to read because it is less specific; maybe it's a core style guide issue ?

This being said, i think it would also make sense to ask for that NULL default on non-NULL column, and make sure an error is indeed returned and the table is not created. It could make another case for the test.

Anonymous’s picture

Status: Needs review » Needs work

The last submitted patch failed testing.

damien tournoud’s picture

Status: Needs work » Needs review
StatusFileSize
new3.79 KB

Cleaned-up the schema API test (and only it), the fix for drivers should go in a different issue, IMO.

Anonymous’s picture

Status: Needs review » Needs work

The last submitted patch failed testing.

damien tournoud’s picture

Status: Needs work » Needs review
Anonymous’s picture

Status: Needs review » Needs work

The last submitted patch failed testing.

damien tournoud’s picture

StatusFileSize
new3.8 KB

Fixed missing {} in the queries.

damien tournoud’s picture

The fix for the MySQL implementation is now in a separate issue: #333499: Fix handling of NULL default values in MySQL schema API

damien tournoud’s picture

Status: Needs work » Needs review
StatusFileSize
new4.01 KB

Improved version: we now check that the previously inserted rows are kept when changing the definition of a field (this is useful because the SQLite implementation migrate the data to a new table because there is limited ALTER TABLE support on that engine).

dries’s picture

Status: Needs review » Fixed

Committed to CVS HEAD. Other test to follow soon.

damien tournoud’s picture

@Dries: apparently you committed #10, not #12.

damien tournoud’s picture

Status: Fixed » Needs review
StatusFileSize
new5.19 KB

Here is a patch against HEAD.

damien tournoud’s picture

StatusFileSize
new5.09 KB

Latest patch had a strange $Id$.

dries’s picture

Status: Needs review » Fixed

Thanks for the prompt help. Committed to CVS HEAD. Thanks.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.