From 8026bd68c4465a90907da32cead9f9ead62fc4b3 Mon Sep 17 00:00:00 2001 From: Magnus Hauge Bakke Date: Wed, 21 Feb 2024 16:24:37 +0100 Subject: [PATCH] Add integration tests for lateral joins --- .../Database/MySql/JoinLateralTest.php | 102 ++++++++++++++++++ .../Database/Postgres/JoinLateralTest.php | 102 ++++++++++++++++++ .../Database/SqlServer/JoinLateralTest.php | 98 +++++++++++++++++ 3 files changed, 302 insertions(+) create mode 100644 tests/Integration/Database/MySql/JoinLateralTest.php create mode 100644 tests/Integration/Database/Postgres/JoinLateralTest.php create mode 100644 tests/Integration/Database/SqlServer/JoinLateralTest.php diff --git a/tests/Integration/Database/MySql/JoinLateralTest.php b/tests/Integration/Database/MySql/JoinLateralTest.php new file mode 100644 index 000000000000..584d95b6a5fc --- /dev/null +++ b/tests/Integration/Database/MySql/JoinLateralTest.php @@ -0,0 +1,102 @@ +id('id'); + $table->string('name'); + }); + + Schema::create('posts', function (Blueprint $table) { + $table->id('id'); + $table->string('title'); + $table->integer('rating'); + $table->unsignedBigInteger('user_id'); + }); + } + + protected function destroyDatabaseMigrations() + { + Schema::drop('posts'); + Schema::drop('users'); + } + + protected function setUp(): void + { + parent::setUp(); + + DB::table('users')->insert([ + ['name' => Str::random()], + ['name' => Str::random()], + ]); + + DB::table('posts')->insert([ + ['title' => Str::random(), 'rating' => 1, 'user_id' => 1], + ['title' => Str::random(), 'rating' => 3, 'user_id' => 1], + ['title' => Str::random(), 'rating' => 7, 'user_id' => 1], + ]); + } + + public function testJoinLateral() + { + $subquery = DB::table('posts') + ->select('title as best_post_title', 'rating as best_post_rating') + ->whereColumn('user_id', 'users.id') + ->orderBy('rating', 'desc') + ->limit(1); + + $userWithPosts = DB::table('users') + ->where('id', 1) + ->joinLateral($subquery, 'best_post') + ->first(); + + $this->assertNotNull($userWithPosts); + $this->assertEquals(7, $userWithPosts->best_post_rating); + + $userWithoutPosts = DB::table('users') + ->where('id', 2) + ->joinLateral($subquery, 'best_post') + ->first(); + + $this->assertNull($userWithoutPosts); + } + + public function testLeftJoinLateral() + { + $subquery = DB::table('posts') + ->select('title as best_post_title', 'rating as best_post_rating') + ->whereColumn('user_id', 'users.id') + ->orderBy('rating', 'desc') + ->limit(1); + + $userWithPosts = DB::table('users') + ->where('id', 1) + ->leftJoinLateral($subquery, 'best_post') + ->first(); + + $this->assertNotNull($userWithPosts); + $this->assertEquals(7, $userWithPosts->best_post_rating); + + $userWithoutPosts = DB::table('users') + ->where('id', 2) + ->leftJoinLateral($subquery, 'best_post') + ->first(); + + $this->assertNotNull($userWithoutPosts); + $this->assertNull($userWithoutPosts->best_post_title); + $this->assertNull($userWithoutPosts->best_post_rating); + } +} diff --git a/tests/Integration/Database/Postgres/JoinLateralTest.php b/tests/Integration/Database/Postgres/JoinLateralTest.php new file mode 100644 index 000000000000..6ec665951416 --- /dev/null +++ b/tests/Integration/Database/Postgres/JoinLateralTest.php @@ -0,0 +1,102 @@ +id('id'); + $table->string('name'); + }); + + Schema::create('posts', function (Blueprint $table) { + $table->id('id'); + $table->string('title'); + $table->integer('rating'); + $table->unsignedBigInteger('user_id'); + }); + } + + protected function destroyDatabaseMigrations() + { + Schema::drop('posts'); + Schema::drop('users'); + } + + protected function setUp(): void + { + parent::setUp(); + + DB::table('users')->insert([ + ['name' => Str::random()], + ['name' => Str::random()], + ]); + + DB::table('posts')->insert([ + ['title' => Str::random(), 'rating' => 1, 'user_id' => 1], + ['title' => Str::random(), 'rating' => 3, 'user_id' => 1], + ['title' => Str::random(), 'rating' => 7, 'user_id' => 1], + ]); + } + + public function testJoinLateral() + { + $subquery = DB::table('posts') + ->select('title as best_post_title', 'rating as best_post_rating') + ->whereColumn('user_id', 'users.id') + ->orderBy('rating', 'desc') + ->limit(1); + + $userWithPosts = DB::table('users') + ->where('id', 1) + ->joinLateral($subquery, 'best_post') + ->first(); + + $this->assertNotNull($userWithPosts); + $this->assertEquals(7, $userWithPosts->best_post_rating); + + $userWithoutPosts = DB::table('users') + ->where('id', 2) + ->joinLateral($subquery, 'best_post') + ->first(); + + $this->assertNull($userWithoutPosts); + } + + public function testLeftJoinLateral() + { + $subquery = DB::table('posts') + ->select('title as best_post_title', 'rating as best_post_rating') + ->whereColumn('user_id', 'users.id') + ->orderBy('rating', 'desc') + ->limit(1); + + $userWithPosts = DB::table('users') + ->where('id', 1) + ->leftJoinLateral($subquery, 'best_post') + ->first(); + + $this->assertNotNull($userWithPosts); + $this->assertEquals(7, $userWithPosts->best_post_rating); + + $userWithoutPosts = DB::table('users') + ->where('id', 2) + ->leftJoinLateral($subquery, 'best_post') + ->first(); + + $this->assertNotNull($userWithoutPosts); + $this->assertNull($userWithoutPosts->best_post_title); + $this->assertNull($userWithoutPosts->best_post_rating); + } +} diff --git a/tests/Integration/Database/SqlServer/JoinLateralTest.php b/tests/Integration/Database/SqlServer/JoinLateralTest.php new file mode 100644 index 000000000000..7aa2a5f9ac35 --- /dev/null +++ b/tests/Integration/Database/SqlServer/JoinLateralTest.php @@ -0,0 +1,98 @@ +id('id'); + $table->string('name'); + }); + + Schema::create('posts', function (Blueprint $table) { + $table->id('id'); + $table->string('title'); + $table->integer('rating'); + $table->unsignedBigInteger('user_id'); + }); + } + + protected function destroyDatabaseMigrations() + { + Schema::drop('posts'); + Schema::drop('users'); + } + + protected function setUp(): void + { + parent::setUp(); + + DB::table('users')->insert([ + ['name' => Str::random()], + ['name' => Str::random()], + ]); + + DB::table('posts')->insert([ + ['title' => Str::random(), 'rating' => 1, 'user_id' => 1], + ['title' => Str::random(), 'rating' => 3, 'user_id' => 1], + ['title' => Str::random(), 'rating' => 7, 'user_id' => 1], + ]); + } + + public function testJoinLateral() + { + $subquery = DB::table('posts') + ->select('title as best_post_title', 'rating as best_post_rating') + ->whereColumn('user_id', 'users.id') + ->orderBy('rating', 'desc') + ->limit(1); + + $userWithPosts = DB::table('users') + ->where('id', 1) + ->joinLateral($subquery, 'best_post') + ->first(); + + $this->assertNotNull($userWithPosts); + $this->assertEquals(7, (int) $userWithPosts->best_post_rating); + + $userWithoutPosts = DB::table('users') + ->where('id', 2) + ->joinLateral($subquery, 'best_post') + ->first(); + + $this->assertNull($userWithoutPosts); + } + + public function testLeftJoinLateral() + { + $subquery = DB::table('posts') + ->select('title as best_post_title', 'rating as best_post_rating') + ->whereColumn('user_id', 'users.id') + ->orderBy('rating', 'desc') + ->limit(1); + + $userWithPosts = DB::table('users') + ->where('id', 1) + ->leftJoinLateral($subquery, 'best_post') + ->first(); + + $this->assertNotNull($userWithPosts); + $this->assertEquals(7, (int) $userWithPosts->best_post_rating); + + $userWithoutPosts = DB::table('users') + ->where('id', 2) + ->leftJoinLateral($subquery, 'best_post') + ->first(); + + $this->assertNotNull($userWithoutPosts); + $this->assertNull($userWithoutPosts->best_post_title); + $this->assertNull($userWithoutPosts->best_post_rating); + } +}