{"record":{"id":"5ae222868339cdd6","repo":"apache/cassandra","slug":"prepared-statements-for-other-than-modification-an","errorCode":null,"errorMessage":"Prepared statements for other than modification and selection statements should be avoided, statement id: %s","messagePattern":"Prepared statements for other than modification and selection statements should be avoided, statement id: (.+?)","errorType":"validation","errorClass":"ClientWarn","httpStatus":null,"severity":"info","filePath":"src/java/org/apache/cassandra/service/ClientState.java","lineNumber":728,"sourceCode":"    }\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    {\n        if (keyspace == null)\n            throw new InvalidRequestException(\"You have not set a keyspace for this session\");\n    }\n\n    public AuthenticatedUser getUser()\n    {\n        return user;\n    }\n\n    private Set<Permission> authorize(IResource resource)\n    {\n        return user.getPermissions(resource);","sourceCodeStart":710,"sourceCodeEnd":746,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/ClientState.java#L710-L746","documentation":"A client warning emitted when a statement other than a modification (INSERT/UPDATE/DELETE) or selection (SELECT) statement — e.g. schema statements like CREATE TABLE or USE — is prepared. Preparing such statements provides no benefit and may cause ambiguity; it is warned once per session.","triggerScenarios":"A client sends a PREPARE message whose statement parses to something other than a modification or selection statement, e.g. `PREPARE CREATE TABLE ...` / prepared ALTER/USE statements via the driver's session.prepare().","commonSituations":"Drivers/frameworks that blindly call session.prepare() on every CQL string including DDL; migration tools that pre-prepare schema scripts; templated query layers preparing utility statements.","solutions":["Only prepare SELECT and data-modification statements; execute DDL and other statements directly with session.execute()","Refactor framework/ORM layers to whitelist statement types before calling prepare()","Acknowledge the warning is client-visible only (ClientWarn); no server-side action is taken, but remove the pattern"],"exampleFix":"// before\nPreparedStatement ps = session.prepare(\"CREATE TABLE myks.t (id int PRIMARY KEY)\");\nsession.execute(ps.bind());\n// after\nsession.execute(\"CREATE TABLE myks.t (id int PRIMARY KEY)\");","handlingStrategy":"validation","validationCode":"// only prepare SELECT / modification statements\nString verb = statement.trim().split(\"\\\\s+\")[0].toLowerCase();\nif (!(verb.equals(\"select\") || verb.equals(\"insert\") || verb.equals(\"update\") || verb.equals(\"delete\") || verb.equals(\"batch\")))\n    throw new IllegalArgumentException(\"Do not prepare '\" + verb + \"' statements; execute them directly\");","typeGuard":null,"tryCatchPattern":"// driver-side warning handler to surface the misuse\ncluster.register(warnings -> warnings.forEach(w -> log.warn(\"Server warning: {}\", w)));","preventionTips":["Execute DDL (CREATE/ALTER/DROP) directly with session.execute, never prepare()","Whitelist preparable statement verbs in ORM/templating layers","Enable driver warning handlers to catch this in dev/test"],"tags":["cql","prepared-statements","ddl"],"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"}