From 9e3179fece72f199fc624aa2ee9fa7e3b7e70267 Mon Sep 17 00:00:00 2001 From: Kazuyoshi Tomita Date: Thu, 1 Feb 2024 13:45:43 +0900 Subject: [PATCH] Fixed an error when $query->from is of type Illuminate\Database\Query\Expression. --- src/Illuminate/Database/Query/Builder.php | 2 +- tests/Database/DatabaseQueryBuilderTest.php | 34 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index ebb833707b11..cf5889e32a61 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -394,7 +394,7 @@ protected function prependDatabaseNameIfCrossDatabaseQuery($query) $this->getConnection()->getDatabaseName()) { $databaseName = $query->getConnection()->getDatabaseName(); - if (! str_starts_with($query->from, $databaseName) && ! str_contains($query->from, '.')) { + if (is_string($query->from) && ! str_starts_with($query->from, $databaseName) && ! str_contains($query->from, '.')) { $query->from($databaseName.'.'.$query->from); } } diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index cf0c8389b09b..15c701d1b3ef 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -2504,6 +2504,40 @@ public function testJoinSubWithPrefix() $this->assertSame('select * from "prefix_users" inner join (select * from "contacts") as "prefix_sub" on "prefix_users"."id" = "prefix_sub"."id"', $builder->toSql()); } + public function testJoinSubWithCrossDatabaseQuery() + { + // Create another database connection and builder. + $connection2 = m::mock(ConnectionInterface::class); + $connection2->shouldReceive('getDatabaseName')->andReturn('database2'); + $builder2 = new Builder($connection2, new Grammar, m::mock(Processor::class)); + + // Create subquery that use another databases. + // Case1: 'from' property is string + $subquery = $builder2 + ->from('posts') + ->select('user_id, title'); + + $builder = $this->getBuilder(); + $builder->from('users')->joinSub($subquery, 'sub', function ($join) { + $join->on('users.id', '=', 'sub.user_id'); + }); + + $this->assertSame('select * from "users" inner join (select "user_id, title" from "database2"."posts") as "sub" on "users"."id" = "sub"."user_id"', $builder->toSql()); + + // Create subquery that use another databases. + // Case2: 'from' property is Expression + $subquery = $builder2 + ->from(new Raw('database2.posts')) // set Expression + ->select('user_id, title'); + + $builder = $this->getBuilder(); + $builder->from('users')->joinSub($subquery, 'sub', function ($join) { + $join->on('users.id', '=', 'sub.user_id'); + }); + + $this->assertSame('select * from "users" inner join (select "user_id, title" from database2.posts) as "sub" on "users"."id" = "sub"."user_id"', $builder->toSql()); + } + public function testLeftJoinSub() { $builder = $this->getBuilder();