From 7ed7d9a1a5a06ee1f231134fe649f6be282c3cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robson=20Ten=C3=B3rio?= Date: Sun, 10 Nov 2019 23:01:11 -0300 Subject: [PATCH] Fix "top all" strategy with custom select --- src/Cache/Query/Grammars/Grammar.php | 4 +- tests/CacheQueryBuilderTest.php | 132 +++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 2 deletions(-) diff --git a/src/Cache/Query/Grammars/Grammar.php b/src/Cache/Query/Grammars/Grammar.php index f6846cd..bf269d3 100644 --- a/src/Cache/Query/Grammars/Grammar.php +++ b/src/Cache/Query/Grammars/Grammar.php @@ -22,7 +22,7 @@ protected function compileAnsiOffset(Builder $query, $components) $components['orders'] = 'order by 1'; } - $components['columns'] = $this->compileOver(''); + $components['columns'] = $this->compileOver($this->columnize($query->columns)); $sql = $this->concatenate($components); return $this->compileTableExpression($sql, $query); @@ -30,7 +30,7 @@ protected function compileAnsiOffset(Builder $query, $components) protected function compileOver($orderings) { - return 'select top all *'; + return "select top all {$orderings}"; } protected function compileTableExpression($sql, $query) diff --git a/tests/CacheQueryBuilderTest.php b/tests/CacheQueryBuilderTest.php index 6916d43..7f19425 100644 --- a/tests/CacheQueryBuilderTest.php +++ b/tests/CacheQueryBuilderTest.php @@ -254,6 +254,25 @@ public function testUnions() $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); } + public function testUnionsWithCustomSelect() + { + $builder = $this->getBuilder(); + + $builder->select(['name', 'email']) + ->from('users') + ->where('id', '=', 1); + + $builder->union( + $this->getBuilder()->select(['name', 'email'])->from('users')->where('id', '=', 2) + ); + + $this->assertEquals( + 'select * from (select name, email from users where id = ?) as temp_table union select * from (select name, email from users where id = ?) as temp_table', + $builder->toSql() + ); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + } + public function testUnionAlls() { $builder = $this->getBuilder(); @@ -273,6 +292,25 @@ public function testUnionAlls() $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); } + public function testUnionAllsWithCustomSelect() + { + $builder = $this->getBuilder(); + + $builder->select(['name', 'email']) + ->from('users') + ->where('id', '=', 1); + + $builder->unionAll( + $this->getBuilder()->select(['name', 'email'])->from('users')->where('id', '=', 2) + ); + + $this->assertEquals( + 'select * from (select name, email from users where id = ?) as temp_table union all select * from (select name, email from users where id = ?) as temp_table', + $builder->toSql() + ); + $this->assertEquals([0 => 1, 1 => 2], $builder->getBindings()); + } + public function testMultipleUnions() { $builder = $this->getBuilder(); @@ -294,6 +332,27 @@ public function testMultipleUnions() $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings()); } + public function testMultipleUnionsWithCustomSelect() + { + $builder = $this->getBuilder(); + + $builder->select(['name', 'email'])->from('users')->where('id', '=', 1); + + $builder->union( + $this->getBuilder()->select(['name', 'email'])->from('users')->where('id', '=', 2) + ); + + $builder->union( + $this->getBuilder()->select(['name', 'email'])->from('users')->where('id', '=', 3) + ); + + $this->assertEquals( + 'select * from (select name, email from users where id = ?) as temp_table union select * from (select name, email from users where id = ?) as temp_table union select * from (select name, email from users where id = ?) as temp_table', + $builder->toSql() + ); + $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings()); + } + public function testMultipleUnionAlls() { $builder = $this->getBuilder(); @@ -314,6 +373,26 @@ public function testMultipleUnionAlls() $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings()); } + public function testMultipleUnionAllsWithCustomSelect() + { + $builder = $this->getBuilder(); + + $builder->select(['name', 'email'])->from('users')->where('id', '=', 1); + + $builder->unionAll( + $this->getBuilder()->select(['name', 'email'])->from('users')->where('id', '=', 2) + ); + $builder->unionAll( + $this->getBuilder()->select(['name', 'email'])->from('users')->where('id', '=', 3) + ); + + $this->assertEquals( + 'select * from (select name, email from users where id = ?) as temp_table union all select * from (select name, email from users where id = ?) as temp_table union all select * from (select name, email from users where id = ?) as temp_table', + $builder->toSql() + ); + $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $builder->getBindings()); + } + public function testSubSelectWhereIns() { $builder = $this->getBuilder(); @@ -496,6 +575,20 @@ public function testOffset() ); } + public function testOffsetWithCustomSelect() + { + $builder = $this->getBuilder(); + $connection = $builder->getConnection(); + + $connection->shouldReceive('getConfig')->andReturn(''); + $builder->select(['name', 'email'])->from('users')->offset(10); + + $this->assertEquals( + 'select *, %vid from (select top all name, email from users order by 1) where %vid >= 11', + $builder->toSql() + ); + } + public function testLimitsAndOffsets() { $builder = $this->getBuilder(); @@ -551,6 +644,20 @@ public function testLimitsAndOffsets() ); } + public function testLimitsAndOffsetsWithCustomSelect() + { + $builder = $this->getBuilder(); + $connection = $builder->getConnection(); + + $connection->shouldReceive('getConfig')->andReturn(''); + $builder->select(['name', 'email'])->from('users')->offset(5)->limit(10); + + $this->assertEquals( + 'select *, %vid from (select top all name, email from users order by 1) where %vid between 6 and 15', + $builder->toSql() + ); + } + public function testLimitAndOffsetToPaginateOne() { $builder = $this->getBuilder(); @@ -576,6 +683,31 @@ public function testLimitAndOffsetToPaginateOne() ); } + public function testLimitAndOffsetToPaginateOneWithCustomSelect() + { + $builder = $this->getBuilder(); + $connection = $builder->getConnection(); + + $connection->shouldReceive('getConfig')->andReturn(''); + $builder->select(['name', 'email'])->from('users')->offset(0)->limit(1); + + $this->assertEquals( + 'select top 1 name, email from users', + $builder->toSql() + ); + + $builder = $this->getBuilder(); + $connection = $builder->getConnection(); + + $connection->shouldReceive('getConfig')->andReturn(''); + $builder->select(['name', 'email'])->from('users')->offset(1)->limit(1); + + $this->assertEquals( + 'select *, %vid from (select top all name, email from users order by 1) where %vid between 2 and 2', + $builder->toSql() + ); + } + public function testWhereShortcut() { $builder = $this->getBuilder();