mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 14:46:19 +08:00 
			
		
		
		
	Fixes #14367: In yii\db\mysql\QueryBuilder added support fractional seconds for time types for MySQL >= 5.6.4
				
					
				
			This commit is contained in:
		
				
					committed by
					
						
						Alexander Makarov
					
				
			
			
				
	
			
			
			
						parent
						
							5d7c5f8ae2
						
					
				
				
					commit
					9f383ab228
				
			@ -4,6 +4,7 @@ Yii Framework 2 Change Log
 | 
				
			|||||||
2.0.16 under development
 | 
					2.0.16 under development
 | 
				
			||||||
------------------------
 | 
					------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Enh #14367: In `yii\db\mysql\QueryBuilder` added support fractional seconds for time types for MySQL >= 5.6.4 (konstantin-vl)
 | 
				
			||||||
- Bug #16766: `yii\filters\ContentNegotiator` was not setting `Vary` header to inform cache recipients (koteq, cebe, samdark)
 | 
					- Bug #16766: `yii\filters\ContentNegotiator` was not setting `Vary` header to inform cache recipients (koteq, cebe, samdark)
 | 
				
			||||||
- Bug #11960: Fixed `checked` option ignore in `yii\helpers\BaseHtml::checkbox()` (misantron)
 | 
					- Bug #11960: Fixed `checked` option ignore in `yii\helpers\BaseHtml::checkbox()` (misantron)
 | 
				
			||||||
- Bug #14759: Fixed `yii\web\JsonResponseFormatter` output for `null` data (misantron)
 | 
					- Bug #14759: Fixed `yii\web\JsonResponseFormatter` output for `null` data (misantron)
 | 
				
			||||||
 | 
				
			|||||||
@ -39,9 +39,6 @@ class QueryBuilder extends \yii\db\QueryBuilder
 | 
				
			|||||||
        Schema::TYPE_FLOAT => 'float',
 | 
					        Schema::TYPE_FLOAT => 'float',
 | 
				
			||||||
        Schema::TYPE_DOUBLE => 'double',
 | 
					        Schema::TYPE_DOUBLE => 'double',
 | 
				
			||||||
        Schema::TYPE_DECIMAL => 'decimal(10,0)',
 | 
					        Schema::TYPE_DECIMAL => 'decimal(10,0)',
 | 
				
			||||||
        Schema::TYPE_DATETIME => 'datetime',
 | 
					 | 
				
			||||||
        Schema::TYPE_TIMESTAMP => 'timestamp',
 | 
					 | 
				
			||||||
        Schema::TYPE_TIME => 'time',
 | 
					 | 
				
			||||||
        Schema::TYPE_DATE => 'date',
 | 
					        Schema::TYPE_DATE => 'date',
 | 
				
			||||||
        Schema::TYPE_BINARY => 'blob',
 | 
					        Schema::TYPE_BINARY => 'blob',
 | 
				
			||||||
        Schema::TYPE_BOOLEAN => 'tinyint(1)',
 | 
					        Schema::TYPE_BOOLEAN => 'tinyint(1)',
 | 
				
			||||||
@ -49,6 +46,15 @@ class QueryBuilder extends \yii\db\QueryBuilder
 | 
				
			|||||||
        Schema::TYPE_JSON => 'json'
 | 
					        Schema::TYPE_JSON => 'json'
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * {@inheritdoc}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function init()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->typeMap = array_merge($this->typeMap, $this->defaultTimeTypeMap());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * {@inheritdoc}
 | 
					     * {@inheritdoc}
 | 
				
			||||||
