yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.23k stars 6.91k forks source link

mssql empty strings changed to null for string type colums in 2.0.50 #20195

Closed axeltomasson closed 3 months ago

axeltomasson commented 3 months ago

What steps will reproduce the problem?

Read mssql nvarchar column of a database with db version less then 2017.

In https://github.com/yiisoft/yii2/commit/9d3c71d6a712a99f42ae1c5d588312f49514523a#diff-ea76a30d7da4b9fb69fe63d479c0764c4fd9bf99fbb859ba664ff0bc79a6bf8cR411

The function booleanTypeLegacy sets non abstract column type in last return statement ( for example nvarchar)

$column->type = $this->booleanTypeLegacy($column->size, $type);

What is the expected result?

Read empty string from mssql column of type nvarchar.

What do you get instead?

Read column value is null.

Additional info

Q A
Yii version 2.0.50
PHP version 8.3.7
Operating system

One way to fix would be to move function code directly into code where used:

411c411,419
<                     $column->type = $this->booleanTypeLegacy($column->size, $type);
---
>                     if ($column->size === 1 && ($type === 'tinyint' || $type === 'bit')) {
>                         $column->type = 'boolean';
>                     } elseif ($type === 'bit') {
>                         if ($column->size > 32) {
>                             $column->type = 'bigint';
>                         } elseif ($column->size === 32) {
>                             $column->type = 'integer';
>                         }
>                     }
819,840d826
<     /**
<      * Assigns a type boolean for the column type bit, for legacy versions of MSSQL.
<      *
<      * @param int $size column size.
<      * @param string $type column type.
<      *
<      * @return string column type.
<      */
<     private function booleanTypeLegacy($size, $type)
<     {
<         if ($size === 1 && ($type === 'tinyint' || $type === 'bit')) {
<             return 'boolean';
<         } elseif ($type === 'bit') {
<             if ($size > 32) {
<                 return 'bigint';
<             } elseif ($size === 32) {
<                 return 'integer';
<             }
<         }
< 
<         return $type;
<     }
terabytesoftw commented 3 months ago

You have time for a PR, could you add a test, thanks.

marcovtwout commented 3 months ago

@axeltomasson Could you clarify: is this a regression in 2.0.50 or was it also broken in 2.0.49?

axeltomasson commented 3 months ago

@axeltomasson Could you clarify: is this a regression in 2.0.50 or was it also broken in 2.0.49?

2.0.50, broke in https://github.com/yiisoft/yii2/commit/9d3c71d6a712a99f42ae1c5d588312f49514523a#diff-ea76a30d7da4b9fb69fe63d479c0764c4fd9bf99fbb859ba664ff0bc79a6bf8cR839

when booleanTypeLegacy started to return $type directly into $column->type