From 57888a3526b31b1051cc76eb67c6e3881c118a9d Mon Sep 17 00:00:00 2001 From: susnasr Date: Fri, 12 Dec 2025 18:19:04 +0500 Subject: [PATCH] Feat: Add native JSON column type support for SQL Server 2025+ (Fixes #57965) --- .../Schema/Grammars/SqlServerGrammar.php | 8 ++++- tests/Database/SqlServerBuilderTest.php | 32 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php b/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php index 28b5e5a7a161..613429cf138d 100755 --- a/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php @@ -749,6 +749,12 @@ protected function typeEnum(Fluent $column) */ protected function typeJson(Fluent $column) { + $version = $this->connection->getServerVersion(); + + if (version_compare($version, '2025', '>=')) { + return 'json'; + } + return 'nvarchar(max)'; } @@ -760,7 +766,7 @@ protected function typeJson(Fluent $column) */ protected function typeJsonb(Fluent $column) { - return 'nvarchar(max)'; + return $this->typeJson($column); } /** diff --git a/tests/Database/SqlServerBuilderTest.php b/tests/Database/SqlServerBuilderTest.php index 5ae3689adfd0..3615ac316a85 100644 --- a/tests/Database/SqlServerBuilderTest.php +++ b/tests/Database/SqlServerBuilderTest.php @@ -43,4 +43,36 @@ public function testDropDatabaseIfExists() $builder->dropDatabaseIfExists('my_temporary_database_b'); } + + public function testItUsesNativeJsonTypeForSqlServer2025Plus() + { + // Mockery is already aliased as 'm' at the top of the file. + $connection = m::mock(Connection::class); + $grammar = new SqlServerGrammar($connection); + + // CRITICAL: Mock the internal connection method to return the version supporting the feature. + $connection->shouldReceive('getServerVersion')->once()->andReturn('2025.0.0'); + // Mock table prefix if needed by the Grammar methods you touch. + $connection->shouldReceive('getTablePrefix')->andReturn(''); + + $column = new \Illuminate\Support\Fluent(['name' => 'data', 'type' => 'json']); + + // Assert that the Grammar returns the native JSON type. + $this->assertEquals('json', $grammar->typeJson($column)); + } + + public function testItFallsBackToNvarcharMaxForSqlServerPre2025() + { + $connection = m::mock(Connection::class); + $grammar = new SqlServerGrammar($connection); + + // CRITICAL: Mock the internal connection method to return an older version. + $connection->shouldReceive('getServerVersion')->once()->andReturn('2019.0.0'); + $connection->shouldReceive('getTablePrefix')->andReturn(''); + + $column = new \Illuminate\Support\Fluent(['name' => 'data', 'type' => 'json']); + + // Assert that the Grammar falls back to the old nvarchar(max) type. + $this->assertEquals('nvarchar(max)', $grammar->typeJson($column)); + } }