From 9b34314d1ef8c6fd7e77451fe9bf0abdc12c27ea Mon Sep 17 00:00:00 2001 From: Patrice Bender Date: Mon, 2 Sep 2024 16:07:32 +0200 Subject: [PATCH] fix: prepend aliases to refs within function args in on conditions (#795) we need to drill recursively into the function arguments found in on-conditions and prepend aliases of the outer query in case of scoped queries / expands fixes #779 Co-authored-by: Johannes Vogel <31311694+johannes-vogel@users.noreply.github.com> --- db-service/lib/cqn4sql.js | 5 +++ db-service/test/bookshop/db/schema.cds | 7 ++++ db-service/test/cqn4sql/table-alias.test.js | 43 +++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/db-service/lib/cqn4sql.js b/db-service/lib/cqn4sql.js index 155d0efaa..561e2c606 100644 --- a/db-service/lib/cqn4sql.js +++ b/db-service/lib/cqn4sql.js @@ -1853,6 +1853,11 @@ function cqn4sql(originalQuery, model) { result[i] = asXpr(xpr) continue } + if(lhs.args) { + const args = calculateOnCondition(lhs.args) + result[i] = { ...lhs, args } + continue + } const rhs = result[i + 2] if (rhs?.ref || lhs.ref) { // if we have refs on each side of the comparison, we might need to perform tuple expansion diff --git a/db-service/test/bookshop/db/schema.cds b/db-service/test/bookshop/db/schema.cds index 11be15b7a..c8f8a62f9 100644 --- a/db-service/test/bookshop/db/schema.cds +++ b/db-service/test/bookshop/db/schema.cds @@ -422,3 +422,10 @@ entity Item { key ID: Integer; item: Association to Item; } + +entity Posts { + key ID: Integer; + name: String; + iSimilar: Association to many Posts on UPPER(name) = UPPER(iSimilar.name); + iSimilarNested: Association to many Posts on UPPER(iSimilarNested.name) = UPPER(LOWER(UPPER(name)), name); +} diff --git a/db-service/test/cqn4sql/table-alias.test.js b/db-service/test/cqn4sql/table-alias.test.js index bed39dd34..ecaceac1f 100644 --- a/db-service/test/cqn4sql/table-alias.test.js +++ b/db-service/test/cqn4sql/table-alias.test.js @@ -263,6 +263,49 @@ describe('table alias access', () => { let result = cqn4sql(query, model) expect(result).to.deep.equal(expected) }) + + it('refs in function args in on condition are aliased', () => { + let query = CQL` + SELECT + ID, + iSimilar { name } + from bookshop.Posts` + + const expected = CQL` + SELECT + Posts.ID, + ( + SELECT from bookshop.Posts as iSimilar { + iSimilar.name + } + where UPPER(Posts.name) = UPPER(iSimilar.name) + ) as iSimilar + from bookshop.Posts as Posts` + + let result = cqn4sql(query, model) + expect(JSON.parse(JSON.stringify(result))).to.deep.equal(expected) + }) + it('refs in nested function args in on condition are aliased', () => { + let query = CQL` + SELECT + ID, + iSimilarNested { name } + from bookshop.Posts` + + const expected = CQL` + SELECT + Posts.ID, + ( + SELECT from bookshop.Posts as iSimilarNested { + iSimilarNested.name + } + where UPPER(iSimilarNested.name) = UPPER(LOWER(UPPER(Posts.name)), Posts.name) + ) as iSimilarNested + from bookshop.Posts as Posts` + + let result = cqn4sql(query, model) + expect(JSON.parse(JSON.stringify(result))).to.deep.equal(expected) + }) }) describe('replace $self references', () => {