@ -362,4 +368,41 @@ class QueryBuilder extends \yii\db\QueryBuilder
 | 
				
			|||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Checks the ability to use fractional seconds.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     * @see https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function supportsFractionalSeconds()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $version = $this->db->getSlavePdo()->getAttribute(\PDO::ATTR_SERVER_VERSION);
 | 
				
			||||||
 | 
					        return version_compare($version, '5.6.4', '>=');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns the map for default time type.
 | 
				
			||||||
 | 
					     * If the version of MySQL is lower than 5.6.4, then the types will be without fractional seconds,
 | 
				
			||||||
 | 
					     * otherwise with fractional seconds.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function defaultTimeTypeMap()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $map = [
 | 
				
			||||||
 | 
					            Schema::TYPE_DATETIME => 'datetime',
 | 
				
			||||||
 | 
					            Schema::TYPE_TIMESTAMP => 'timestamp',
 | 
				
			||||||
 | 
					            Schema::TYPE_TIME => 'time',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($this->supportsFractionalSeconds()) {
 | 
				
			||||||
 | 
					            $map = [
 | 
				
			||||||
 | 
					                Schema::TYPE_DATETIME => 'datetime(0)',
 | 
				
			||||||
 | 
					                Schema::TYPE_TIMESTAMP => 'timestamp(0)',
 | 
				
			||||||
 | 
					                Schema::TYPE_TIME => 'time(0)',
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $map;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -280,7 +280,6 @@ abstract class QueryBuilderTest extends DatabaseTestCase
 | 
				
			|||||||
                Schema::TYPE_DATETIME . ' NOT NULL',
 | 
					                Schema::TYPE_DATETIME . ' NOT NULL',
 | 
				
			||||||
                $this->dateTime()->notNull(),
 | 
					                $this->dateTime()->notNull(),
 | 
				
			||||||
                [
 | 
					                [
 | 
				
			||||||
                    'mysql' => 'datetime NOT NULL',
 | 
					 | 
				
			||||||
                    'postgres' => 'timestamp(0) NOT NULL',
 | 
					                    'postgres' => 'timestamp(0) NOT NULL',
 | 
				
			||||||
                    'sqlite' => 'datetime NOT NULL',
 | 
					                    'sqlite' => 'datetime NOT NULL',
 | 
				
			||||||
                    'oci' => 'TIMESTAMP NOT NULL',
 | 
					                    'oci' => 'TIMESTAMP NOT NULL',
 | 
				
			||||||
@ -292,7 +291,6 @@ abstract class QueryBuilderTest extends DatabaseTestCase
 | 
				
			|||||||
                Schema::TYPE_DATETIME,
 | 
					                Schema::TYPE_DATETIME,
 | 
				
			||||||
                $this->dateTime(),
 | 
					                $this->dateTime(),
 | 
				
			||||||
                [
 | 
					                [
 | 
				
			||||||
                    'mysql' => 'datetime',
 | 
					 | 
				
			||||||
                    'postgres' => 'timestamp(0)',
 | 
					                    'postgres' => 'timestamp(0)',
 | 
				
			||||||
                    'sqlite' => 'datetime',
 | 
					                    'sqlite' => 'datetime',
 | 
				
			||||||
                    'oci' => 'TIMESTAMP',
 | 
					                    'oci' => 'TIMESTAMP',
 | 
				
			||||||
@ -871,7 +869,6 @@ abstract class QueryBuilderTest extends DatabaseTestCase
 | 
				
			|||||||
                Schema::TYPE_TIME . ' NOT NULL',
 | 
					                Schema::TYPE_TIME . ' NOT NULL',
 | 
				
			||||||
                $this->time()->notNull(),
 | 
					                $this->time()->notNull(),
 | 
				
			||||||
                [
 | 
					                [
 | 
				
			||||||
                    'mysql' => 'time NOT NULL',
 | 
					 | 
				
			||||||
                    'postgres' => 'time(0) NOT NULL',
 | 
					                    'postgres' => 'time(0) NOT NULL',
 | 
				
			||||||
                    'sqlite' => 'time NOT NULL',
 | 
					                    'sqlite' => 'time NOT NULL',
 | 
				
			||||||
                    'oci' => 'TIMESTAMP NOT NULL',
 | 
					                    'oci' => 'TIMESTAMP NOT NULL',
 | 
				
			||||||
@ -883,7 +880,6 @@ abstract class QueryBuilderTest extends DatabaseTestCase
 | 
				
			|||||||
                Schema::TYPE_TIME,
 | 
					                Schema::TYPE_TIME,
 | 
				
			||||||
                $this->time(),
 | 
					                $this->time(),
 | 
				
			||||||
                [
 | 
					                [
 | 
				
			||||||
                    'mysql' => 'time',
 | 
					 | 
				
			||||||
                    'postgres' => 'time(0)',
 | 
					                    'postgres' => 'time(0)',
 | 
				
			||||||
                    'sqlite' => 'time',
 | 
					                    'sqlite' => 'time',
 | 
				
			||||||
                    'oci' => 'TIMESTAMP',
 | 
					                    'oci' => 'TIMESTAMP',
 | 
				
			||||||
@ -906,7 +902,6 @@ abstract class QueryBuilderTest extends DatabaseTestCase
 | 
				
			|||||||
                Schema::TYPE_TIMESTAMP . ' NOT NULL',
 | 
					                Schema::TYPE_TIMESTAMP . ' NOT NULL',
 | 
				
			||||||
                $this->timestamp()->notNull(),
 | 
					                $this->timestamp()->notNull(),
 | 
				
			||||||
                [
 | 
					                [
 | 
				
			||||||
                    'mysql' => 'timestamp NOT NULL',
 | 
					 | 
				
			||||||
                    'postgres' => 'timestamp(0) NOT NULL',
 | 
					                    'postgres' => 'timestamp(0) NOT NULL',
 | 
				
			||||||
                    'sqlite' => 'timestamp NOT NULL',
 | 
					                    'sqlite' => 'timestamp NOT NULL',
 | 
				
			||||||
                    'oci' => 'TIMESTAMP NOT NULL',
 | 
					                    'oci' => 'TIMESTAMP NOT NULL',
 | 
				
			||||||
@ -934,7 +929,6 @@ abstract class QueryBuilderTest extends DatabaseTestCase
 | 
				
			|||||||
                Schema::TYPE_TIMESTAMP . ' NULL DEFAULT NULL',
 | 
					                Schema::TYPE_TIMESTAMP . ' NULL DEFAULT NULL',
 | 
				
			||||||
                $this->timestamp()->defaultValue(null),
 | 
					                $this->timestamp()->defaultValue(null),
 | 
				
			||||||
                [
 | 
					                [
 | 
				
			||||||
                    'mysql' => 'timestamp NULL DEFAULT NULL',
 | 
					 | 
				
			||||||
                    'postgres' => 'timestamp(0) NULL DEFAULT NULL',
 | 
					                    'postgres' => 'timestamp(0) NULL DEFAULT NULL',
 | 
				
			||||||
                    'sqlite' => 'timestamp NULL DEFAULT NULL',
 | 
					                    'sqlite' => 'timestamp NULL DEFAULT NULL',
 | 
				
			||||||
                    'sqlsrv' => 'timestamp NULL DEFAULT NULL',
 | 
					                    'sqlsrv' => 'timestamp NULL DEFAULT NULL',
 | 
				
			||||||
 | 
				
			|||||||
@ -85,6 +85,64 @@ class QueryBuilderTest extends \yiiunit\framework\db\QueryBuilderTest
 | 
				
			|||||||
            ];
 | 
					            ];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return array_merge(parent::columnTypes(), $this->columnTimeTypes(), $columns);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function columnTimeTypes()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $columns = [
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                Schema::TYPE_DATETIME . ' NOT NULL',
 | 
				
			||||||
 | 
					                $this->dateTime()->notNull(),
 | 
				
			||||||
 | 
					                'datetime NOT NULL',
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                Schema::TYPE_DATETIME,
 | 
				
			||||||
 | 
					                $this->dateTime(),
 | 
				
			||||||
 | 
					                'datetime',
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                Schema::TYPE_TIME . ' NOT NULL',
 | 
				
			||||||
 | 
					                $this->time()->notNull(),
 | 
				
			||||||
 | 
					                'time NOT NULL',
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                Schema::TYPE_TIME,
 | 
				
			||||||
 | 
					                $this->time(),
 | 
				
			||||||
 | 
					                'time',
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                Schema::TYPE_TIMESTAMP . ' NOT NULL',
 | 
				
			||||||
 | 
					                $this->timestamp()->notNull(),
 | 
				
			||||||
 | 
					                'timestamp NOT NULL',
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                Schema::TYPE_TIMESTAMP . ' NULL DEFAULT NULL',
 | 
				
			||||||
 | 
					                $this->timestamp()->defaultValue(null),
 | 
				
			||||||
 | 
					                'timestamp NULL DEFAULT NULL',
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * @link https://github.com/yiisoft/yii2/issues/14367
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        $mysqlVersion = $this->getDb()->getSlavePdo()->getAttribute(\PDO::ATTR_SERVER_VERSION);
 | 
				
			||||||
 | 
					        $supportsFractionalSeconds = version_compare($mysqlVersion,'5.6.4', '>=');
 | 
				
			||||||
 | 
					        if ($supportsFractionalSeconds) {
 | 
				
			||||||
 | 
					            $expectedValues = [
 | 
				
			||||||
 | 
					                'datetime(0) NOT NULL',
 | 
				
			||||||
 | 
					                'datetime(0)',
 | 
				
			||||||
 | 
					                'time(0) NOT NULL',
 | 
				
			||||||
 | 
					                'time(0)',
 | 
				
			||||||
 | 
					                'timestamp(0) NOT NULL',
 | 
				
			||||||
 | 
					                'timestamp(0) NULL DEFAULT NULL',
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach ($expectedValues as $index => $expected) {
 | 
				
			||||||
 | 
					                $columns[$index][2] = $expected;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * @link https://github.com/yiisoft/yii2/issues/14834
 | 
					         * @link https://github.com/yiisoft/yii2/issues/14834
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
@ -99,11 +157,11 @@ class QueryBuilderTest extends \yiiunit\framework\db\QueryBuilderTest
 | 
				
			|||||||
            $columns[] = [
 | 
					            $columns[] = [
 | 
				
			||||||
                Schema::TYPE_TIMESTAMP,
 | 
					                Schema::TYPE_TIMESTAMP,
 | 
				
			||||||
                $this->timestamp(),
 | 
					                $this->timestamp(),
 | 
				
			||||||
                'timestamp',
 | 
					                $supportsFractionalSeconds ? 'timestamp(0)' : 'timestamp',
 | 
				
			||||||
            ];
 | 
					            ];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return array_merge(parent::columnTypes(), $columns);
 | 
					        return $columns;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function primaryKeysProvider()
 | 
					    public function primaryKeysProvider()
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user