From 30aae1229bd048f2eb28f85e9630e50c311c9cb1 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Tue, 14 Oct 2025 09:44:13 +0800 Subject: [PATCH 1/4] Test Improvements Signed-off-by: Mior Muhammad Zaki --- .../Database/QueryBuilderUpdateTest.php | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tests/Integration/Database/QueryBuilderUpdateTest.php b/tests/Integration/Database/QueryBuilderUpdateTest.php index 4e87f19a343b..66cc0d512881 100644 --- a/tests/Integration/Database/QueryBuilderUpdateTest.php +++ b/tests/Integration/Database/QueryBuilderUpdateTest.php @@ -28,16 +28,37 @@ protected function afterRefreshingDatabase() public function testBasicUpdateForJson($column, $given, $expected) { DB::table('example')->insert([ + ['name' => 'Taylor Otwell', 'title' => 'Mr.'], + ]); + + DB::table('example')->update([ + $column => $given, + ]); + + $this->assertDatabaseHas('example', [ 'name' => 'Taylor Otwell', 'title' => 'Mr.', + $column => $column === 'payload' ? $this->castAsJson($expected) : $expected, ]); + } - DB::table('example')->update([$column => $given]); + #[RequiresDatabase(['sqlite', 'mysql', 'mariadb'])] + public function testSubqueryUpdate() + { + DB::table('example')->insert([ + ['name' => 'Taylor Otwell', 'title' => 'Mr.'], + ]); + + var_dump(DB::table('example')->selectRaw('CONCAT(example.title, example.name)')::class); + + DB::table('example')->update([ + 'payload->fullname' => DB::table('example')->selectRaw('CONCAT(example.title, example.name)') + ]); $this->assertDatabaseHas('example', [ 'name' => 'Taylor Otwell', 'title' => 'Mr.', - $column => $column === 'payload' ? $this->castAsJson($expected) : $expected, + 'payload' => $this->castAsJson(['fullname' => 'Mr. Taylor Otwell']), ]); } From 825473bd2099f0ab83650732b1071c60a0017a8c Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Tue, 14 Oct 2025 01:44:49 +0000 Subject: [PATCH 2/4] Apply fixes from StyleCI --- tests/Integration/Database/QueryBuilderUpdateTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Integration/Database/QueryBuilderUpdateTest.php b/tests/Integration/Database/QueryBuilderUpdateTest.php index 66cc0d512881..56e58ce2a67a 100644 --- a/tests/Integration/Database/QueryBuilderUpdateTest.php +++ b/tests/Integration/Database/QueryBuilderUpdateTest.php @@ -52,7 +52,7 @@ public function testSubqueryUpdate() var_dump(DB::table('example')->selectRaw('CONCAT(example.title, example.name)')::class); DB::table('example')->update([ - 'payload->fullname' => DB::table('example')->selectRaw('CONCAT(example.title, example.name)') + 'payload->fullname' => DB::table('example')->selectRaw('CONCAT(example.title, example.name)'), ]); $this->assertDatabaseHas('example', [ From e26e30a26d3b8a54bf3e6e60f3c59543f4fa4324 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Tue, 14 Oct 2025 09:52:26 +0800 Subject: [PATCH 3/4] wip Signed-off-by: Mior Muhammad Zaki --- tests/Integration/Database/QueryBuilderUpdateTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Integration/Database/QueryBuilderUpdateTest.php b/tests/Integration/Database/QueryBuilderUpdateTest.php index 56e58ce2a67a..592ea841c08f 100644 --- a/tests/Integration/Database/QueryBuilderUpdateTest.php +++ b/tests/Integration/Database/QueryBuilderUpdateTest.php @@ -52,7 +52,7 @@ public function testSubqueryUpdate() var_dump(DB::table('example')->selectRaw('CONCAT(example.title, example.name)')::class); DB::table('example')->update([ - 'payload->fullname' => DB::table('example')->selectRaw('CONCAT(example.title, example.name)'), + 'payload->fullname' => DB::table('example')->selectRaw('CONCAT(title, name)'), ]); $this->assertDatabaseHas('example', [ From e942448d075f379c271fe6daae57879d58e62138 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Tue, 14 Oct 2025 11:00:27 +0800 Subject: [PATCH 4/4] wip Signed-off-by: Mior Muhammad Zaki --- .../Database/Query/Grammars/MySqlGrammar.php | 1 + .../Query/Grammars/PostgresGrammar.php | 3 ++ .../Database/Query/Grammars/SQLiteGrammar.php | 3 ++ .../Query/Grammars/SqlServerGrammar.php | 3 ++ .../Database/QueryBuilderUpdateTest.php | 35 +++++++++++++++++-- 5 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php b/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php index 4372bae32791..1856b998ca01 100755 --- a/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php +++ b/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php @@ -442,6 +442,7 @@ protected function compileUpdateWithoutJoins(Builder $query, $table, $columns, $ * @param array $values * @return array */ + #[\Override] public function prepareBindingsForUpdate(array $bindings, array $values) { $values = (new Collection($values)) diff --git a/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php index 615852e2ae7d..3a2a7b425f3c 100755 --- a/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php @@ -618,6 +618,7 @@ protected function compileUpdateWithJoinsOrLimit(Builder $query, array $values) * @param array $values * @return array */ + #[\Override] public function prepareBindingsForUpdate(array $bindings, array $values) { $values = (new Collection($values))->map(function ($value, $column) { @@ -628,6 +629,8 @@ public function prepareBindingsForUpdate(array $bindings, array $values) $cleanBindings = Arr::except($bindings, 'select'); + $values = Arr::flatten(array_map(fn ($value) => value($value), $values)); + return array_values( array_merge($values, Arr::flatten($cleanBindings)) ); diff --git a/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php b/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php index a70571d2ceb9..f9a82febd948 100755 --- a/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php +++ b/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php @@ -384,6 +384,7 @@ protected function compileUpdateWithJoinsOrLimit(Builder $query, array $values) * @param array $values * @return array */ + #[\Override] public function prepareBindingsForUpdate(array $bindings, array $values) { $groups = $this->groupJsonColumnsForUpdate($values); @@ -396,6 +397,8 @@ public function prepareBindingsForUpdate(array $bindings, array $values) $cleanBindings = Arr::except($bindings, 'select'); + $values = Arr::flatten(array_map(fn ($value) => value($value), $values)); + return array_values( array_merge($values, Arr::flatten($cleanBindings)) ); diff --git a/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php b/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php index 45cebeaa8036..2cd0d15a0be5 100755 --- a/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php +++ b/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php @@ -453,10 +453,13 @@ public function compileUpsert(Builder $query, array $values, array $uniqueBy, ar * @param array $values * @return array */ + #[\Override] public function prepareBindingsForUpdate(array $bindings, array $values) { $cleanBindings = Arr::except($bindings, 'select'); + $values = Arr::flatten(array_map(fn ($value) => value($value), $values)); + return array_values( array_merge($values, Arr::flatten($cleanBindings)) ); diff --git a/tests/Integration/Database/QueryBuilderUpdateTest.php b/tests/Integration/Database/QueryBuilderUpdateTest.php index 592ea841c08f..d8783ce8a250 100644 --- a/tests/Integration/Database/QueryBuilderUpdateTest.php +++ b/tests/Integration/Database/QueryBuilderUpdateTest.php @@ -19,8 +19,15 @@ protected function afterRefreshingDatabase() $table->string('name')->nullable(); $table->string('title')->nullable(); $table->string('status')->nullable(); + $table->integer('credits')->nullable(); $table->json('payload')->nullable(); }); + + Schema::create('example_credits', function (Blueprint $table) { + $table->increments('id'); + $table->unsignedBigInteger('example_id'); + $table->integer('credits'); + }); } #[DataProvider('jsonValuesDataProvider')] @@ -47,18 +54,40 @@ public function testSubqueryUpdate() { DB::table('example')->insert([ ['name' => 'Taylor Otwell', 'title' => 'Mr.'], + ['name' => 'Tim MacDonald', 'title' => 'Mr.'], + ]); + + DB::table('example_credits')->insert([ + ['example_id' => 1, 'credits' => 10], + ['example_id' => 1, 'credits' => 20], ]); - var_dump(DB::table('example')->selectRaw('CONCAT(example.title, example.name)')::class); + $this->assertDatabaseHas('example', [ + 'name' => 'Taylor Otwell', + 'title' => 'Mr.', + 'credits' => null, + ]); + + $this->assertDatabaseHas('example', [ + 'name' => 'Tim MacDonald', + 'title' => 'Mr.', + 'credits' => null, + ]); DB::table('example')->update([ - 'payload->fullname' => DB::table('example')->selectRaw('CONCAT(title, name)'), + 'credits' => DB::table('example_credits')->selectRaw('sum(credits)')->whereColumn('example_credits.example_id', 'example.id'), ]); $this->assertDatabaseHas('example', [ 'name' => 'Taylor Otwell', 'title' => 'Mr.', - 'payload' => $this->castAsJson(['fullname' => 'Mr. Taylor Otwell']), + 'credits' => 30, + ]); + + $this->assertDatabaseHas('example', [ + 'name' => 'Tim MacDonald', + 'title' => 'Mr.', + 'credits' => null, ]); }