diff --git a/src/Query/JoinClause.php b/src/Query/JoinClause.php index 6032a06..2bb003b 100644 --- a/src/Query/JoinClause.php +++ b/src/Query/JoinClause.php @@ -58,6 +58,13 @@ class JoinClause */ private $subQuery; + /** + * Join alias. + * + * @var \Tinderbox\ClickhouseBuilder\Query\Identifier + */ + private $alias; + /** * JoinClause constructor. * @@ -237,13 +244,33 @@ public function query($query = null) /** * Get sub-query builder. * + * @param string|null $alias + * * @return BaseBuilder */ - public function subQuery(): BaseBuilder + public function subQuery(string $alias = null): BaseBuilder { + if ($alias) { + $this->as($alias); + } + return $this->subQuery = $this->query->newQuery(); } + /** + * Set join alias. + * + * @param string $alias + * + * @return $this + */ + public function as(string $alias) + { + $this->alias = new Identifier($alias); + + return $this; + } + /** * Get using columns. * @@ -304,6 +331,16 @@ public function getTable() return $this->table; } + /** + * Get alias. + * + * @return Identifier + */ + public function getAlias(): ?Identifier + { + return $this->alias; + } + /** * Converts strings to Identifier objects. * diff --git a/src/Query/Traits/JoinComponentCompiler.php b/src/Query/Traits/JoinComponentCompiler.php index 3c1672d..ccf7077 100644 --- a/src/Query/Traits/JoinComponentCompiler.php +++ b/src/Query/Traits/JoinComponentCompiler.php @@ -16,7 +16,7 @@ trait JoinComponentCompiler * * @return string */ - protected function compileJoinComponent(Builder $query, JoinClause $join) : string + protected function compileJoinComponent(Builder $query, JoinClause $join): string { $this->verifyJoin($join); @@ -26,16 +26,20 @@ protected function compileJoinComponent(Builder $query, JoinClause $join) : stri $result[] = 'GLOBAL'; } - if (! is_null($join->getStrict())) { + if (!is_null($join->getStrict())) { $result[] = $join->getStrict(); } - if (! is_null($join->getType())) { + if (!is_null($join->getType())) { $result[] = $join->getType(); } $result[] = 'JOIN'; $result[] = $this->wrap($join->getTable()); + if ($join->getAlias()) { + $result[] = 'AS'; + $result[] = $this->wrap($join->getAlias()); + } $result[] = 'USING'; $result[] = implode(', ', array_map(function ($column) { return $this->wrap($column); diff --git a/tests/GrammarTest.php b/tests/GrammarTest.php index 071f93c..3274e11 100644 --- a/tests/GrammarTest.php +++ b/tests/GrammarTest.php @@ -6,7 +6,6 @@ use Mockery as m; use PHPUnit\Framework\TestCase; use Tinderbox\Clickhouse\Client; -use Tinderbox\ClickhouseBuilder\Exceptions\BuilderException; use Tinderbox\ClickhouseBuilder\Exceptions\GrammarException; use Tinderbox\ClickhouseBuilder\Query\Builder; use Tinderbox\ClickhouseBuilder\Query\Column; @@ -24,7 +23,7 @@ class GrammarTest extends TestCase { use MockeryPHPUnitIntegration; - public function getBuilder() : Builder + public function getBuilder(): Builder { return new Builder(m::mock(Client::class)); } @@ -205,7 +204,7 @@ public function testCompileSelect() $select = $grammar->compileSelect($this->getBuilder()->from('table')->groupBy([])); $this->assertEquals('SELECT * FROM `table`', $select); - + $select = $grammar->compileSelect($this->getBuilder()->from('table')->groupBy('*')); $this->assertEquals('SELECT * FROM `table`', $select); @@ -265,12 +264,17 @@ public function testCompileSelect() $select = $grammar->compileSelect($this->getBuilder()->anyLeftJoin('table', ['column'], true)); $this->assertEquals('SELECT * GLOBAL ANY LEFT JOIN `table` USING `column`', $select); - - $select = $grammar->compileSelect($this->getBuilder()->anyLeftJoin(function(JoinClause $join) { + + $select = $grammar->compileSelect($this->getBuilder()->anyLeftJoin(function (JoinClause $join) { $join->table($this->getBuilder()->table('test')->select('column')); }, ['column'], true)); $this->assertEquals('SELECT * GLOBAL ANY LEFT JOIN (SELECT `column` FROM `test`) USING `column`', $select); + $select = $grammar->compileSelect($this->getBuilder()->anyLeftJoin(function (JoinClause $join) { + $join->subQuery('test')->table('table'); + }, ['column'])); + $this->assertEquals('SELECT * ANY LEFT JOIN (SELECT * FROM `table`) AS `test` USING `column`', $select); + /* * With complex two elements logic expressions */ @@ -343,20 +347,20 @@ public function testCompileDelete() $sql = $grammar->compileDelete($builder); $this->assertEquals('ALTER TABLE `table` DELETE WHERE `column` = 1', $sql); - + $builder = $this->getBuilder(); $builder->from('table')->where('column', 1)->onCluster('test'); - + $sql = $grammar->compileDelete($builder); - + $this->assertEquals('ALTER TABLE `table` ON CLUSTER test DELETE WHERE `column` = 1', $sql); - + $builder = $this->getBuilder(); $builder->from('table'); - + $this->expectException(GrammarException::class); $this->expectExceptionMessage('Missed where section for delete statement.'); - + $grammar->compileDelete($builder); } } diff --git a/tests/JoinClauseTest.php b/tests/JoinClauseTest.php index d71402a..9223d64 100644 --- a/tests/JoinClauseTest.php +++ b/tests/JoinClauseTest.php @@ -61,6 +61,14 @@ public function testSettersGetters() $join->distributed(true); $this->assertTrue($join->isDistributed()); + + $alias = 'test'; + $join->as($alias); + $this->assertEquals($join->getAlias(), $alias); + + $alias = 'test1'; + $join->subQuery($alias); + $this->assertEquals($join->getAlias(), $alias); } public function testQuery()