{"record":{"id":"cf86e8bde6c49d17","repo":"MyCATApache/Mycat-Server","slug":"invalid-sql-origsql","errorCode":null,"errorMessage":"invalid sql:{origSQL}","messagePattern":"invalid sql:(.+?)","errorType":"exception","errorClass":"SQLNonTransientException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/util/RouterUtil.java","lineNumber":653,"sourceCode":"\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\n\t\t//两种情况处理 1 有主键的 id ,但是值为null 进行改下\r","sourceCodeStart":635,"sourceCodeEnd":671,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/util/RouterUtil.java#L635-L671","documentation":"During INSERT routing, RouterUtil locates the first '(' of the column list via the raw SQL; if no left bracket exists the statement cannot be parsed as an INSERT with a column list, so it throws SQLNonTransientException('invalid sql:...'). This also blocks INSERT INTO ... SELECT statements which lack the values column-list structure. The SQL is rejected as non-routable.","triggerScenarios":"Executing an INSERT whose text has no '(' column list (e.g. INSERT INTO t VALUES (...) written without column list? no — specifically statements like INSERT INTO t SELECT * FROM t2 lacking '(' before firstRightBracketIndex handling), or any malformed insert where firstLeftBracketIndex < 0.","commonSituations":"INSERT ... SELECT statements routed through multi-node insert logic; hand-written or generated SQL with syntax mistakes; ORM emitting inserts without column lists hitting this code path.","solutions":["Rewrite the INSERT to include an explicit column list: INSERT INTO t (col1, col2) VALUES (...)","Route INSERT ... SELECT statements to a single node instead of the sharded insert path (e.g. use hint or route to default node)","Fix SQL syntax so the statement is a well-formed INSERT with a values list"],"exampleFix":"-- before\nINSERT INTO t_order SELECT * FROM tmp_order;\n-- after\nINSERT INTO t_order (id, user_id, amount) VALUES (1, 100, 9.99);","handlingStrategy":"validation","validationCode":"// before routing\nString upper = sql.toUpperCase();\nif (!upper.matches(\"\\\\s*INSERT\\\\s+INTO\\\\s+\\\\S+\\\\s*\\\\(.*\")) {\n  throw new IllegalArgumentException(\"insert requires column list: \" + sql);\n}","typeGuard":null,"tryCatchPattern":"try { route(sql); } catch (SQLNonTransientException e) { if (e.getMessage().startsWith(\"invalid sql:\")) { /* fix or reroute to single node */ } throw e; }","preventionTips":["Always write INSERTs with explicit column lists","Avoid INSERT ... SELECT through MyCat sharded tables","Lint generated SQL in ORM/DAO layers"],"tags":["sql","insert","routing"],"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-16T04:17:20.429Z"}