{"record":{"id":"7f0524bbee026f0d","repo":"MyCATApache/Mycat-Server","slug":"invalid-sql-origsql-7f0524","errorCode":null,"errorMessage":"invalid sql: + origSQL","messagePattern":"invalid sql: \\+ origSQL","errorType":"exception","errorClass":"SQLNonTransientException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/util/RouterUtil.java","lineNumber":652,"sourceCode":"\t\t} else {\r\n\t\t\treturn  -1;\r\n\t\t}\r\n\r\n\t}\r\n\r\n\tpublic static boolean processInsert(ServerConnection sc,SchemaConfig schema,\r\n\t\t\tint sqlType,String origSQL,String tableName,String primaryKey) throws SQLNonTransientException {\r\n\r\n\t\tint firstLeftBracketIndex = origSQL.indexOf(\"(\");\r\n\t\tint firstRightBracketIndex = origSQL.indexOf(\")\");\r\n\t\tString upperSql = origSQL.toUpperCase();\r\n\t\tint valuesIndex = upperSql.indexOf(\"VALUES\");\r\n\t\tint selectIndex = upperSql.indexOf(\"SELECT\");\r\n\t\tint fromIndex = upperSql.indexOf(\"FROM\");\r\n\t\t//屏蔽insert into table1 select * from table2语句\r\n\t\tif(firstLeftBracketIndex < 0) {\r\n\t\t\tString msg = \"invalid sql:\" + origSQL;\r\n\t\t\tLOGGER.warn(msg);\r\n\t\t\tthrow new SQLNonTransientException(msg);\r\n\t\t}\r\n\t\t//屏蔽批量插入\r\n\t\tif(selectIndex > 0 &&fromIndex>0&&selectIndex>firstRightBracketIndex&&valuesIndex<0) {\r\n\t\t\tString msg = \"multi insert not provided\" ;\r\n\t\t\tLOGGER.warn(msg);\r\n\t\t\tthrow new SQLNonTransientException(msg);\r\n\t\t}\r\n\t\t//插入语句必须提供列结构，因为MyCat默认对于表结构无感知\r\n\t\tif(valuesIndex + \"VALUES\".length() <= firstLeftBracketIndex) {\r\n\t\t\tthrow new SQLSyntaxErrorException(\"insert must provide ColumnList\");\r\n\t\t}\r\n\t\tObject[] vauleArrayAndSuffixStr = parseSqlValueArrayAndSuffixStr(origSQL , valuesIndex);\r\n\t\tList<List<String>> vauleArray = (List<List<String>>) vauleArrayAndSuffixStr[0];\r\n\t\tString suffixStr = null;\r\n\t\tif (vauleArrayAndSuffixStr.length > 1) {\r\n\t\t\tsuffixStr = (String) vauleArrayAndSuffixStr[1];\r\n\t\t}\r","sourceCodeStart":634,"sourceCodeEnd":670,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/util/RouterUtil.java#L634-L670","documentation":"RouterUtil's batch-insert handling analyzes an INSERT statement to locate the VALUES clause for batch splitting. If no opening parenthesis is found in the SQL (firstLeftBracketIndex < 0), the statement is not in the expected `INSERT ... VALUES (...)` shape and is rejected as invalid with SQLNonTransientException.","triggerScenarios":"An INSERT statement routed through the batch-insert path that contains no parentheses — e.g. `INSERT INTO tbl SELECT * FROM other`, `INSERT INTO tbl SET a=1`, or a truncated/garbled statement.","commonSituations":"INSERT ... SELECT used to copy data (explicitly blocked here); MySQL SET-style INSERTs; ORM-generated INSERTs with unusual syntax hitting the batch-insert code path.","solutions":["Rewrite the statement as a parenthesized VALUES insert: `INSERT INTO tbl (cols) VALUES (...)`; execute INSERT...SELECT directly on the backend if needed","For SET-style inserts, convert to VALUES syntax","Do a pre-check in client code that the SQL contains \"(\" before routing it through Mycat's batch-insert path"],"exampleFix":"-- before\nINSERT INTO t_user SELECT * FROM tmp_users;\n-- after\nINSERT INTO t_user (id, name) VALUES (1,'a'), (2,'b');","handlingStrategy":"validation","validationCode":"if (!sql.contains(\"(\")) throw new IllegalArgumentException(\"INSERT must use VALUES (...) syntax for mycat routing\");","typeGuard":null,"tryCatchPattern":"try { executeInsert(sql); } catch (SQLNonTransientException e) { if (e.getMessage().startsWith(\"invalid sql:\")) { rewriteToValuesInsert(sql); } else throw e; }","preventionTips":["Use only `INSERT ... VALUES (...)` syntax through Mycat","Run INSERT...SELECT / SET-style inserts directly on the backend","Lint generated SQL for supported INSERT forms","Reject non-parenthesized INSERTs at the app's SQL boundary"],"tags":["mysql","routing","insert","sql-syntax"],"backgroundTag":"invalid-argument-format","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"}