-
Notifications
You must be signed in to change notification settings - Fork 14
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: Improved placeholders and limit clause #567
Conversation
@@ -1,8 +1,8 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
|
|||
exports[`delete test complex cascade delete for entity with 'not exists' 1`] = `"DELETE FROM Books as Books WHERE ( Books.author_id is not null or Books.author_version is not null ) and not exists (SELECT 1 as _exists FROM Author as Author left JOIN Books as parent ON parent.ID = Author.parent_ID WHERE Author.parent_ID = parent.code and parent.descr = Author.version)"`; | |||
exports[`delete test complex cascade delete for entity with 'not exists' 1`] = `"DELETE FROM Books as Books WHERE ( Books.author_id is not null or Books.author_version is not null ) and not exists (SELECT ? as _exists FROM Author as Author left JOIN Books as parent ON parent.ID = Author.parent_ID WHERE Author.parent_ID = parent.code and parent.descr = Author.version)"`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to detect SELECT 1? That's a common pattern in our implementation that we could also try to put in SQL string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also a requirement for it to work with the hdb
driver on HANA. As it checks the datatype of the place holder and of the data send to the placeholder. When doing SELECT ?
the type of ?
resolves to VARCHAR
and then sending 1
the driver rejects the request. So now when a column is a {val:...}
it will always be inlined as otherwise all type information is lost.
Blocked: HDBCLIENT-1254 (planned: Q3.2024) |
@@ -290,7 +290,7 @@ class CQN2SQLRenderer { | |||
return `extensions__->${this.string('$."' + x.element.name + '"')} as ${x.as || x.element.name}` | |||
} | |||
/////////////////////////////////////////////////////////////////////////////////////// | |||
let sql = this.expr(x) | |||
let sql = this.expr({ param: false, __proto__: x }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When selecting static values it is required to always inline them. Otherwise typed databases are confused what type it is supposed to return and causes trouble with SELECT 1
as SELECT ?
will only accept strings as parameters as the default type of ?
is nvarchar
. Breaking a lot of queries.
db-service/lib/cqn2sql.js
Outdated
* @param {import('./infer/cqn').val} param0 | ||
* @returns {string} SQL | ||
*/ | ||
val({ val, param }) { | ||
const inline = !this.values || param === false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you pull that up here, if we still only need that down there in line 907, only if we reach that, of course?
switch (typeof val) { | ||
case 'string': return this.string(val) | ||
case 'object': return 'NULL' | ||
default: | ||
return `${val}` | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did the old code work before and not anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before the only value that would arrive here where strings. Now it can also be numbers and null
. It could also have Booleans, but currently they are still being in lined.
case 'boolean': return `${val}` | ||
case 'number': return `${val}` // REVISIT for HANA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we pass numbers as bind parameters anymore? Has that advantages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is including numbers as binding parameters again.
🤖 I have created a release *beep* *boop* --- <details><summary>db-service: 1.9.0</summary> ## [1.9.0](db-service-v1.8.0...db-service-v1.9.0) (2024-05-08) ### Added * Add missing `func` cqn structures ([#629](#629)) ([9d7539a](9d7539a)) ### Fixed * **`order by`:** reject non-fk traversals of own columns in order by ([#599](#599)) ([3288d63](3288d63)) * Align all quote functions with @sap/cds-compiler ([#619](#619)) ([42e9828](42e9828)) * assign artificial alias if selecting from anonymous subquery ([#608](#608)) ([e1a7711](e1a7711)) * avoid spread operator ([#630](#630)) ([a39fb65](a39fb65)) * flat update with arbitrary where clauses ([#598](#598)) ([f108798](f108798)) * improved `=` and `!=` with val `null` for HANA and Postgres ([#626](#626)) ([cbcfe3b](cbcfe3b)) * Improved placeholders and limit clause ([#567](#567)) ([d5d5dbb](d5d5dbb)) * multiple result responses ([#602](#602)) ([bf0bed4](bf0bed4)) * only consider persisted columns for simple operations ([#592](#592)) ([6e31bda](6e31bda)) ### Changed * require `>= sap/cds-compiler@4.9` ([f4d09e2](f4d09e2)) * require `>= sap/cds@7.9.0` ([#627](#627)) ([f4d09e2](f4d09e2)) </details> <details><summary>sqlite: 1.7.0</summary> ## [1.7.0](sqlite-v1.6.0...sqlite-v1.7.0) (2024-05-08) ### Added * select decimals as strings if cds.env.features.string_decimals ([#616](#616)) ([39addbf](39addbf)) ### Fixed * Change `sql` property to `query` for errors ([#611](#611)) ([585577a](585577a)) * **hana:** Remove encoding from hana-client streams ([#623](#623)) ([fed8f6f](fed8f6f)) * Improved placeholders and limit clause ([#567](#567)) ([d5d5dbb](d5d5dbb)) </details> <details><summary>postgres: 1.8.0</summary> ## [1.8.0](postgres-v1.7.0...postgres-v1.8.0) (2024-05-08) ### Added * select decimals as strings if cds.env.features.string_decimals ([#616](#616)) ([39addbf](39addbf)) ### Fixed * Align all quote functions with @sap/cds-compiler ([#619](#619)) ([42e9828](42e9828)) * Change `sql` property to `query` for errors ([#611](#611)) ([585577a](585577a)) * Improved placeholders and limit clause ([#567](#567)) ([d5d5dbb](d5d5dbb)) * Use json datatype for Postgres insert ([#582](#582)) ([f1c9c89](f1c9c89)) </details> <details><summary>hana: 0.3.0</summary> ## [0.3.0](hana-v0.2.0...hana-v0.3.0) (2024-05-08) ### Added * select decimals as strings if cds.env.features.string_decimals ([#616](#616)) ([39addbf](39addbf)) ### Fixed * Add multi `concat` function to `@cap-js/hana` ([#624](#624)) ([df436fe](df436fe)) * Align all quote functions with @sap/cds-compiler ([#619](#619)) ([42e9828](42e9828)) * Change `sql` property to `query` for errors ([#611](#611)) ([585577a](585577a)) * Disconnect HANA tenant when deleted ([#589](#589)) ([a107db9](a107db9)) * **hana:** Align not found behavior in @cap-js/hana ([#603](#603)) ([54d2efb](54d2efb)) * **hana:** Allow custom fuzzy search cqn ([#620](#620)) ([80383f0](80383f0)) * **hana:** Allow HANA to use != and == inside xpr combinations ([#607](#607)) ([c578e9f](c578e9f)) * **hana:** Reference column alias in order by ([#615](#615)) ([7cd3a26](7cd3a26)) * **hana:** Remove encoding from hana-client streams ([#623](#623)) ([fed8f6f](fed8f6f)) * **hana:** Support associations with static values ([#604](#604)) ([05babcf](05babcf)) * improved `=` and `!=` with val `null` for HANA and Postgres ([#626](#626)) ([cbcfe3b](cbcfe3b)) * Improved placeholders and limit clause ([#567](#567)) ([d5d5dbb](d5d5dbb)) * Use json datatype for Postgres insert ([#582](#582)) ([f1c9c89](f1c9c89)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: Johannes Vogel <johannes.vogel@sap.com> Co-authored-by: Patrice Bender <patrice.bender@sap.com>
Added more cases that the
SQL
contains place holders. It now includesnull
andnumbers
. Now that it also includesnumbers
it is also used for thelimit
clause. With special behavior forHANA
where theLIMIT
is inline and theOFFSET
is a place holder. Allowing the execution plan to create better optimizations.