From 6e9862c82caa1c9e7ee103c25bda13ce31e01c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Wed, 21 Feb 2024 16:06:33 +0100 Subject: [PATCH] do no wrap inner from in extra select --- src/Model/UnionModel.php | 30 ++++++++++++++++-------------- tests/ModelUnionTest.php | 33 ++++++++++++++------------------- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/Model/UnionModel.php b/src/Model/UnionModel.php index 22ff6f56a1..939c5f1fd5 100644 --- a/src/Model/UnionModel.php +++ b/src/Model/UnionModel.php @@ -96,7 +96,7 @@ public function addNestedModel(Model $model, array $fieldMap = []): Model */ public function actionSelectInnerTable() { - return $this->action('select'); + return $this->createSubQuery(null); } #[\Override] @@ -105,28 +105,21 @@ 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': @@ -134,7 +127,7 @@ public function action(string $mode, array $args = []) return parent::action($mode, $args); /* $args['alias'] = 'val'; - $subquery = $this->getSubAction($mode, $args); + $subquery = $this->createSubAction($mode, $args); $args = [$args[0], $this->expr('{}', ['val'])]; @@ -170,8 +163,17 @@ private function createUnionQuery(array $subqueries): Persistence\Sql\Query * * @param list $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 @@ -219,7 +221,7 @@ public function getSubQuery(array $fields): Persistence\Sql\Query /** * @param array $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]) { diff --git a/tests/ModelUnionTest.php b/tests/ModelUnionTest.php index ebd4f1ade2..bc8f62d8a0 100644 --- a/tests/ModelUnionTest.php +++ b/tests/ModelUnionTest.php @@ -65,30 +65,30 @@ 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\'']); @@ -96,7 +96,7 @@ public function testMissingField(): void $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] ); } @@ -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] ); } @@ -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] ); } @@ -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] ); @@ -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] ); } @@ -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`, `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` `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] ); }