{"record":{"id":"eb36eb30a3d205bc","repo":"MyCATApache/Mycat-Server","slug":"er-parse-error-eb36eb","errorCode":"ER_PARSE_ERROR","errorMessage":"msg == null ? e.getClass().getSimpleName() : msg","messagePattern":"msg == null \\? e\\.getClass\\(\\)\\.getSimpleName\\(\\) : msg","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/server/ServerConnection.java","lineNumber":328,"sourceCode":"\t\t\twriteErrMessage(ErrorCode.ERR_BAD_LOGICDB,\n\t\t\t\t\t\"Unknown MyCAT Database '\" + db + \"'\");\n\t\t\treturn null;\n\t\t}\n\n\t\t// 路由计算\n\t\tRouteResultset rrs = null;\n\t\ttry {\n\t\t\trrs = MycatServer\n\t\t\t\t\t.getInstance()\n\t\t\t\t\t.getRouterservice()\n\t\t\t\t\t.route(MycatServer.getInstance().getConfig().getSystem(),\n\t\t\t\t\t\t\tschema, type, sql, this.charset, this);\n\n\t\t} catch (Exception e) {\n\t\t\tStringBuilder s = new StringBuilder();\n\t\t\tLOGGER.warn(s.append(this).append(sql).toString() + \" err:\" + e.toString(),e);\n\t\t\tString msg = e.getMessage();\n\t\t\twriteErrMessage(ErrorCode.ER_PARSE_ERROR, msg == null ? e.getClass().getSimpleName() : msg);\n\t\t\treturn null;\n\t\t}\n\t\treturn rrs;\n\t}\n\n\n\n\n\tpublic void routeEndExecuteSQL(String sql, final int type, final SchemaConfig schema) {\n\t\t// 路由计算\n\t\tRouteResultset rrs = null;\n\t\ttry {\n\t\t\trrs = MycatServer\n\t\t\t\t\t.getInstance()\n\t\t\t\t\t.getRouterservice()\n\t\t\t\t\t.route(MycatServer.getInstance().getConfig().getSystem(),\n\t\t\t\t\t\t\tschema, type, sql, this.charset, this);\n","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/server/ServerConnection.java#L310-L346","documentation":"ServerConnection.routeSQL() wraps SQL routing in a catch-all: any exception raised while parsing/routing a query through the RouterService is converted to a MySQL ER_PARSE_ERROR packet sent back to the client. The message is the exception's getMessage(), or the exception class's simple name when the message is null. It is a generic 'your SQL could not be routed/parsed by Mycat' reply rather than a true MySQL parser error.","triggerScenarios":"Any Exception thrown inside routeSQL while calling MycatServer.getInstance().getRouterservice().route(...), e.g. syntax Mycat's SQL parser cannot handle, unknown table/schema in sharding rules, or a routing rule throwing; also when e.getMessage() is null (e.g. NPE) the client sees just the class name like 'NullPointerException'.","commonSituations":"Mycat-specific or non-standard SQL syntax the embedded Druid parser rejects; queries against tables lacking schemaConfig/sharding config; NPEs from incomplete schema.xml configuration being surfaced as parse errors; version upgrades where the router became stricter.","solutions":["Read the server log (LOGGER.warn prints this + sql + full stack trace) to find the real underlying exception and its cause.","Fix the SQL to use syntax supported by Mycat's router, or adjust schema/rule configuration for the referenced tables.","If the message is just a class name (null message), inspect the stack trace for an NPE from missing schema/rule config and complete schema.xml/rule.xml."],"exampleFix":"// before: incomplete sharding config causes NPE inside route()\nSELECT * FROM order_detail WHERE id=1  // table missing in schema.xml -> NPE -> ER_PARSE_ERROR 'NullPointerException'\n// after\n<!-- schema.xml: declare the table so routing succeeds -->\n<table name=\"order_detail\" dataNode=\"dn1\" />","handlingStrategy":"try-catch","validationCode":"// before sending: check the statement is non-empty and table is declared in schema\nString sql = \"SELECT * FROM order_detail WHERE id=1\";\nif (sql == null || sql.trim().isEmpty()) throw new IllegalArgumentException(\"empty SQL\");\n// verify table exists in Mycat schema config (e.g. via SHOW TABLES on manager port)\nboolean declared = mycatSchemaTables.contains(resolveTableName(sql));\nif (!declared) { /* fix schema.xml before routing */ }","typeGuard":null,"tryCatchPattern":"try {\n    routeSQL(sql, type);\n} catch (Exception e) {\n    // client sees ER_PARSE_ERROR; consult server log for the real cause\n    LOGGER.error(\"route failed for sql: \" + sql, e);\n    String detail = (e.getMessage() != null) ? e.getMessage() : e.getClass().getSimpleName();\n    throw new RuntimeException(\"SQL routing failed: \" + detail, e);\n}","preventionTips":["Always check the Mycat server log, not just the client error packet, since ER_PARSE_ERROR masks the real exception.","Keep schema.xml/rule.xml in sync with every table referenced by application SQL.","Test new SQL against Mycat with EXPLAIN via the manager port before deploying.","Avoid syntax known to be unsupported by Mycat's Druid-based parser."],"tags":["sql","routing","mysql","parser"],"backgroundTag":"sql-query-failed","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}