{"record":{"id":"a96482bf10e1068c","repo":"MyCATApache/Mycat-Server","slug":"you-have-an-error-in-your-sql-syntax-check-the-ma","errorCode":null,"errorMessage":"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{expr}' at line 1","messagePattern":"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(.+?)' at line 1","errorType":"exception","errorClass":"SQLNonTransientException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/parser/druid/impl/MysqlMethodInvocationHandler.java","lineNumber":120,"sourceCode":"                } else if (\"MINUTE\".equals(unit)) {\n                    result = DateUtils.addMinutes(date, delta);\n                } else if (\"SECOND\".equals(unit)) {\n                    result = DateUtils.addSeconds(date, delta);\n                } else {\n                    return null;\n                }\n                String ret = DateFormatUtils.format(result, \"yyyy-MM-dd HH:mm:ss\");\n                return new SQLIdentifierExpr(ret);\n            } catch (ParseException e) {\n                LOGGER.error(\"\",e);\n            }\n        }\n        return null;\n    }\n\n    private void throwSyntaxError(SQLExpr expr) throws SQLNonTransientException {\n        String errMsg = \"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\" + expr + \"' at line 1\";\n        throw new SQLNonTransientException(errMsg);\n    }\n}","sourceCodeStart":102,"sourceCodeEnd":122,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/parser/druid/impl/MysqlMethodInvocationHandler.java#L102-L122","documentation":"When parsing ADDDATE (and similar date functions), the handler validates argument structure; invalid arguments cause throwSyntaxError to raise a SQLNonTransientException that mimics MySQL's native syntax error, pointing at the offending expression. It signals the function call is malformed for MySQL semantics, not just unsupported.","triggerScenarios":"invokeAddDate is given an SQLMethodInvokeExpr whose arguments do not match the expected (expr, days) form — e.g. ADDDATE with wrong argument count, a non-numeric second argument, or nested unsupported expression — where the handler calls throwSyntaxError(expr).","commonSituations":"Typo'd date arithmetic like ADDDATE('2024-01-01'); passing a column/expression where an integer interval is required; generated SQL emitting INTERVAL clauses the parser doesn't model.","solutions":["Correct the function call to MySQL's valid form: ADDDATE(date, INTERVAL n DAY) or ADDDATE(date, n)","Compute the date in the application and embed a literal value","Check the exact expression named in the error for syntax/argument errors"],"exampleFix":"// before\nADDDATE('2024-01-01')\n// after\nADDDATE('2024-01-01', INTERVAL 1 DAY)","handlingStrategy":"validation","validationCode":"// validate ADDDATE shape before parsing\nif (args.length != 2 || !(args[1] instanceof SQLIntegerExpr || args[1] instanceof SQLIntervalExpr)) {\n    throw new IllegalArgumentException(\"ADDDATE requires (date, integer|INTERVAL n unit)\");\n}","typeGuard":null,"tryCatchPattern":"try { route(sql) } catch (SQLNonTransientException e) { if (e.getMessage().contains(\"for the right syntax to use near\")) { logAndFixFunctionCall(e.getMessage()); } }","preventionTips":["Follow MySQL grammar exactly for date functions","Prefer ADDDATE(date, INTERVAL n DAY) form","Test generated SQL against a real MySQL before routing through Mycat"],"tags":["mysql","sql-syntax","date-function"],"backgroundTag":"sql-syntax-error","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}