MyCATApache/Mycat-Server · error · SQLNonTransientException

ChildTable multi insert not provided

Error message

ChildTable multi insert not provided

What it means

Mycat's child-table (ER relation) insert routing handles only single-row inserts, because it resolves the storage node from one joinKey value of the parent row. parserChildTable detects isMultiInsert(insertStmt) after finding the joinKey and rejects multi-row (batch) INSERTs with this SQLNonTransientException.

Solutions

  1. Split the multi-row INSERT into separate single-row INSERT statements, one per child row.
  2. Use a JDBC batch (addBatch/executeBatch) of single-row inserts instead of multi-row VALUES.
  3. If bulk loading is needed, insert directly into backend data nodes, or temporarily configure the table as non-child.

Example fix

// before
INSERT INTO order_items (item_id, order_id, qty) VALUES (9,1001,2),(10,1002,1);
// after
INSERT INTO order_items (item_id, order_id, qty) VALUES (9,1001,2);
INSERT INTO order_items (item_id, order_id, qty) VALUES (10,1002,1);
Defensive patterns

Strategy: fallback

Validate before calling

// Detect multi-row VALUES and fall back to per-row inserts
function splitMultiRowInsert(sql) {
  if (sql.toUpperCase().includes("VALUES") && (sql.match(/\),\s*\(/g) || []).length > 0) {
    return null; // caller should rewrite into single-row INSERTs
  }
  return sql;
}

Try / catch

try {
  execute(sql);
} catch (SQLNonTransientException e) {
  if (e.getMessage().contains("ChildTable multi insert not provided")) {
    for (String single : splitIntoSingleRowInserts(sql)) execute(single);
  } else { throw e; }
}

Prevention

When it happens

Trigger: INSERT INTO child_table (...joinKey...) VALUES (...), (...), ... (multiple VALUES tuples) on a table configured as childTable in schema.xml.

Common situations: Batch seed/migration scripts inserting many child rows in one statement; ORM bulk-insert helpers generating multi-row VALUES; works on plain MySQL, fails through Mycat for ER tables.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/dcd90b0f79fa15ec. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/route/parser/druid/impl/DruidInsertParser.java:133

	private boolean isMultiInsert(MySqlInsertStatement insertStmt) {
		return (insertStmt.getValuesList() != null && insertStmt.getValuesList().size() > 1) || insertStmt.getQuery() != null;
	}
	
	private RouteResultset parserChildTable(SchemaConfig schema, RouteResultset rrs,
			String tableName, MySqlInsertStatement insertStmt) throws SQLNonTransientException {
		TableConfig tc = schema.getTables().get(tableName);
		
		String joinKey = tc.getJoinKey();
		int joinKeyIndex = getJoinKeyIndex(insertStmt.getColumns(), joinKey);
		if(joinKeyIndex == -1) {
			String inf = "joinKey not provided :" + tc.getJoinKey()+ "," + insertStmt;
			LOGGER.warn(inf);
			throw new SQLNonTransientException(inf);
		}
		if(isMultiInsert(insertStmt)) {
			String msg = "ChildTable multi insert not provided" ;
			LOGGER.warn(msg);
			throw new SQLNonTransientException(msg);
		}
		
		String joinKeyVal = insertStmt.getValues().getValues().get(joinKeyIndex).toString();

		
		String sql = insertStmt.toString();
		
		// try to route by ER parent partion key
		RouteResultset theRrs = RouterUtil.routeByERParentKey(null,schema, ServerParse.INSERT,sql, rrs, tc,joinKeyVal);
		if (theRrs != null) {
			rrs.setFinishedRoute(true);
			return theRrs;
		}

		// route by sql query root parent's datanode
		String findRootTBSql = tc.getLocateRTableKeySql().toLowerCase() + joinKeyVal;
		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug("find root parent's node sql "+ findRootTBSql);

View on GitHub (pinned to 65f8d8beb7)