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 codegen for RETURNING clause #3872

Merged
merged 2 commits into from
Feb 13, 2023

Conversation

MariusVolkhart
Copy link
Contributor

This fixes a bug in the codegen of RETURNING clauses for Postgres and SQLite INSERT statements.

Previously, the generated code did not compile if multiple, but not all, columns of the table were returned.

The same bug likely exists for UPDATE and DELETE, but I didn't check or try to fix those.

@@ -92,13 +95,34 @@ class PostgreSqlTypeResolver(private val parentResolver: TypeResolver) : TypeRes
}

override fun queryWithResults(sqlStmt: SqlStmt): QueryWithResults? {
fun List<QueryElement.QueryColumn>.flattenCompounded(): List<QueryElement.QueryColumn> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fun is copied from SelectQueryable.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, all new code was actually copied? What about publishing the code instead and reuse it instead copying it twice (and having it 3 times now)?

@@ -81,8 +81,8 @@ class PgInsertReturningTest {

assertThat(generator.defaultResultTypeFunction().toString()).isEqualTo(
"""
|public fun insertReturn(data_: com.example.Data_): app.cash.sqldelight.ExecutableQuery<com.example.Data_> = insertReturn(data_) { data__, id ->
| com.example.Data_(
|public fun insertReturn(data_: com.example.Data_): app.cash.sqldelight.ExecutableQuery<com.example.InsertReturn> = insertReturn(data_) { data__, id ->
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test verified that the code got generated, but the generated code didn't compile. I'd recommend actually deleting the test, given the integration tests have, in my opinion, better coverage, but either way, the test passes now.

insertAndReturnMany:
INSERT INTO dog
VALUES (?, ?, DEFAULT)
RETURNING name, breed;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the problem scenario. 1 and All variants are present for coverage.

@@ -92,13 +95,34 @@ class PostgreSqlTypeResolver(private val parentResolver: TypeResolver) : TypeRes
}

override fun queryWithResults(sqlStmt: SqlStmt): QueryWithResults? {
fun List<QueryElement.QueryColumn>.flattenCompounded(): List<QueryElement.QueryColumn> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, all new code was actually copied? What about publishing the code instead and reuse it instead copying it twice (and having it 3 times now)?

@hfhbd
Copy link
Collaborator

hfhbd commented Feb 9, 2023

Thank you.

The code generation is correct for scenarios where a single column is returned, as well as when all columns are returned. However, if multiple, but not all, columns are returned, then the generated code still uses the table type, rather than generating a new interface for the projection.
…ong code

The code generation was correct for scenarios where a single column is returned, as well as when all columns are returned. However, if multiple, but not all, columns are returned, then the generated code still used the table type, rather than generating a new interface for the projection.

With this change, the pureTable computation more closely resembles that of SelectQueryable, which contains more complex logic for purity identification.
Copy link
Contributor Author

@MariusVolkhart MariusVolkhart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes:

  • Extracted the common logic into ReturningQueryable and FlattenCompounded. Happy to change names as needed.
  • Added tests for UPDATE and DELETE RETURNING scenarios. These did indeed exhibit the bug, and benefit from the same change, further reusing the common logic.

@@ -21,16 +20,6 @@ class SelectQueryable(
* which points to that table (Pure meaning it has exactly the same columns in the same order).
*/
override val pureTable: NamedElement? by lazy {
fun List<QueryColumn>.flattenCompounded(): List<QueryColumn> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to FlattenCompounded with internal visibility, for reuse in new class ReturningQueryable

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Names are okay.

* @param select The `RETURNING` clause of the statement. Represented as a query since it returns values to the caller.
* @param tableName Name of the table the [statement] is operating on.
*/
class ReturningQueryable(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used by SQLite and Postgres dialects at the moment, but reasonable to think additional dialects would want this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, thanks.

@hfhbd hfhbd merged commit a5280b5 into cashapp:master Feb 13, 2023
@MariusVolkhart MariusVolkhart deleted the mv/returningCodeGen branch February 13, 2023 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants