private static void DispatchInsertReplace(RouteResultsetNode[] rn, DmlInsertReplaceStatement stmt, IList <string> ruleColumns, IDictionary <int, IList <object[]> > dataNodeMap, TableConfig matchedTable, string originalSql, PartitionKeyVisitor visitor) { if (stmt.Select != null) { DispatchWhereBasedStmt(rn, stmt, ruleColumns, dataNodeMap, matchedTable, originalSql, visitor); return; } var colsIndex = visitor.GetColumnIndex(stmt.Table.IdTextUpUnescape); if (colsIndex == null || colsIndex.IsEmpty()) { throw new ArgumentException("columns index is empty: " + originalSql); } var colsIndexList = new List <ColumnValueType>(ruleColumns.Count); for (int i = 0, len = ruleColumns.Count; i < len; ++i) { colsIndexList.Add(colsIndex[ruleColumns[i]]); } var dataNodeId = -1; foreach (var en in dataNodeMap) { var tuples = en.Value; var replaceRowList = new HashSet <RowExpression>(); foreach (var tuple in tuples) { ICollection <Pair <IExpression, IAstNode> > tupleExprs = null; for (var i1 = 0; i1 < tuple.Length; ++i1) { var valueMap = colsIndexList[i1]; var value = tuple[i1]; var set = GetExpressionSet(valueMap, value); tupleExprs = CollectionUtil.IntersectSet(tupleExprs, set); } if (tupleExprs == null || tupleExprs.IsEmpty()) { throw new ArgumentException( string.Format("route: empty expression list for insertReplace stmt: {0}", originalSql)); } foreach (var p in tupleExprs) { if (p.Value == stmt && p.Key is RowExpression) { replaceRowList.Add((RowExpression)p.Key); } } } stmt.ReplaceRowList = new List <RowExpression>(replaceRowList); var sql = GenSql(stmt, originalSql); stmt.ClearReplaceRowList(); var dataNodeName = matchedTable.DataNodes[en.Key]; rn[++dataNodeId] = new RouteResultsetNode(dataNodeName, sql); } }
private static void DispatchWhereBasedStmt(RouteResultsetNode[] rn, ISqlStatement stmtAST, IList <string> ruleColumns, IDictionary <int, IList <object[]> > dataNodeMap, TableConfig matchedTable, string originalSQL, PartitionKeyVisitor visitor) { // [perf tag] 11.617 us: sharding multivalue if (ruleColumns.Count > 1) { string sql; if (visitor.IsSchemaTrimmed()) { sql = GenSql(stmtAST, originalSQL); } else { sql = originalSQL; } var i = -1; foreach (var dataNodeId in dataNodeMap.Keys) { var dataNode = matchedTable.DataNodes[dataNodeId]; rn[++i] = new RouteResultsetNode(dataNode, sql); } return; } var table = matchedTable.Name; var columnIndex = visitor.GetColumnIndex(table); var valueMap = columnIndex.GetValue(ruleColumns[0]); ReplacePartitionKeyOperand(columnIndex, ruleColumns); var unreplacedInExpr = new Dictionary <InExpression, ICollection <IExpression> >(1); var unreplacedSingleExprs = new HashSet <IReplacableExpression>(); // [perf tag] 12.2755 us: sharding multivalue var nodeId = -1; foreach (var en in dataNodeMap) { var tuples = en.Value; unreplacedSingleExprs.Clear(); unreplacedInExpr.Clear(); foreach (var tuple in tuples) { var value = tuple[0]; var indexedExpressionPair = GetExpressionSet(valueMap, value); foreach (var pair in indexedExpressionPair) { var expr = pair.Key; var parent = (InExpression)pair.Value; if (PartitionKeyVisitor.IsPartitionKeyOperandSingle(expr, parent)) { unreplacedSingleExprs.Add((IReplacableExpression)expr); } else if (PartitionKeyVisitor.IsPartitionKeyOperandIn(expr, parent)) { var newInSet = unreplacedInExpr.GetValue(parent); if (newInSet == null) { newInSet = new HashSet <IExpression>(); unreplacedInExpr[parent] = newInSet; } newInSet.Add(expr); } } } // [perf tag] 15.3745 us: sharding multivalue foreach (var expr1 in unreplacedSingleExprs) { expr1.ClearReplaceExpr(); } foreach (var entemp in unreplacedInExpr) { var @in = entemp.Key; var set = entemp.Value; if (set == null || set.IsEmpty()) { @in.ReplaceExpr = ReplacableExpressionConstants.BoolFalse; } else { @in.ClearReplaceExpr(); var inlist = @in.GetInExpressionList(); if (inlist != null) { inlist.ReplaceExpr = new List <IExpression>(set); } } } // [perf tag] 16.506 us: sharding multivalue var sql = GenSql(stmtAST, originalSQL); // [perf tag] 21.3425 us: sharding multivalue var dataNodeName = matchedTable.DataNodes[en.Key]; rn[++nodeId] = new RouteResultsetNode(dataNodeName, sql); foreach (var expr2 in unreplacedSingleExprs) { expr2.ReplaceExpr = ReplacableExpressionConstants.BoolFalse; } foreach (var in1 in unreplacedInExpr.Keys) { in1.ReplaceExpr = ReplacableExpressionConstants.BoolFalse; var list = in1.GetInExpressionList(); if (list != null) { list.ClearReplaceExpr(); } } } }