{"record":{"id":"867f3f052abce7d8","repo":"apache/cassandra","slug":"use-keyspace-with-prepared-statements-is-consi","errorCode":null,"errorMessage":"`USE <keyspace>` with prepared statements is considered to be an anti-pattern due to ambiguity in non-qualified table names. Please consider removing instances of `Session#setKeyspace(<keyspace>)`, `Session#execute(\"USE <keyspace>\")` and `cluster.newSession(<keyspace>)` and always use fully qualified table names (e.g. <keyspace>.<table>). Keyspace used: %s, statement keyspace: %s, statement id: %s","messagePattern":"`USE <keyspace>` with prepared statements is considered to be an anti-pattern due to ambiguity in non-qualified table names\\. Please consider removing instances of `Session#setKeyspace\\(<keyspace>\\)`, `Session#execute\\(\"USE <keyspace>\"\\)` and `cluster\\.newSession\\(<keyspace>\\)` and always use fully qualified table names \\(e\\.g\\. <keyspace>\\.<table>\\)\\. Keyspace used: (.+?), statement keyspace: (.+?), statement id: (.+?)","errorType":"validation","errorClass":"ClientWarn","httpStatus":null,"severity":"info","filePath":"src/java/org/apache/cassandra/service/ClientState.java","lineNumber":716,"sourceCode":"     *\n     * @return {@code true} if this user is the system user, {@code false} otherwise.\n     */\n    public boolean isSystem()\n    {\n        return isInternal;\n    }\n\n    public void ensureIsSuperuser(String message)\n    {\n        if (!isSuper())\n            throw new UnauthorizedException(message);\n    }\n\n    public void warnAboutUseWithPreparedStatements(MD5Digest statementId, String preparedKeyspace)\n    {\n        if (!issuedPreparedStatementsUseWarning)\n        {\n            ClientWarn.instance.warn(String.format(\"`USE <keyspace>` with prepared statements is considered to be an anti-pattern due to ambiguity in non-qualified table names. \" +\n                                                   \"Please consider removing instances of `Session#setKeyspace(<keyspace>)`, `Session#execute(\\\"USE <keyspace>\\\")` and `cluster.newSession(<keyspace>)` from your code, and \" +\n                                                   \"always use fully qualified table names (e.g. <keyspace>.<table>). \" +\n                                                   \"Keyspace used: %s, statement keyspace: %s, statement id: %s\", getRawKeyspace(), preparedKeyspace, statementId));\n            issuedPreparedStatementsUseWarning = true;\n        }\n    }\n\n    public void warnAboutUneligiblePreparedStatement(MD5Digest statementId)\n    {\n        if (!issuedWarningForUneligiblePreparedStatements)\n        {\n            ClientWarn.instance.warn(String.format(\"Prepared statements for other than modification and selection statements should be avoided, statement id: %s\", statementId));\n            issuedWarningForUneligiblePreparedStatements = true;\n        }\n    }\n\n    private static void validateKeyspace(String keyspace)\n    {","sourceCodeStart":698,"sourceCodeEnd":734,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/ClientState.java#L698-L734","documentation":"A client warning (sent to the driver via ClientWarn, not a server log) issued when a prepared statement's keyspace is changed with USE or Session#setKeyspace. Mixing USE with prepared statements creates ambiguity for non-qualified table names and is flagged as an anti-pattern; the warning is issued once per ClientState session.","triggerScenarios":"Client executes `USE <keyspace>` (or Session#setKeyspace / cluster.newSession semantics) after prepare() has recorded prepared statements on this ClientState; the next prepare or execution path calls warnAboutUseWithPreparedStatements.","commonSituations":"Applications sharing one session/connection pool that switch keyspace with USE before binding prepared statements; drivers that auto-issue USE; scripts ported from cqlsh habits into driver code.","solutions":["Remove USE/setKeyspace calls and fully qualify table names (keyspace.table) in all statements","Create a session bound to the keyspace instead (cluster.connect(keyspace)) without issuing USE between prepares","Re-prepare statements after any intentional keyspace switch; treat the warning as a code smell to fix, not suppress"],"exampleFix":"// before\nsession.execute(\"USE myks\");\nPreparedStatement ps = session.prepare(\"SELECT * FROM mytable\");\n// after\nPreparedStatement ps = session.prepare(\"SELECT * FROM myks.mytable\");","handlingStrategy":"validation","validationCode":"// assert no USE statements are issued alongside prepared statements\nString cql = statement.trim().toLowerCase();\nif (cql.startsWith(\"use \") && session.getPreparedStatements().count() > 0)\n    throw new IllegalArgumentException(\"Do not USE keyspace while using prepared statements; qualify table names\");","typeGuard":null,"tryCatchPattern":"// driver-side: consume warnings so the anti-pattern surfaces\ncluster.register(warnings -> warnings.forEach(w -> log.warn(\"Server warning: {}\", w)));","preventionTips":["Always fully qualify table names (keyspace.table) in prepared statements","Bind the session to a keyspace at connect time instead of issuing USE","Enable and monitor driver warning handlers in all environments","Add code-review/lint checks rejecting USE in application CQL"],"tags":["cql","prepared-statements","anti-pattern"],"backgroundTag":"deprecated-api-usage","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}