Skip to content

Commit

Permalink
do no wrap inner from in extra select
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed Feb 21, 2024
1 parent 6a5f2b8 commit a82a108
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 33 deletions.
30 changes: 16 additions & 14 deletions src/Model/UnionModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public function addNestedModel(Model $model, array $fieldMap = []): Model
*/
public function actionSelectInnerTable()
{
return $this->action('select');
return $this->createSubQuery(null);
}

#[\Override]
Expand All @@ -105,36 +105,29 @@ public function action(string $mode, array $args = [])
$subquery = null;
switch ($mode) {
case 'select':
// get list of available fields
$fields = $this->onlyFields ?? array_keys($this->getFields());
foreach ($fields as $k => $field) {
if ($this->getField($field)->neverPersist) {
unset($fields[$k]);
}
}
$subquery = $this->getSubQuery($fields);
$subquery = $this->createSubQuery(null);
$query = parent::action($mode, $args)->reset('table')->table($subquery, $this->tableAlias);

$this->hook(self::HOOK_INIT_UNION_SELECT_QUERY, [$query]);

return $query;
case 'count':
$subquery = $this->getSubAction('count', ['alias' => 'cnt']);
$subquery = $this->createSubAction('count', ['alias' => 'cnt']);

$mode = 'fx';
$args = ['sum', $this->expr('{}', ['cnt'])];

break;
case 'field':
$subquery = $this->getSubQuery([$args[0]]);
$subquery = $this->createSubQuery([$args[0]]);

break;
case 'fx':
case 'fx0':
return parent::action($mode, $args);
/* $args['alias'] = 'val';
$subquery = $this->getSubAction($mode, $args);
$subquery = $this->createSubAction($mode, $args);
$args = [$args[0], $this->expr('{}', ['val'])];
Expand Down Expand Up @@ -170,8 +163,17 @@ private function createUnionQuery(array $subqueries): Persistence\Sql\Query
*
* @param list<string> $fields
*/
public function getSubQuery(array $fields): Persistence\Sql\Query
public function createSubQuery(?array $fields): Persistence\Sql\Query
{
if ($fields === null) {
$fields = $this->onlyFields ?? array_keys($this->getFields());
foreach ($fields as $k => $field) {
if ($this->getField($field)->neverPersist) {
unset($fields[$k]);
}
}
}

$subqueries = [];
foreach ($this->union as [$nestedModel, $fieldMap]) {
// map fields for related model
Expand Down Expand Up @@ -219,7 +221,7 @@ public function getSubQuery(array $fields): Persistence\Sql\Query
/**
* @param array<mixed> $actionArgs
*/
public function getSubAction(string $action, array $actionArgs = []): Persistence\Sql\Query
public function createSubAction(string $action, array $actionArgs = []): Persistence\Sql\Query
{
$subqueries = [];
foreach ($this->union as [$model, $fieldMap]) {
Expand Down
33 changes: 14 additions & 19 deletions tests/ModelUnionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,38 +65,38 @@ public function testFieldExpr(): void
$this->assertSameSql('-NULL', $transaction->expr('[]', [$transaction->getFieldExpr($transaction->nestedInvoice, 'blah', '-[]')])->render()[0]);
}

public function testNestedQuery1(): void
public function testCreateSubQueryBasic(): void
{
$transaction = $this->createTransaction();

$this->assertSameSql(
'select `name` `name` from `invoice` UNION ALL select `name` `name` from `payment`',
$transaction->getSubQuery(['name'])->render()[0]
$transaction->createSubQuery(['name'])->render()[0]
);

$this->assertSameSql(
'select `name` `name`, `amount` `amount` from `invoice` UNION ALL select `name` `name`, `amount` `amount` from `payment`',
$transaction->getSubQuery(['name', 'amount'])->render()[0]
$transaction->createSubQuery(['name', 'amount'])->render()[0]
);

$this->assertSameSql(
'select `name` `name` from `invoice` UNION ALL select `name` `name` from `payment`',
$transaction->getSubQuery(['name'])->render()[0]
$transaction->createSubQuery(['name'])->render()[0]
);
}

/**
* If field is not set for one of the nested model, instead of generating exception, NULL will be filled in.
*/
public function testMissingField(): void
public function testCreateSubQueryMissingField(): void
{
$transaction = $this->createTransaction();
$transaction->nestedInvoice->addExpression('type', ['expr' => '\'invoice\'']);
$transaction->addField('type');

$this->assertSameSql(
'select (\'invoice\') `type`, `amount` `amount` from `invoice` UNION ALL select NULL `type`, `amount` `amount` from `payment`',
$transaction->getSubQuery(['type', 'amount'])->render()[0]
$transaction->createSubQuery(['type', 'amount'])->render()[0]
);
}

Expand All @@ -120,16 +120,14 @@ public function testActions(): void
);

$this->assertSameSql(
// QUERY IS WIP
'select sum(`amount`) from (select `client_id`, `name`, `amount` from (select `client_id` `client_id`, `name` `name`, `amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_tu`) `_tu`',
'select sum(`amount`) from (select `client_id` `client_id`, `name` `name`, `amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_tu`',
$transaction->action('fx', ['sum', 'amount'])->render()[0]
);

$transaction = $this->createSubtractInvoiceTransaction();

$this->assertSameSql(
// QUERY IS WIP
'select sum(`amount`) from (select `client_id`, `name`, `amount` from (select `client_id` `client_id`, `name` `name`, -`amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_tu`) `_tu`',
'select sum(`amount`) from (select `client_id` `client_id`, `name` `name`, -`amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_tu`',
$transaction->action('fx', ['sum', 'amount'])->render()[0]
);
}
Expand All @@ -144,13 +142,13 @@ public function testActions2(): void
self::assertSame(-9.0, (float) $transaction->action('fx', ['sum', 'amount'])->getOne());
}

public function testSubAction1(): void
public function testCreateSubAction(): void
{
$transaction = $this->createSubtractInvoiceTransaction();

$this->assertSameSql(
'select sum(-`amount`) from `invoice` UNION ALL select sum(`amount`) from `payment`',
$transaction->getSubAction('fx', ['sum', 'amount'])->render()[0]
$transaction->createSubAction('fx', ['sum', 'amount'])->render()[0]
);
}

Expand Down Expand Up @@ -327,8 +325,7 @@ public function testReference(): void
self::assertSame(29.0, (float) $client->load(1)->ref('tr')->action('fx', ['sum', 'amount'])->getOne());

$this->assertSameSql(
// QUERY IS WIP
'select sum(`amount`) from (select `client_id`, `name`, `amount` from (select `client_id` `client_id`, `name` `name`, `amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_tu`) `_t_e7d707a26e7f` where `client_id` = :a',
'select sum(`amount`) from (select `client_id` `client_id`, `name` `name`, `amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_t_e7d707a26e7f` where `client_id` = :a',
$client->load(1)->ref('tr')->action('fx', ['sum', 'amount'])->render()[0]
);

Expand All @@ -340,8 +337,7 @@ public function testReference(): void
self::assertSame(-9.0, (float) $client->load(1)->ref('tr')->action('fx', ['sum', 'amount'])->getOne());

$this->assertSameSql(
// QUERY IS WIP
'select sum(`amount`) from (select `client_id`, `name`, `amount` from (select `client_id` `client_id`, `name` `name`, -`amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_tu`) `_t_e7d707a26e7f` where `client_id` = :a',
'select sum(`amount`) from (select `client_id` `client_id`, `name` `name`, -`amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_t_e7d707a26e7f` where `client_id` = :a',
$client->load(1)->ref('tr')->action('fx', ['sum', 'amount'])->render()[0]
);
}
Expand All @@ -362,10 +358,9 @@ public function testFieldAggregateUnion(): void
self::assertNull($client->tryLoad(3));

