Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: nested ternary in calculated element #981

Merged
merged 3 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion db-service/lib/infer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ function infer(originalQuery, model) {
} else if (arg.xpr || arg.args) {
const prop = arg.xpr ? 'xpr' : 'args'
arg[prop].forEach(step => {
const subPath = { $refLinks: [...basePath.$refLinks], ref: [...basePath.ref] }
let subPath = { $refLinks: [...basePath.$refLinks], ref: [...basePath.ref] }
if (step.ref) {
step.$refLinks.forEach((link, i) => {
const { definition } = link
Expand All @@ -874,6 +874,10 @@ function infer(originalQuery, model) {
} else if (step.args || step.xpr) {
const nestedProp = step.xpr ? 'xpr' : 'args'
step[nestedProp].forEach(a => {
// reset sub path for each nested argument
// e.g. case when <path> then <otherPath> else <anotherPath> end
if(!a.ref)
subPath = { $refLinks: [...basePath.$refLinks], ref: [...basePath.ref] }
mergePathsIntoJoinTree(a, subPath)
})
}
Expand Down
10 changes: 10 additions & 0 deletions db-service/test/bookshop/db/booksWithExpr.cds
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,13 @@ entity VariableReplacements {
// with variable replacements
authorAlive = author[dateOfBirth <= $now and dateOfDeath >= $now and $user.unknown.foo.bar = 'Bob'];
}

entity Ternary {
key ID : Integer;
value : Integer;
book : Association to Books;
nestedTernary : Integer = (1 > 0 ? 1 : (book.stock > 10 ? value : 3));
nestedTernaryWithTwoJoins : Integer = (1 > 0 ? 1 : (book.stock > book.author.age ? value : 3));
nestedTernaryWithNestedXpr : Integer = (1 > 0 ? 1 : (((10 + book.stock) in (1, 2, 3 , 4)) ? value : 3));
calculatedElementInNestedTernary : Integer = (1 > 0 ? 1 : (book.stock > nestedTernaryWithTwoJoins ? value : 3));
}
33 changes: 33 additions & 0 deletions db-service/test/cqn4sql/calculated-elements.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,39 @@ describe('Unfolding calculated elements in select list', () => {
expect(query).to.deep.equal(expected)
})

it('in ternary', () => {
let query = cqn4sql(CQL`SELECT from booksCalc.Ternary { ID, nestedTernary }`, model)
const expected = CQL`SELECT from booksCalc.Ternary as Ternary
left join booksCalc.Books as book on book.ID = Ternary.book_ID
{
Ternary.ID,
(case when 1 > 0 then 1 else (case when book.stock > 10 then Ternary.value else 3 end) end) as nestedTernary
}`
expect(query).to.deep.equal(expected)
})

it('calcualted element in nested ternary', () => {
let query = cqn4sql(CQL`SELECT from booksCalc.Ternary { ID, calculatedElementInNestedTernary }`, model)
const expected = CQL`SELECT from booksCalc.Ternary as Ternary
left join booksCalc.Books as book on book.ID = Ternary.book_ID
left join booksCalc.Authors as author on author.ID = book.author_ID
{
Ternary.ID,
(case when 1 > 0 then 1 else (case when book.stock > (case when 1 > 0 then 1 else (case when book.stock > years_between(author.dateOfBirth, author.dateOfDeath) then Ternary.value else 3 end) end) then Ternary.value else 3 end) end) as calculatedElementInNestedTernary
}`
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
expect(query).to.deep.equal(expected)
})
it('list in ternary', () => {
let query = cqn4sql(CQL`SELECT from booksCalc.Ternary { ID, nestedTernaryWithNestedXpr }`, model)
const expected = CQL`SELECT from booksCalc.Ternary as Ternary
left join booksCalc.Books as book on book.ID = Ternary.book_ID
{
Ternary.ID,
(case when 1 > 0 then 1 else (case when ( (10 + book.stock) in (1, 2, 3, 4) ) then Ternary.value else 3 end) end) as nestedTernaryWithNestedXpr
}`
expect(query).to.deep.equal(expected)
})
it('in function', () => {
let query = cqn4sql(CQL`SELECT from booksCalc.Books { ID, round(area, 2) as f }`, model)
const expected = CQL`SELECT from booksCalc.Books as Books {
Expand Down
Loading