in src/main/core-api/java/com/mysql/cj/QueryInfo.java [752:802]
public static boolean isReadOnlySafeQuery(String sql, boolean noBackslashEscapes) {
/*
* Read-only unsafe statements:
* - ALTER; CHANGE; CREATE; DELETE; DROP; GRANT; IMPORT; INSERT; INSTALL; LOAD; OPTIMIZE; RENAME; REPAIR; REPLACE; RESET; REVOKE; TRUNCATE; UNINSTALL;
* - UPDATE; WITH ... DELETE|UPDATE
*
* Read-only safe statements:
* - ANALYZE; BEGIN; BINLOG; CACHE; CALL; CHECK; CHECKSUM; CLONE; COMMIT; DEALLOCATE; DESC; DESCRIBE; EXECUTE; EXPLAIN; FLUSH; GET; HANDLER; HELP; KILL;
* - LOCK; PREPARE; PURGE; RELEASE; RESIGNAL; ROLLBACK; SAVEPOINT; SELECT; SET; SHOW; SIGNAL; START; STOP; TABLE; UNLOCK; USE; VALUES;
* - WITH ... [SELECT|TABLE|VALUES]; XA
*/
int statementKeywordPos = indexOfStatementKeyword(sql, noBackslashEscapes);
if (statementKeywordPos == -1) {
return true; // Assume it's safe.
}
char firstStatementChar = Character.toUpperCase(sql.charAt(statementKeywordPos));
if (firstStatementChar == 'A' && StringUtils.startsWithIgnoreCaseAndWs(sql, "ALTER", statementKeywordPos)) {
return false;
} else if (firstStatementChar == 'C' && (StringUtils.startsWithIgnoreCaseAndWs(sql, "CHANGE", statementKeywordPos)
|| StringUtils.startsWithIgnoreCaseAndWs(sql, "CREATE", statementKeywordPos))) {
return false;
} else if (firstStatementChar == 'D' && (StringUtils.startsWithIgnoreCaseAndWs(sql, "DELETE", statementKeywordPos)
|| StringUtils.startsWithIgnoreCaseAndWs(sql, "DROP", statementKeywordPos))) {
return false;
} else if (firstStatementChar == 'G' && StringUtils.startsWithIgnoreCaseAndWs(sql, "GRANT", statementKeywordPos)) {
return false;
} else if (firstStatementChar == 'I' && (StringUtils.startsWithIgnoreCaseAndWs(sql, "IMPORT", statementKeywordPos)
|| StringUtils.startsWithIgnoreCaseAndWs(sql, "INSERT", statementKeywordPos)
|| StringUtils.startsWithIgnoreCaseAndWs(sql, "INSTALL", statementKeywordPos))) {
return false;
} else if (firstStatementChar == 'L' && StringUtils.startsWithIgnoreCaseAndWs(sql, "LOAD", statementKeywordPos)) {
return false;
} else if (firstStatementChar == 'O' && StringUtils.startsWithIgnoreCaseAndWs(sql, "OPTIMIZE", statementKeywordPos)) {
return false;
} else if (firstStatementChar == 'R' && (StringUtils.startsWithIgnoreCaseAndWs(sql, "RENAME", statementKeywordPos)
|| StringUtils.startsWithIgnoreCaseAndWs(sql, "REPAIR", statementKeywordPos)
|| StringUtils.startsWithIgnoreCaseAndWs(sql, "REPLACE", statementKeywordPos)
|| StringUtils.startsWithIgnoreCaseAndWs(sql, "RESET", statementKeywordPos)
|| StringUtils.startsWithIgnoreCaseAndWs(sql, "REVOKE", statementKeywordPos))) {
return false;
} else if (firstStatementChar == 'T' && StringUtils.startsWithIgnoreCaseAndWs(sql, "TRUNCATE", statementKeywordPos)) {
return false;
} else if (firstStatementChar == 'U' && (StringUtils.startsWithIgnoreCaseAndWs(sql, "UNINSTALL", statementKeywordPos)
|| StringUtils.startsWithIgnoreCaseAndWs(sql, "UPDATE", statementKeywordPos))) {
return false;
} else if (firstStatementChar == 'W' && StringUtils.startsWithIgnoreCaseAndWs(sql, "WITH", statementKeywordPos)) {
String context = getContextForWithStatement(sql, noBackslashEscapes);
return context == null || !context.equalsIgnoreCase("DELETE") && !context.equalsIgnoreCase("UPDATE");
}
return true; // Assume it's safe by default.
}