$this->assertSameSql(
// QUERY IS WIP
$this->getDatabasePlatform() instanceof SQLServerPlatform || $this->getDatabasePlatform() instanceof OraclePlatform
? 'select `id`, `name`, `surname`, `order`, (select coalesce(sum(`amount`), 0) from (select `client_id`, `name`, `amount` from (select `client_id` `client_id`, `name` `name`, `amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_tu`) `_t_e7d707a26e7f` where `client_id` = `client`.`id`) `balance` from `client` group by `id`, `id`, `name`, `surname`, `order`, (select coalesce(sum(`amount`), 0) from (select `client_id`, `name`, `amount` from (select `client_id` `client_id`, `name` `name`, `amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_tu`) `_t_e7d707a26e7f` where `client_id` = `client`.`id`) having `id` = :a'
: 'select `id`, `name`, `surname`, `order`, (select coalesce(sum(`amount`), 0) from (select `client_id`, `name`, `amount` from (select `client_id` `client_id`, `name` `name`, `amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_tu`) `_t_e7d707a26e7f` where `client_id` = `client`.`id`) `balance` from `client` group by `id` having `id` = :a',
? 'select `id`, `name`, `surname`, `order`, (select coalesce(sum(`amount`), 0) from (select `client_id` `client_id`, `name` `name`, `amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_t_e7d707a26e7f` where `client_id` = `client`.`id`) `balance` from `client` group by `id`, `id`, `name`, `surname`, `order`, (select coalesce(sum(`amount`), 0) from (select `client_id` `client_id`, `name` `name`, `amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_t_e7d707a26e7f` where `client_id` = `client`.`id`) having `id` = :a'
: 'select `id`, `name`, `surname`, `order`, (select coalesce(sum(`amount`), 0) from (select `client_id` `client_id`, `name` `name`, `amount` `amount` from `invoice` UNION ALL select `client_id` `client_id`, `name` `name`, `amount` `amount` from `payment`) `_t_e7d707a26e7f` where `client_id` = `client`.`id`) `balance` from `client` group by `id` having `id` = :a',
$client->load(1)->action('select')->render()[0]
);
}
Expand Down

0 comments on commit a82a108

Please sign in to comment.