{"record":{"id":"dcd90b0f79fa15ec","repo":"MyCATApache/Mycat-Server","slug":"childtable-multi-insert-not-provided","errorCode":null,"errorMessage":"ChildTable multi insert not provided","messagePattern":"ChildTable multi insert not provided","errorType":"exception","errorClass":"SQLNonTransientException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/parser/druid/impl/DruidInsertParser.java","lineNumber":133,"sourceCode":"\tprivate boolean isMultiInsert(MySqlInsertStatement insertStmt) {\n\t\treturn (insertStmt.getValuesList() != null && insertStmt.getValuesList().size() > 1) || insertStmt.getQuery() != null;\n\t}\n\t\n\tprivate RouteResultset parserChildTable(SchemaConfig schema, RouteResultset rrs,\n\t\t\tString tableName, MySqlInsertStatement insertStmt) throws SQLNonTransientException {\n\t\tTableConfig tc = schema.getTables().get(tableName);\n\t\t\n\t\tString joinKey = tc.getJoinKey();\n\t\tint joinKeyIndex = getJoinKeyIndex(insertStmt.getColumns(), joinKey);\n\t\tif(joinKeyIndex == -1) {\n\t\t\tString inf = \"joinKey not provided :\" + tc.getJoinKey()+ \",\" + insertStmt;\n\t\t\tLOGGER.warn(inf);\n\t\t\tthrow new SQLNonTransientException(inf);\n\t\t}\n\t\tif(isMultiInsert(insertStmt)) {\n\t\t\tString msg = \"ChildTable multi insert not provided\" ;\n\t\t\tLOGGER.warn(msg);\n\t\t\tthrow new SQLNonTransientException(msg);\n\t\t}\n\t\t\n\t\tString joinKeyVal = insertStmt.getValues().getValues().get(joinKeyIndex).toString();\n\n\t\t\n\t\tString sql = insertStmt.toString();\n\t\t\n\t\t// try to route by ER parent partion key\n\t\tRouteResultset theRrs = RouterUtil.routeByERParentKey(null,schema, ServerParse.INSERT,sql, rrs, tc,joinKeyVal);\n\t\tif (theRrs != null) {\n\t\t\trrs.setFinishedRoute(true);\n\t\t\treturn theRrs;\n\t\t}\n\n\t\t// route by sql query root parent's datanode\n\t\tString findRootTBSql = tc.getLocateRTableKeySql().toLowerCase() + joinKeyVal;\n\t\tif (LOGGER.isDebugEnabled()) {\n\t\t\tLOGGER.debug(\"find root parent's node sql \"+ findRootTBSql);","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/parser/druid/impl/DruidInsertParser.java#L115-L151","documentation":"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.","triggerScenarios":"INSERT INTO child_table (...joinKey...) VALUES (...), (...), ... (multiple VALUES tuples) on a table configured as childTable in schema.xml.","commonSituations":"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.","solutions":["Split the multi-row INSERT into separate single-row INSERT statements, one per child row.","Use a JDBC batch (addBatch/executeBatch) of single-row inserts instead of multi-row VALUES.","If bulk loading is needed, insert directly into backend data nodes, or temporarily configure the table as non-child."],"exampleFix":"// before\nINSERT INTO order_items (item_id, order_id, qty) VALUES (9,1001,2),(10,1002,1);\n// after\nINSERT INTO order_items (item_id, order_id, qty) VALUES (9,1001,2);\nINSERT INTO order_items (item_id, order_id, qty) VALUES (10,1002,1);","handlingStrategy":"fallback","validationCode":"// Detect multi-row VALUES and fall back to per-row inserts\nfunction splitMultiRowInsert(sql) {\n  if (sql.toUpperCase().includes(\"VALUES\") && (sql.match(/\\),\\s*\\(/g) || []).length > 0) {\n    return null; // caller should rewrite into single-row INSERTs\n  }\n  return sql;\n}","typeGuard":null,"tryCatchPattern":"try {\n  execute(sql);\n} catch (SQLNonTransientException e) {\n  if (e.getMessage().contains(\"ChildTable multi insert not provided\")) {\n    for (String single : splitIntoSingleRowInserts(sql)) execute(single);\n  } else { throw e; }\n}","preventionTips":["Avoid multi-row INSERTs against childTable-configured tables.","Use JDBC batch of single-row statements for bulk child inserts."],"tags":["insert","child-table","batch-insert"],"backgroundTag":"unsupported-operation","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"}