From b7b1562111eb8e942380f56e9f5531eee39f8302 Mon Sep 17 00:00:00 2001 From: Yurii Date: Tue, 3 Feb 2026 14:54:36 +0200 Subject: [PATCH] ORM: no alias --- application/Espo/ORM/Query/Part/Selection.php | 17 +++++++++++++++++ application/Espo/ORM/Query/SelectBuilder.php | 4 ++-- .../ORM/QueryComposer/BaseQueryComposer.php | 15 +++++++++++++-- tests/unit/Espo/ORM/MysqlQueryComposerTest.php | 9 +++++---- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/application/Espo/ORM/Query/Part/Selection.php b/application/Espo/ORM/Query/Part/Selection.php index baf93d01d0..8686303228 100644 --- a/application/Espo/ORM/Query/Part/Selection.php +++ b/application/Espo/ORM/Query/Part/Selection.php @@ -63,6 +63,10 @@ class Selection ); } + /** + * With an alias. With null, the field name will be used as an alias or an expression itself. + * Use `withNoAlias` to prevent alias addition. + */ public function withAlias(?string $alias): self { $obj = clone $this; @@ -70,4 +74,17 @@ class Selection return $obj; } + + /** + * With on alias. + * + * @since 9.3.0 + */ + public function withNoAlias(): self + { + $obj = clone $this; + $obj->alias = ''; + + return $obj; + } } diff --git a/application/Espo/ORM/Query/SelectBuilder.php b/application/Espo/ORM/Query/SelectBuilder.php index 9e558c7562..a14e2374d5 100644 --- a/application/Espo/ORM/Query/SelectBuilder.php +++ b/application/Espo/ORM/Query/SelectBuilder.php @@ -166,7 +166,7 @@ class SelectBuilder implements Builder if (is_string($select)) { $this->params['select'] = $this->params['select'] ?? []; - $this->params['select'][] = $alias ? + $this->params['select'][] = $alias !== null ? [$select, $alias] : $select; @@ -321,7 +321,7 @@ class SelectBuilder implements Builder } if ($item instanceof Selection) { - $resultList[] = $item->getAlias() ? + $resultList[] = $item->getAlias() !== null ? [$item->getExpression()->getValue(), $item->getAlias()] : [$item->getExpression()->getValue()]; diff --git a/application/Espo/ORM/QueryComposer/BaseQueryComposer.php b/application/Espo/ORM/QueryComposer/BaseQueryComposer.php index 701cd6343a..2baf9a1980 100644 --- a/application/Espo/ORM/QueryComposer/BaseQueryComposer.php +++ b/application/Espo/ORM/QueryComposer/BaseQueryComposer.php @@ -1793,11 +1793,22 @@ abstract class BaseQueryComposer implements QueryComposer foreach ($itemPairList as $item) { $expression = $item[0]; + + if ($expression === '') { + throw new RuntimeException("Bad select expression."); + } + + if ($item[1] === '') { + $selectPartItemList[] = $expression; + + continue; + } + /** @noinspection PhpDeprecationInspection */ $alias = $this->sanitizeSelectAlias($item[1]); - if ($expression === '' || $alias === '') { - throw new RuntimeException("Bad select expression."); + if ($alias === '') { + throw new RuntimeException("Bad alias."); } $selectPartItemList[] = "$expression AS " . $this->quoteIdentifier($alias); diff --git a/tests/unit/Espo/ORM/MysqlQueryComposerTest.php b/tests/unit/Espo/ORM/MysqlQueryComposerTest.php index 6d6c29fb3b..90c9a90e1b 100644 --- a/tests/unit/Espo/ORM/MysqlQueryComposerTest.php +++ b/tests/unit/Espo/ORM/MysqlQueryComposerTest.php @@ -31,6 +31,7 @@ namespace tests\unit\Espo\ORM; use Espo\ORM\Query\Part\Condition as Cond; use Espo\ORM\Query\Part\Join; +use Espo\ORM\Query\Part\Selection; use Espo\ORM\Query\Part\Where\Comparison; use Espo\ORM\Query\Part\WhereClause; use Espo\ORM\Query\SelectBuilder; @@ -3644,7 +3645,7 @@ class MysqlQueryComposerTest extends TestCase ->query( SelectBuilder::create() ->select([ - 'order', + Selection::fromString('order')->withNoAlias(), 'id', 'parentId' ]) @@ -3655,7 +3656,7 @@ class MysqlQueryComposerTest extends TestCase ->query( SelectBuilder::create() ->select([ - 'order', + Selection::fromString('order')->withNoAlias(), 'id', 'parentId', ]) @@ -3691,9 +3692,9 @@ class MysqlQueryComposerTest extends TestCase $expected = "WITH RECURSIVE `common_table` AS (" . - "(SELECT category.order AS `order`, category.id AS `id`, category.parent_id AS `parentId` FROM `category` " . + "(SELECT category.order, category.id AS `id`, category.parent_id AS `parentId` FROM `category` " . "WHERE category.parent_id IS NULL) UNION ALL " . - "(SELECT category.order AS `order`, category.id AS `id`, category.parent_id AS `parentId` FROM `category` " . + "(SELECT category.order, category.id AS `id`, category.parent_id AS `parentId` FROM `category` " . "JOIN `common_table` AS `comTab` ON comTab.id = category.parent_id " . "WHERE category.parent_id IS NULL)) SELECT test.id AS `id` FROM `test` AS `test` " . "JOIN `common_table` AS `comTab` ON comTab.id = test.category_id";