Fixed Error: xxxxx already exists in table, but cannot change length

Jon W

Well-known member
Affected version
2.1.0
If a setup file tries to create a new boolean column and that column already exists, it produces the following error:
xxxxx already exists in table, but cannot change length
where xxxxx is the column name.

This happens even if the column is already set to size 3 or 4, but the code is checking whether it is size 1, so it fails.

The code is on line 128-132 of XF/Db/Schema/Column:
Code:
            case 'BOOL':
            case 'BOOLEAN':
                $type = 'TINYINT';
                $length = 1;
                break;

It would probably be better to set this to 4.
 
Wouldn't that be the correct error since a boolean is 0 or 1 and a TINYINT with a size of 1?

Maybe I'm not understanding why a boolean would have a size greater than 1.

That and I can't imagine why you would be creating a column that already exists. ;)
 
Hmm... I haven't run across that. I'll keep an eye open for it.
I see you always explicitly set the column size to 1 in your add-ons, so that makes sense that you wouldn't have noticed.

The default value for a tinyint is 4 though, even if you set the column type to 'bool' or 'boolean' (which then uses tinyint).
 
I see you always explicitly set the column size to 1 in your add-ons, so that makes sense that you wouldn't have noticed.

The default value for a tinyint is 4 though, even if you set the column type to 'bool' or 'boolean' (which then uses tinyint).
Now that is interesting. Just did a test using BOOL as the column type and it does set the size to 4. Odd, but it does happen.
 
I see you always explicitly set the column size to 1 in your add-ons, so that makes sense that you wouldn't have noticed.
Doing some tests, even that doesn't work any more.
Code:
$table->addColumn('column_name', 'TINYINT', 1)->setDefault(0);
Results in a size of 3.
 
Thank you for reporting this issue. It has now been resolved and we are aiming to include it in a future XF release (2.1.1).

Change log:
Don't set a length when setting up boolean columns in the schema manager as we don't actually output this for integer types.
Any changes made as a result of this issue being resolved may not be rolled out here until later.
 
Just as a note, I couldn't actually reproduce the issue here directly (using the schema manager to create the column and then re-running the alter), though I can see why it's incorrect as we implicitly ignore lengths on integer fields because they don't actually work as lengths.

But that's also the reason I couldn't reproduce it -- the comparison code (which is just above the length check) should normally detect them as equal. I'd have to guess there was something additional that was different about the columns.
 
While this has nothing to do with the bug reported, and I agree that an int value is an int value, ie: a tinyint is -128 to 127 or 0 to 255, the length set in the database is a good visual reminder of what should be in that column.

IE for tinyint size...
1 - Boolean or 0 to 9
2 - 0 to 99
3 - 0 to 255
4 - Don't care

In other words, if I have the size set to 1 and there's a value of 78 in there, I know without a doubt something is wrong somewhere.

At least that's what I've always used them for. ;)
 
Last edited:
Top Bottom