Skip to content

Quote Column Names#624

Merged
cfis merged 1 commit intocomposite-primary-keys:masterfrom
code-dot-org:elijah/quote-composite-column-names
Dec 12, 2025
Merged

Quote Column Names#624
cfis merged 1 commit intocomposite-primary-keys:masterfrom
code-dot-org:elijah/quote-composite-column-names

Conversation

@Hamms
Copy link
Contributor

@Hamms Hamms commented Dec 11, 2025

The current MySQL query generation logic does not quote the primary keys in generated subqueries, which can result in queries like:

DELETE FROM `datablock_storage_kvps` WHERE (datablock_storage_kvps.project_id, datablock_storage_kvps.key) IN (SELECT project_id,key FROM (SELECT DISTINCT `datablock_storage_kvps`.`project_id`, `datablock_storage_kvps`.`key` FROM `datablock_storage_kvps` WHERE `datablock_storage_kvps`.`project_id` = 13) __active_record_temp)

Which can, depending on the names given to the keys (in this case, "key"), result in errors like:

ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key FROM (SELECT DISTINCT `datablock_storage_kvps`.`project_id`, `datablock_stor' at line 1

This PR adds logic to quote the parameters in both the WHERE and SELECT clauses, resulting in a query like:

DELETE FROM `datablock_storage_kvps` WHERE (`datablock_storage_kvps`.`project_id`, `datablock_storage_kvps`.`key`) IN (SELECT `project_id`,`key` FROM (SELECT DISTINCT `datablock_storage_kvps`.`project_id`, `datablock_storage_kvps`.`key` FROM `datablock_storage_kvps` WHERE `datablock_storage_kvps`.`project_id` = 13) __active_record_temp)

The current MySQL query generation logic does not quote the primary keys in generated subqueries, which can result in queries like:

```mysql
DELETE FROM `datablock_storage_kvps` WHERE (datablock_storage_kvps.project_id, datablock_storage_kvps.key) IN (SELECT project_id,key FROM (SELECT DISTINCT `datablock_storage_kvps`.`project_id`, `datablock_storage_kvps`.`key` FROM `datablock_storage_kvps` WHERE `datablock_storage_kvps`.`project_id` = 13) __active_record_temp)
```

Which can, depending on the names given to the keys, result in errors like:

    ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key FROM (SELECT DISTINCT `datablock_storage_kvps`.`project_id`, `datablock_stor' at line 1

This PR adds logic to quote the parameters in both the `WHERE` and `SELECT` clauses, resulting in a query like:

```mysql
DELETE FROM `datablock_storage_kvps` WHERE (`datablock_storage_kvps`.`project_id`, `datablock_storage_kvps`.`key`) IN (SELECT `project_id`,`key` FROM (SELECT DISTINCT `datablock_storage_kvps`.`project_id`, `datablock_storage_kvps`.`key` FROM `datablock_storage_kvps` WHERE `datablock_storage_kvps`.`project_id` = 13) __active_record_temp)
```
@cfis
Copy link
Contributor

cfis commented Dec 11, 2025

Ok, well tests pass, so good by me. Let me know once you take this out of draft status.

@Hamms Hamms marked this pull request as ready for review December 11, 2025 21:50
@Hamms
Copy link
Contributor Author

Hamms commented Dec 11, 2025

Great, thanks! I was thinking of adding some new tests to cover this case, but now I'm thinking that might be more trouble than its worth, particularly given how situationally specific it is.

Happy to do so if you think it'd be worthwhile, but otherwise I'd say this is ready for review! :)

@cfis cfis merged commit ec2e404 into composite-primary-keys:master Dec 12, 2025
20 checks passed
@cfis
Copy link
Contributor

cfis commented Dec 12, 2025

A test is always good!

@Hamms
Copy link
Contributor Author

Hamms commented Dec 15, 2025

Would you say a test for this is worth adding yet another text fixture? I made a couple of attempts to create a test case which reproduces the original error by modifying existing fixtures, but kept breaking other tests in the process 🙃

I can easily create a new fixture just for this test, but I don't want to add unnecessarily to the maintenance burden here. What's your preference?

@cfis
Copy link
Contributor

cfis commented Dec 18, 2025

Good question - I was trying to avoid adding new fixtures. But now that CPK has been superseded by what is built into ActiveRecord, I leave it up to you.

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.

2 participants