diff --git a/db-service/lib/cqn4sql.js b/db-service/lib/cqn4sql.js index 0dc5a4e75..60569c547 100644 --- a/db-service/lib/cqn4sql.js +++ b/db-service/lib/cqn4sql.js @@ -388,13 +388,6 @@ function cqn4sql(originalQuery, model = cds.context?.model || cds.model) { return transformedColumns function handleSubquery(col) { - if (!col.SELECT.from.as) { - const uniqueSubqueryAlias = inferred.joinTree.addNextAvailableTableAlias( - getLastStringSegment(col.SELECT.from.ref[col.SELECT.from.ref.length - 1]), - originalQuery.outerQueries, - ) - Object.defineProperty(col.SELECT.from, 'uniqueSubqueryAlias', { value: uniqueSubqueryAlias }) - } transformedColumns.push(() => { const res = transformSubquery(col) if (col.as) res.as = col.as @@ -442,7 +435,7 @@ function cqn4sql(originalQuery, model = cds.context?.model || cds.model) { } let columnAlias = col.as || (col.isJoinRelevant ? col.flatName : null) - const refNavigation = col.ref.slice(col.ref[0] === tableAlias ? 1 : 0).join('_') + const refNavigation = col.ref.slice(col.$refLinks[0].definition.kind !== 'element' ? 1 : 0).join('_') if (!columnAlias && col.flatName && col.flatName !== refNavigation) columnAlias = refNavigation if (col.$refLinks.some(link => link.definition._target?.['@cds.persistence.skip'] === true)) return @@ -918,7 +911,17 @@ function cqn4sql(originalQuery, model = cds.context?.model || cds.model) { Object.defineProperty(q, 'outerQueries', { value: outerQueries }) } if (isLocalized(inferred.target)) q.SELECT.localized = true + if (q.SELECT.from.ref && !q.SELECT.from.as) assignUniqueSubqueryAlias() return cqn4sql(q, model) + + function assignUniqueSubqueryAlias() { + if (q.SELECT.from.uniqueSubqueryAlias) return + const uniqueSubqueryAlias = inferred.joinTree.addNextAvailableTableAlias( + getLastStringSegment(q.SELECT.from.ref[q.SELECT.from.ref.length - 1]), + originalQuery.outerQueries, + ) + Object.defineProperty(q.SELECT.from, 'uniqueSubqueryAlias', { value: uniqueSubqueryAlias }) + } } /** diff --git a/db-service/lib/infer/join-tree.js b/db-service/lib/infer/join-tree.js index 1fa2902bc..d1257d11c 100644 --- a/db-service/lib/infer/join-tree.js +++ b/db-service/lib/infer/join-tree.js @@ -101,9 +101,6 @@ class JoinTree { Object.entries(sources).forEach(entry => { const alias = this.addNextAvailableTableAlias(entry[0]) this._roots.set(alias, new Root(entry)) - if (entry[1].sources) - // respect outer aliases - this.addAliasesOfSubqueryInFrom(entry[1].sources) }) } diff --git a/db-service/test/cqn2sql/__snapshots__/expression.test.js.snap b/db-service/test/cqn2sql/__snapshots__/expression.test.js.snap index 284dd47c9..6825afe6f 100644 --- a/db-service/test/cqn2sql/__snapshots__/expression.test.js.snap +++ b/db-service/test/cqn2sql/__snapshots__/expression.test.js.snap @@ -55,7 +55,7 @@ exports[`expressions with complex xpr 1`] = ` exports[`expressions with exists 1`] = ` { - "sql": "SELECT Foo.ID,Foo.a,Foo.b,Foo.c,Foo.x FROM Foo as Foo WHERE exists (SELECT Foo2.name FROM Foo2 as Foo2) or not exists (SELECT Foo2.name FROM Foo2 as Foo2)", + "sql": "SELECT Foo.ID,Foo.a,Foo.b,Foo.c,Foo.x FROM Foo as Foo WHERE exists (SELECT Foo2.name FROM Foo2 as Foo2) or not exists (SELECT Foo22.name FROM Foo2 as Foo22)", "values": [], } `; diff --git a/db-service/test/cqn2sql/__snapshots__/select.test.js.snap b/db-service/test/cqn2sql/__snapshots__/select.test.js.snap index ff7693df6..7e04923d6 100644 --- a/db-service/test/cqn2sql/__snapshots__/select.test.js.snap +++ b/db-service/test/cqn2sql/__snapshots__/select.test.js.snap @@ -32,9 +32,9 @@ exports[`cqn2sql WHERE entries where with place holder 1`] = ` } `; -exports[`cqn2sql WHERE select with a nested select in a complex where 1`] = `"SELECT Foo.a,Foo.b,Foo.c FROM Foo as Foo WHERE ( Foo.x + 1 ) < 9 AND Foo.x IN (SELECT Foo.a FROM Foo as Foo WHERE Foo.x < 9)"`; +exports[`cqn2sql WHERE select with a nested select in a complex where 1`] = `"SELECT Foo.a,Foo.b,Foo.c FROM Foo as Foo WHERE ( Foo.x + 1 ) < 9 AND Foo.x IN (SELECT Foo2.a FROM Foo as Foo2 WHERE Foo2.x < 9)"`; -exports[`cqn2sql WHERE select with a nested select in where 1`] = `"SELECT Foo.a,Foo.b,Foo.c FROM Foo as Foo WHERE Foo.x IN (SELECT Foo.a FROM Foo as Foo WHERE Foo.x < 9)"`; +exports[`cqn2sql WHERE select with a nested select in where 1`] = `"SELECT Foo.a,Foo.b,Foo.c FROM Foo as Foo WHERE Foo.x IN (SELECT Foo2.a FROM Foo as Foo2 WHERE Foo2.x < 9)"`; exports[`cqn2sql WHERE where with partial cqn 1`] = `"SELECT Foo.ID,Foo.a,Foo.b,Foo.c,Foo.x FROM Foo as Foo WHERE (Foo.x = 9)"`; @@ -128,7 +128,7 @@ exports[`cqn2sql quoted column aliases select with subselect in exists and colum exports[`cqn2sql quoted column aliases select with subselect with in and column aliases 1`] = ` { - "sql": "SELECT Foo.a as A,? as ABC,Foo.x + 1 as Xpr1 FROM Foo as Foo WHERE ( Foo.x + 1 ) < 9 AND Foo.x IN (SELECT Foo.a as B,Foo.x - 4 as Xpr2 FROM Foo as Foo WHERE Foo.x < 9)", + "sql": "SELECT Foo.a as A,? as ABC,Foo.x + 1 as Xpr1 FROM Foo as Foo WHERE ( Foo.x + 1 ) < 9 AND Foo.x IN (SELECT Foo2.a as B,Foo2.x - 4 as Xpr2 FROM Foo as Foo2 WHERE Foo2.x < 9)", "values": [ "abc", ], diff --git a/db-service/test/cqn4sql/assocs2joins.test.js b/db-service/test/cqn4sql/assocs2joins.test.js index 40c76031c..98db6abd2 100644 --- a/db-service/test/cqn4sql/assocs2joins.test.js +++ b/db-service/test/cqn4sql/assocs2joins.test.js @@ -926,13 +926,13 @@ describe('subqueries in from', () => { model, ) const expected = CQL`SELECT from ( - SELECT from bookshop.Books as Books - left outer join bookshop.Authors as author on author.ID = Books.author_ID - { Books.author_ID, Books.author_ID as a_ID, author.name as author_name } + SELECT from bookshop.Books as Books2 + left outer join bookshop.Authors as author on author.ID = Books2.author_ID + { Books2.author_ID, Books2.author_ID as a_ID, author.name as author_name } ) as Bar left outer join bookshop.Authors as a on a.ID = Bar.a_ID - left outer join bookshop.Books as books2 on books2.author_ID = a.ID - { Bar.author_name, books2.descr as a_books_descr} + left outer join bookshop.Books as books on books.author_ID = a.ID + { Bar.author_name, books.descr as a_books_descr} ` expect(query).to.deep.equal(expected) }) diff --git a/db-service/test/cqn4sql/table-alias.test.js b/db-service/test/cqn4sql/table-alias.test.js index b4c102d4c..840d17edb 100644 --- a/db-service/test/cqn4sql/table-alias.test.js +++ b/db-service/test/cqn4sql/table-alias.test.js @@ -674,7 +674,7 @@ describe('table alias access', () => { model, ) expect(query).to.deep.equal( - CQL`SELECT from (SELECT from bookshop.Books as Books { Books.ID, Books.stock }) as Books { Books.ID, Books.stock }`, + CQL`SELECT from (SELECT from bookshop.Books as Books2 { Books2.ID, Books2.stock }) as Books { Books.ID, Books.stock }`, ) }) it('explicit alias for FROM subquery', () => { @@ -930,7 +930,7 @@ describe('table alias access', () => { where: [ { list: [{ ref: ['dedication', 'addressee', 'ID'] }] }, 'in', - CQL`SELECT Books2.ID from bookshop.Books as Books2 where Books2.ID = 5`, + CQL`SELECT ID from bookshop.Books where ID = 5`, ], }, ],