-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Boolean MySQL migration vs. auto-model-attribute-typecast inconsistency #19808
Comments
I would check typecasting process. |
Maybe we should have the same condition in MySQL yii2/framework/db/sqlite/Schema.php Line 333 in 5f3d36e
|
The change seems correct to me, but it will be BC, since it currently returns integer. yii2/tests/framework/db/SchemaTest.php Line 431 in 5f3d36e
|
If you look at the mysql documentation, you can see that this data type can be -128...127 signed and 0...255 unsigned. tinyint(1) doesn't equal the boolean type and this change will potentially break a lot of projects |
Why would you use |
Document yii2/framework/db/QueryBuilder.php Line 1183 in 6804fbe
|
I also stumbled upon this ... and I asked myself the following question: Why did |
For new projects this would be fine, but I think @VladimirRakovich comment was about existing projects, where model values are now |
yiisoft/yii2-gii#440 (comment) Why did you change your mind :) ? |
I think this is because of MySQL docs where it was mentioned as a preferred implementation of boolean column (I hope I remember it correctly and not making it up). |
This is an old bug, which was fixed according to the Yii2 documentation. |
My questions stands also for existing projects - why would you specify length as |
Yeah, but this also works the other way :) |
It's here: https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
|
Do we have a way to overwrite this detected type in somewhat convenient manner? I still think that |
IMHO it is simply wrong to assume in the schema that EVERY tinyint col (no matter if with or without length) is a boolean. this is valid (My)SQL and the
And for MySQL the length param for tinyint has no effect. The possible range of values is only dependent on signed or unsigned. |
If you are right in this case, we can fix it, we just have to define whether the type |
How? Column schema does not check what values are stored in this column. |
yii2/framework/db/mysql/Schema.php Line 282 in 6804fbe
|
And even if you look at what is stored so far, how is schema supposed to know what i want to store tomorrow? |
That is why I propose a way to define types of columns in config and keep current type detection as a fallback. For me this guessing PHP type from DB schema was always a bit too magic, I would prefer to keep these definitions as part of the code with explicitly defined defaults or types. |
Example and discussion from a non-PHP project: metabase/metabase#3506 tldr: They implemented a driver flag We have the manual saying |
I just did a test for the boolean column, it is a Yii2 mapping, which phpTypeCast will always return a boolean value, be it tinyint(1) or bit(1). |
@terabytesoftw Still valid SQL but still NO boolean col:
To be clear: i understand the problem, that MySQL has no real boolean column type, and that the docs state that boolean "is" a tinyint(1), but the assumption the other way around, that every tinyint(1) is a boolean is simply wrong. |
related: |
@rob006 How would that look like? Also related in general: |
|
After investigating all the yii2 issues, i also saw that yii2 supports legacy versions of Mysql in its versions 5, if it is correct that tinyint(1) would be synonymous with boolean, but not tinyint(1) unsigned which would be integer, then for me two solutions. 1.- Check the case when tinyint is unsigned, and it will work fine. Example: https://mysqlconnector.net/api/mysqlconnector/mysqlconnectionstringbuilder/treattinyasboolean/ 2.- Let's simply reverse the commit, and this problem should never have existed. It's my two cents. |
I will look into it and try to propose a solution. |
btw in Yii3, we use |
see: #19808 (comment) Why here, because of this one word synonyms from the doc, it is pretended that there is a defined column data type Just open a MySQL and try it yourself what you can write into a tiniyint field and what you get out of it. If you still think it's a good idea to always cast the value from a tinyint(1) column to the php type boolean, go ahead. This would be obviously a bug and will potentially break perfectly valid code, but hey, we would have a boolean or at least we could pretend that it is so. I'm out. |
The first thing i must clarify is that, i have not said that there is a boolean type in MYSQL, simply by not having a specific type a mapping is made, and this is the Framework specification, you can consult QueryBuilder in getColumnType, it simply refers me to the existing documentation, keep in mind that this also handles legacy versions of mysql, where in the previous documentation it said that tinyint(1) was synonymous with boolean, i'm not making it up. yii2/framework/db/QueryBuilder.php Line 1183 in 6804fbe
|
How would the framework do that? Aren't you able to set In a project I have columns defined in migration with |
The framework works this way in this case, you can read the code and documentation, where it clearly says that tinyint(1) works with 0 for false, 1 for true, the framework does the typeCast, this is how it works for this case, in Yii3 to eliminate ambiguity we use bit(1), and that is why i asked here how the best way to solve it would be, since here applying bit(1) would be BC, but it eliminates the ambiguity. |
https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-19.html
|
Yes, i agree, this commit should be reverted. |
TINYINT(1)
column is created using$this->boolean()
in migrationBIT(1)
column is type-casted tobool
during model population (TINYINT(1)
column is type-casted asinteger
)The text was updated successfully, but these errors were encountered: