MyCATApache/Mycat-Server · error · SQLNonTransientException
"bad insert sql (sharding column:"+ partitionColumn + " not…
Error message
"bad insert sql (sharding column:"+ partitionColumn + " not provided," + insertStmt
What it means
For a sharded (non-child) table, Mycat needs the sharding/partition column's value from an INSERT to compute the target datanode. parserSingleInsert scans the statement's column list for the partition column; if it is absent (isFound == false), routing is impossible and it throws SQLNonTransientException.
Solutions
- Always include the sharding column and a concrete value in the INSERT column list and VALUES
- Check schema.xml partitionColumn name matches the actual column exactly (it is compared uppercased)
- If the column has a default/auto-increment, still pass an explicit value in the INSERT
- Change the sharding rule/column if the application inserts without that column
Example fix
// before INSERT INTO orders (id, amount) VALUES (1, 99); // after INSERT INTO orders (id, user_id, amount) VALUES (1, 42, 99); -- user_id is partitionColumn
Defensive patterns
Strategy: validation
Validate before calling
// validate shard key presence before single insert
Set<String> cols = extractInsertColumns(sql); // uppercased
String pc = tableConfig.getRule().getRuleAlgorithm() != null ? getPartitionColumn(tableConfig) : null;
if (pc != null && !cols.contains(pc.toUpperCase())) {
throw new IllegalArgumentException("Insert must include sharding column: " + pc);
} Type guard
static boolean containsShardingColumn(InsertStatement ins, TableConfig tc) {
String pc = tc.getPartitionColumn();
return pc == null || ins.getColumns().stream()
.map(c -> c.toString().toUpperCase())
.anyMatch(c -> c.equals(pc.toUpperCase()));
} Try / catch
try {
executeInsert(sql);
} catch (SQLNonTransientException e) {
if (e.getMessage().startsWith("bad insert sql (sharding column:")) {
throw new IllegalArgumentException("Include the sharding column in every INSERT", e);
}
throw e;
} Prevention
- Always specify full column lists including the shard key in INSERTs
- Never rely on defaults/auto-increment for a sharding column
- Cross-check partitionColumn in schema.xml against the real column name during deployments
When it happens
Trigger: Single-row `INSERT INTO sharded_table (cols...) VALUES (...)` where the partition column configured in schema.xml rule (partitionColumn) is not among cols. Also triggered when column names use backquotes/case that defeat the uppercase compare after removeBackquote is skipped.
Common situations: Insert with an abbreviated column list omitting the shard key; relying on DB default/auto-increment for the shard key; partitionColumn typo in schema.xml (e.g. wrong case or name); table rule configured after data model change.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- bad insert sql columnSize != valueSize:values:
- TODO:insert into .... select .... not supported!
- insert must provide ColumnList
- "joinKey not provided :" + tc.getJoinKey()+ "," + insertStmt
- "Sharding column can't be updated: " + tableName + " -> " +…
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/e08a9bbc2fa5c1af.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/parser/druid/impl/DruidInsertParser.java:203
if(partitionColumn.equalsIgnoreCase(StringUtil.removeBackquote(insertStmt.getColumns().get(i).toString()))) {//找到分片字段
isFound = true;
String column = StringUtil.removeBackquote(insertStmt.getColumns().get(i).toString());
String shardingValue = StringUtil.removeBackquote(getShardingValue(insertStmt.getValues().getValues().get(i)));
insertStmt.getValues().getValues().set(i,new SQLCharExpr(shardingValue));
ctx.setSql(insertStmt.toString());
RouteCalculateUnit routeCalculateUnit = new RouteCalculateUnit();
routeCalculateUnit.addShardingExpr(tableName, column, shardingValue);
ctx.addRouteCalculateUnit(routeCalculateUnit);
//mycat是单分片键,找到了就返回
break;
}
}
if(!isFound) {//分片表的
String msg = "bad insert sql (sharding column:"+ partitionColumn + " not provided," + insertStmt;
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
// insert into .... on duplicateKey
//such as :INSERT INTO TABLEName (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE b=VALUES(b);
//INSERT INTO TABLEName (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;
if(insertStmt.getDuplicateKeyUpdate() != null) {
List<SQLExpr> updateList = insertStmt.getDuplicateKeyUpdate();
for(SQLExpr expr : updateList) {
SQLBinaryOpExpr opExpr = (SQLBinaryOpExpr)expr;
String column = StringUtil.removeBackquote(opExpr.getLeft().toString().toUpperCase());
if(column.equals(partitionColumn)) {
String msg = "Sharding column can't be updated: " + tableName + " -> " + partitionColumn;
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
}
}
}
View on GitHub (pinned to 65f8d8beb7)