Skip to content

Fix: [igo-db] remove implicit like#49

Merged
mickael-coquer-igocreate merged 3 commits intov5from
fix/igo-db/remove-implicit-like
Mar 31, 2026
Merged

Fix: [igo-db] remove implicit like#49
mickael-coquer-igocreate merged 3 commits intov5from
fix/igo-db/remove-implicit-like

Conversation

@mickael-coquer-igocreate
Copy link
Copy Markdown
Contributor

@mickael-coquer-igocreate mickael-coquer-igocreate commented Mar 31, 2026

Summary

  • Suppression du LIKE implicite : une string contenant % dans un where() n'est plus automatiquement convertie en LIKE. Ce comportement permettait d'injecter des patterns LIKE via des données utilisateur non sanitizées.
  • Pour faire un LIKE, il faut maintenant utiliser l'opérateur explicite $like : { column: { $like: 'value%' } }
  • Refacto des assertions dans PaginatedOptimizedQueryTest.js : remplacement de tous les assert.ok(sql.includes(...)) par des assert.strictEqual sur le SQL complet généré, pour une meilleure lisibilité et une détection fiable de toute régression.

Test plan

  • Tests unitaires mis à jour (Sql, PaginatedOptimizedQuery)
  • Assertions strictes sur le SQL complet dans PaginatedOptimizedQueryTest
  • Vérifier qu'aucun where() existant dans les projets ne repose sur le LIKE implicite

🤖 Generated with Claude Code

@mickael-coquer-igocreate mickael-coquer-igocreate changed the base branch from master to v5 March 31, 2026 06:56
Strings with % are no longer auto-converted to LIKE queries.
Use the explicit $like operator instead: { column: { $like: 'value%' } }

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mickael-coquer-igocreate mickael-coquer-igocreate force-pushed the fix/igo-db/remove-implicit-like branch from 171d074 to 1816d14 Compare March 31, 2026 06:59
@mickael-coquer-igocreate
Copy link
Copy Markdown
Contributor Author

Code review

Found 4 issues:

  1. Two tests in "COUNT and IDS phase optimizations" still pass raw 'Dupont%' without { $like: ... } and never assert LIKE in the generated SQL. After this PR they silently produce = instead of LIKE, but the tests still pass — giving false confidence.

describe('COUNT and IDS phase optimizations', function() {
it('COUNT should have no LEFT JOIN, no ORDER BY, and use EXISTS for filters', () => {
const query = mockGetDb(new PaginatedOptimizedQuery(Folder));
query.query.verb = 'count';
query.where({ type: 'agp', 'applicant.last_name': 'Dupont%' })
.order('applicants.last_name ASC')
.join('applicant');
const { sql, params } = query.toSQL();
assert.ok(sql.includes('SELECT COUNT(0)'));
assert.ok(sql.includes('EXISTS'));
assert.ok(!sql.includes('LEFT JOIN'));
assert.ok(!sql.includes('ORDER BY'));
assert.deepStrictEqual(params, ['agp', 'Dupont%']);
});
it('IDS should SELECT only id, use EXISTS, ORDER BY + LIMIT, and no LEFT JOIN when sort is on main table', () => {
const query = mockGetDb(new PaginatedOptimizedQuery(Folder));
query.query.verb = 'select_ids';
query.where({ type: 'agp', 'applicant.last_name': 'Dupont%' })
.order('folders.created_at DESC')
.limit(50);
const { sql, params } = query.toSQL();
assert.ok(sql.includes('SELECT `folders`.`id`'));
assert.ok(sql.includes('EXISTS (SELECT 1 FROM `applicants`'));
assert.ok(sql.includes('ORDER BY folders.created_at DESC'));
assert.ok(sql.includes('LIMIT ?, ?'));
assert.ok(!sql.includes('LEFT JOIN'));
assert.deepStrictEqual(params, ['agp', 'Dupont%', 0, 50]);
});

  1. JSDoc example for _buildOrGroupExists still shows { 'applicant.last_name': 'Dupont%' } as input with LIKE ? as output. After this PR, that input produces = ? — the example is now inconsistent.

* @param {Array} params - Paramètres SQL
* @returns {string} SQL avec EXISTS joints par OR
*
* Exemple :
* Input: [
* { 'applicant.last_name': 'Dupont%' },
* { 'applicant.first_name': 'Jean%' },
* { 'beneficiary.email': 'test@test.com' }
* ]
* Output: (
* EXISTS (SELECT 1 FROM applicants WHERE applicants.id = folders.applicant_id AND applicants.last_name LIKE ?)
* OR EXISTS (SELECT 1 FROM applicants WHERE applicants.id = folders.applicant_id AND applicants.first_name LIKE ?)
* OR EXISTS (SELECT 1 FROM beneficiaries WHERE beneficiaries.id = folders.beneficiary_id AND beneficiaries.email = ?)

  1. Class-level JSDoc example shows AND a.last_name LIKE '%Dupont%' implying a raw string with % generates LIKE. Now stale after implicit LIKE removal.

* FROM `folders` f
* WHERE f.type IN ('agp', 'avt')
* AND EXISTS (
* SELECT 1 FROM `applicants` a
* WHERE a.id = f.applicant_id
* AND a.last_name LIKE '%Dupont%'
* )
* AND EXISTS (
* SELECT 1 FROM `pme_folders` p
* WHERE p.id = f.pme_folder_id
* AND p.status = 'ACTIVE'

  1. The implicit LIKE was documented and used by downstream projects. The codebase has an established deprecation pattern (e.g. Model.destroy() emits a console warning before removal). A similar deprecation cycle would reduce the risk of silent regressions in consumer projects.

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

… removal

- Use explicit $like in COUNT/IDS optimization tests and assert LIKE in SQL
- Update JSDoc examples in PaginatedOptimizedSql to match new behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…eryTest

Replace all assert.ok(sql.includes(...)) with assert.strictEqual on
the complete generated SQL string. This makes tests more readable and
catches any unexpected change in the generated queries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mickael-coquer-igocreate mickael-coquer-igocreate deleted the fix/igo-db/remove-implicit-like branch March 31, 2026 07:33
mickael-coquer-igocreate added a commit that referenced this pull request Mar 31, 2026
## Summary

- Suppression du LIKE implicite : une string contenant `%` dans un
`where()` n'est plus automatiquement convertie en `LIKE`. Ce
comportement permettait d'injecter des patterns LIKE via des données
utilisateur non sanitizées.
- Pour faire un LIKE, il faut maintenant utiliser l'opérateur explicite
`$like` : `{ column: { $like: 'value%' } }`
- Refacto des assertions dans `PaginatedOptimizedQueryTest.js` :
remplacement de tous les `assert.ok(sql.includes(...))` par des
`assert.strictEqual` sur le SQL complet généré, pour une meilleure
lisibilité et une détection fiable de toute régression.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant