MyCATApache/Mycat-Server · error · IllegalArgumentException
not a query sql statement
Error message
not a query sql statement
What it means
MongoSQLParser.query() requires the parsed Druid AST to be a SQLSelectStatement; anything else (INSERT, UPDATE, DELETE, DDL, etc.) triggers IllegalArgumentException("not a query sql statement"). Only SELECT statements can be translated into a MongoDB find query by this parser.
Solutions
- Only send SELECT statements down the query() path; route writes through executeUpdate/InsertData
- Verify the SQL string actually parses as a Druid SQLSelectStatement (no trailing semicolon issues, no vendor-specific syntax)
- Catch IllegalArgumentException around query() and redirect non-select statements to the update path
- Pre-parse with Druid's SQLUtils to confirm statement type before calling query()
Example fix
// before
MongoData data = parser.query(); // throws for non-SELECT
// after
if (parser.getStatement() instanceof SQLSelectStatement) {
MongoData data = parser.query();
} else {
int affected = parser.executeUpdate();
} Defensive patterns
Strategy: type-guard
Validate before calling
SQLStatement stmt = SQLUtils.parseStatements(sql, dbType).get(0);
if (!(stmt instanceof SQLSelectStatement)) {
// route to update path instead of query()
} Type guard
boolean isQuery(SQLStatement statement) {
return statement instanceof SQLSelectStatement;
} Try / catch
try {
MongoData data = parser.query();
} catch (IllegalArgumentException e) {
if ("not a query sql statement".equals(e.getMessage())) {
// re-dispatch via executeUpdate or reject the statement type
} else {
throw e;
}
} Prevention
- Parse and classify SQL with Druid before choosing the query vs update path
- Keep vendor-specific syntax out of statements sent to the Mongo handler
- Add a regression test per statement type (SELECT/INSERT/UPDATE/DELETE) against query()
When it happens
Trigger: Passing a non-SELECT SQL string (INSERT/UPDATE/DELETE/SHOW/etc.) through a path that calls MongoSQLParser.query(), e.g. executing an INSERT or UPDATE via the query/read path of the MongoDB JDBC handler.
Common situations: Client sends an UPDATE or INSERT statement but the MyCat route sends it to the MongoDB backend handler that always invokes query(); SQL dialect differences make Druid parse the statement as non-select (e.g. 'SELECT ... INTO'); test harness passing arbitrary SQL.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- number of columns error
- number of values and columns have to match
- not where of sql
- like SQL error
- Can't identify the operation of of where
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/f66653f5a1ecf020.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/backend/jdbc/mongodb/MongoSQLParser.java:66
return parser.parseStatement();
}
catch (Exception e)
{
LOGGER.error("MongoSQLParser.parserError", e);
}
throw new MongoSQLException.ErrorSQL(s);
}
public void setParams(List params)
{
this._pos = 1;
this._params = params;
}
public MongoData query() throws MongoSQLException{
if (!(statement instanceof SQLSelectStatement)) {
//return null;
throw new IllegalArgumentException("not a query sql statement");
}
MongoData mongo=new MongoData();
DBCursor c=null;
SQLSelectStatement selectStmt = (SQLSelectStatement)statement;
SQLSelectQuery sqlSelectQuery =selectStmt.getSelect().getQuery();
int icount=0;
if(sqlSelectQuery instanceof MySqlSelectQueryBlock) {
MySqlSelectQueryBlock mysqlSelectQuery = (MySqlSelectQueryBlock)selectStmt.getSelect().getQuery();
BasicDBObject fields = new BasicDBObject();
//显示的字段
for(SQLSelectItem item : mysqlSelectQuery.getSelectList()) {
//System.out.println(item.toString());
if (!(item.getExpr() instanceof SQLAllColumnExpr)) {
if (item.getExpr() instanceof SQLAggregateExpr) {
SQLAggregateExpr expr =(SQLAggregateExpr)item.getExpr();
if (expr.getMethodName().equals("COUNT")) {
icount=1;
View on GitHub (pinned to 65f8d8beb7)