Skip to content

Conversation

@chapmandu
Copy link
Contributor

@chapmandu chapmandu commented Feb 3, 2026

Ensures MySQL reserved words (like groups, order, key, etc.) are properly escaped with backticks when used as table names, preventing SQL syntax errors.

Changes:

$escapeReservedWords() in MySQL adapter checks table names against reserved word list
$fromClause() calls the adapter's escape function when building SQL
Test:

Added test: "escapes MySQL reserved word 'groups' in from clause"

This feature does not define reserved words for all db adapters, only MySQL

@chapmandu chapmandu changed the title feat(models): escapeReservedWords function feat(sql): escapes reserved words Feb 3, 2026
@chapmandu chapmandu marked this pull request as ready for review February 3, 2026 06:27
@zainforbjs
Copy link
Contributor

@chapmandu It looks like this change is attempting to automatically escape reserved SQL keywords so users can create tables with names like SELECT or FROM.

While this can technically work, I’m not sure this is the right direction. Allowing reserved words as identifiers can create maintenance challenges outside the ORM layer.

In most cases, frameworks discourage using reserved keywords rather than accommodating them. It might be safer to either document this limitation clearly or throw a meaningful error instead of implicitly supporting it.

@chapmandu
Copy link
Contributor Author

Unfortunately, our database schema contained words that became reserved in later versions of MySQL. We had to fork and patch wheels 2.5 before we could upgrade our database version. If we were to upgrade to 3.0, we would require a resolution to this issue, or fork 3.0 and patch it.

@bpamiri
Copy link
Collaborator

bpamiri commented Feb 12, 2026

Thanks for identifying this issue @chapmandu — supporting legacy databases with reserved-word identifiers is a real need, and your use case (table/column names becoming reserved in newer MySQL versions) is exactly the kind of problem a framework should handle.

After reviewing this PR, I've taken a different approach in #1874 that addresses the same problem for all database adapters rather than just MySQL:

Key differences from this PR:

  1. Always-quote instead of reserved word list — Rather than maintaining a 260+ line struct of reserved words that needs updating as MySQL adds new ones, feat(sql): quote identifiers to prevent reserved word conflicts #1874 wraps all identifiers with the adapter's native quoting character. This is the approach used by Hibernate, Doctrine, ActiveRecord, and SQLAlchemy.

  2. All 6 adapters — MySQL (backticks), SQL Server (brackets), PostgreSQL/Oracle/H2/SQLite (double-quotes). This PR only implements MySQL, with empty TODO stubs for the others.

  3. Bug fix — This PR has return "#local.rv#" in $escapeReservedWords() where local.rv is undefined — should be arguments.word.

  4. Simpler diff — ~170 lines total vs 400+ lines (much of which was whitespace changes mixed with real changes).

The approach in #1874 should handle your legacy database scenario across any supported database engine.

bpamiri added a commit that referenced this pull request Feb 12, 2026
…d word conflicts

Add adapter-specific identifier quoting ($quoteIdentifier) for all 6 database adapters:
- MySQL: backticks (`name`)
- SQL Server: square brackets ([name])
- PostgreSQL, Oracle, SQLite: double-quotes ("name")
- H2: no-op (case-sensitive with quoted identifiers)

Quote table names in FROM, JOIN, DELETE, UPDATE, INSERT clauses and column names
in WHERE, SET, ORDER BY, INSERT column lists, and JOIN ON conditions. SELECT
clause only quotes table name prefixes (not column names) to maintain compatibility
with SQL Server's triple-subquery pagination.

Add $stripIdentifierQuotes helper for comparing rendered SQL containing mixed
quoting styles (used in MSSQL pagination and $identitySelect across all adapters).

Fix read.cfc empty-result regex to handle quoted table prefixes in column lists.

Update test expectations to be adapter-aware using qi() helper that delegates
to the current adapter's quoting character.

Closes #1856

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@chapmandu
Copy link
Contributor Author

Nice @bpamiri

Closed in favour of #1874

@chapmandu chapmandu closed this Feb 12, 2026
@chapmandu chapmandu deleted the chapmandu/mysql-escapeReservedWords branch February 12, 2026 03:54
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.

3 participants