{"record":{"id":"93c94ff035e9cca6","repo":"MyCATApache/Mycat-Server","slug":"syntax-error-illegal-charset","errorCode":null,"errorMessage":"syntax error, illegal charset","messagePattern":"syntax error, illegal charset","errorType":"exception","errorClass":"ParserException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/parser/druid/MycatStatementParser.java","lineNumber":98,"sourceCode":"        }\n\n        if (identifierEquals(IGNORE)) {\n            stmt.setIgnore(true);\n            lexer.nextToken();\n        }\n\n        accept(Token.INTO);\n        accept(Token.TABLE);\n\n        SQLName tableName = exprParser.name();\n        stmt.setTableName(tableName);\n\n        if (identifierEquals(CHARACTER)) {\n            lexer.nextToken();\n            accept(Token.SET);\n\n            if (lexer.token() != Token.LITERAL_CHARS) {\n                throw new ParserException(\"syntax error, illegal charset\");\n            }\n\n            String charset = lexer.stringVal();\n            lexer.nextToken();\n            stmt.setCharset(charset);\n        }\n\n        if (identifierEquals(\"FIELDS\") || identifierEquals(\"COLUMNS\")) {\n            lexer.nextToken();\n            if (identifierEquals(\"TERMINATED\")) {\n                lexer.nextToken();\n                accept(Token.BY);\n                stmt.setColumnsTerminatedBy(new SQLCharExpr(lexer.stringVal()));\n                lexer.nextToken();\n            }\n\n            if (identifierEquals(\"OPTIONALLY\")) {\n                stmt.setColumnsEnclosedOptionally(true);","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/parser/druid/MycatStatementParser.java#L80-L116","documentation":"The LOAD DATA INFILE parser requires the CHARACTER SET keyword to be followed by a quoted charset name (a string literal token). If the lexer does not produce LITERAL_CHARS after 'CHARACTER SET', Mycat throws this ParserException because the charset clause cannot be resolved. It is a SQL syntax guard inside Mycat's Druid-based LOAD DATA parsing (parseLoadDataInFile).","triggerScenarios":"Executing a LOAD DATA INFILE statement whose 'CHARACTER SET' clause is followed by something other than a quoted string literal, e.g. CHARACTER SET utf8 without quotes, a truncated statement, or a comment/garbage token where the charset name should be.","commonSituations":"Clients generating LOAD DATA statements with unquoted charsets (some MySQL docs examples omit quotes); truncated or hand-edited SQL sent to Mycat; Mycat's stricter parser rejecting SQL that plain MySQL tolerates.","solutions":["Quote the charset name in the LOAD DATA statement: LOAD DATA INFILE 'f.csv' INTO TABLE t CHARACTER SET 'utf8'.","Remove the CHARACTER SET clause entirely if the server/connection default charset is acceptable.","Check the full SQL text reaching Mycat for truncation or stray tokens after CHARACTER SET (e.g. logs/proxy rewriting)."],"exampleFix":"// before\nLOAD DATA INFILE '/tmp/a.csv' INTO TABLE t CHARACTER SET utf8;\n// after\nLOAD DATA INFILE '/tmp/a.csv' INTO TABLE t CHARACTER SET 'utf8';","handlingStrategy":"validation","validationCode":"// Validate the LOAD DATA statement before sending through Mycat\nif (/CHARACTER\\s+SET/i.test(sql) && !/CHARACTER\\s+SET\\s+'[^']+'/i.test(sql)) {\n  throw new Error(\"CHARACTER SET clause must use a quoted charset name\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always quote charset names in LOAD DATA INFILE statements.","Keep LOAD DATA statements simple; avoid hand-edited or proxy-rewritten SQL."],"tags":["sql-parsing","load-data-infile","charset"],"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"}