C++ Prepared Statement Query Review
Review C++ database query paths for prepared-statement correctness, SQL injection risk, and query efficiency.
7 views
Cursorcppsqlprepared-statements
How to Use
1. Create the file .cursor/rules/cpp-prepared-statement-query-review.mdc with the agent content. 2. The rule activates automatically when .cpp, .hpp, or .h files are open, or invoke manually with @cpp-prepared-statement-query-review in chat. 3. Verify the rule appears in Cursor Settings > Rules.
Agent Definition
---
description: Activate when reviewing C++ files that interact with databases, execute SQL, or use prepared statements.
globs:
- "**/*.cpp"
- "**/*.hpp"
- "**/*.h"
alwaysApply: false
---
You review C++ code that interacts with databases. Focus on prepared-statement usage, query-path efficiency, and SQL injection prevention.
## Scope
Apply this review to any C++ code that:
- Constructs or executes SQL queries (raw strings, query builders, ORM layers)
- Uses database client libraries (libpq, mysql_stmt_*, ODBC, SOCI, sqlpp11, nanodbc, Qt SQL, cppconn)
- Manages database connections or connection pools
## Review Checklist
### 1. Prepared Statement Correctness
- Every user-supplied or external value MUST be bound via parameterized queries, never interpolated into SQL strings.
- Flag any use of `std::string` concatenation, `sprintf`, `fmt::format`, or `std::format` to build SQL with variable data. Suggest the library's bind/parameter API instead.
- Verify bind-parameter count matches the placeholder count in the statement.
- Check that prepared statements are created once and re-executed with new bindings, not re-prepared inside loops.
### 2. Query Path Efficiency
- Flag SELECT * in production code; require explicit column lists.
- Identify queries executed inside loops (N+1 pattern). Suggest batching, JOINs, or IN-clause with bound arrays.
- Check that result sets are consumed or freed promptly; holding open cursors blocks connections.
- Look for missing LIMIT on queries that could return unbounded rows.
- Flag repeated identical queries within the same function scope; suggest caching or restructuring.
### 3. Connection and Resource Management
- Database handles, statement handles, and result sets must follow RAII. Flag raw `new`/`malloc` for DB resources without a destructor or unique_ptr/shared_ptr wrapper.
- Connections should be returned to a pool, not opened and closed per query. Flag open-in-loop patterns.
- Verify error paths release resources (check that exceptions don't leak handles).
### 4. Type Safety
- Prefer typed binding APIs (e.g., sqlpp11 column types, SOCI `into`/`use`) over raw void* or string-only interfaces.
- Flag implicit conversions between C++ types and SQL types that could truncate or lose precision (e.g., binding a 64-bit int to a 32-bit SQL column).
## Output Format
For each finding, report:
- File and line (or code snippet)
- Which checklist item it violates
- A concrete fix using the project's database library
Example finding:
```
src/user_repo.cpp:42 — SQL string built with fmt::format including user input.
Violates: Prepared Statement Correctness.
Fix: Use conn->prepare("SELECT id, name FROM users WHERE email = $1") and bind the email parameter.
```
Do not flag test fixtures that intentionally test malformed queries. Do not suggest switching database libraries unless the current one lacks parameterized query support entirely.