/// <exception cref="System.SqlSyntaxErrorException" /> public static void RouteFromHint(object frontConn, SchemaConfig schema, RouteResultset rrs, int prefixIndex, string sql) { var hint = CobarHint.ParserCobarHint(sql, prefixIndex); var outputSql = hint.OutputSql; var replica = hint.Replica; var table = hint.Table; var dataNodes = hint.DataNodes; var partitionOperand = hint.PartitionOperand; TableConfig tableConfig = null; if (table == null || schema.Tables == null || (tableConfig = schema.Tables.GetValue(table)) == null) { // table not indicated var nodes = new RouteResultsetNode[1]; rrs.Nodes = nodes; if (dataNodes != null && !dataNodes.IsEmpty()) { var replicaIndex = dataNodes[0].Value; if (replicaIndex >= 0 && RouteResultsetNode.DefaultReplicaIndex != replicaIndex) { // replica index indicated in dataNodes references nodes[0] = new RouteResultsetNode(schema.DataNode, replicaIndex, outputSql); LogExplicitReplicaSet(frontConn, sql, rrs); return; } } nodes[0] = new RouteResultsetNode(schema.DataNode, replica, outputSql); if (replica != RouteResultsetNode.DefaultReplicaIndex) { LogExplicitReplicaSet(frontConn, sql, rrs); } return; } if (dataNodes != null && !dataNodes.IsEmpty()) { var nodes = new RouteResultsetNode[dataNodes.Count]; rrs.Nodes = nodes; var i = 0; var replicaSet = false; foreach (var pair in dataNodes) { var dataNodeName = tableConfig.DataNodes[pair.Key]; var replicaIndex = dataNodes[i].Value; if (replicaIndex >= 0 && RouteResultsetNode.DefaultReplicaIndex != replicaIndex) { replicaSet = true; nodes[i] = new RouteResultsetNode(dataNodeName, replicaIndex, outputSql); } else { replicaSet = replicaSet || (replica != RouteResultsetNode.DefaultReplicaIndex); nodes[i] = new RouteResultsetNode(dataNodeName, replica, outputSql); } ++i; } if (replicaSet) { LogExplicitReplicaSet(frontConn, sql, rrs); } return; } if (partitionOperand == null) { var tableDataNodes = tableConfig.DataNodes; var nodes = new RouteResultsetNode[tableDataNodes.Length]; rrs.Nodes = nodes; for (var i = 0; i < nodes.Length; ++i) { nodes[i] = new RouteResultsetNode(tableDataNodes[i], replica, outputSql); } return; } var cols = partitionOperand.Key; var vals = partitionOperand.Value; if (cols == null || vals == null) { throw new SqlSyntaxErrorException("${partitionOperand} is invalid: " + sql); } RuleConfig rule = null; var tr = tableConfig.Rule; var rules = tr == null ? null : tr.Rules; if (rules != null) { foreach (var r in rules) { var ruleCols = r.Columns; var match = true; foreach (var ruleCol in ruleCols) { match &= cols.Contains(ruleCol); } if (match) { rule = r; break; } } } var tableDataNodes1 = tableConfig.DataNodes; if (rule == null) { var nodes = new RouteResultsetNode[tableDataNodes1.Length]; rrs.Nodes = nodes; var replicaSet = false; for (var i = 0; i < tableDataNodes1.Length; ++i) { replicaSet = replicaSet || (replica != RouteResultsetNode.DefaultReplicaIndex); nodes[i] = new RouteResultsetNode(tableDataNodes1[i], replica, outputSql); } if (replicaSet) { LogExplicitReplicaSet(frontConn, sql, rrs); } return; } var destDataNodes = CalcHintDataNodes(rule, cols, vals, tableDataNodes1); var nodes1 = new RouteResultsetNode[destDataNodes.Count]; rrs.Nodes = nodes1; var i1 = 0; var replicaSet1 = false; foreach (var dataNode in destDataNodes) { replicaSet1 = replicaSet1 || (replica != RouteResultsetNode.DefaultReplicaIndex); nodes1[i1++] = new RouteResultsetNode(dataNode, replica, outputSql); } if (replicaSet1) { LogExplicitReplicaSet(frontConn, sql, rrs); } }
public virtual void TestHint1() { var sql = " /*!cobar: $dataNodeId =2.1, $table='offer'*/ select * "; var hint = CobarHint.ParserCobarHint(sql, 2); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(1, hint.DataNodes.Count); Assert.AreEqual(new Pair <int, int>(2, 1), hint.DataNodes[0]); sql = " /*!cobar: $dataNodeId=0.0, $table='offer'*/ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(1, hint.DataNodes.Count); Assert.AreEqual(new Pair <int, int>(0, 0), hint.DataNodes[0]); sql = " /*!cobar: $dataNodeId=0, $table='offer'*/ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(1, hint.DataNodes.Count); //INFO Assert.AreEqual(new Pair<int, int>(0, null), hint.GetDataNodes()[0]); Assert.AreEqual(new Pair <int, int>(0, -1), hint.DataNodes[0]); sql = "/*!cobar: $dataNodeId = [ 1,2,5.2] , $table = 'offer' */ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(3, hint.DataNodes.Count); sql = "/*!cobar: $partitionOperand=( 'member_id' = 'm1'), $table='offer'*/ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); var pair = hint.PartitionOperand; Assert.AreEqual(1, pair.Key.Length); Assert.AreEqual("MEMBER_ID", pair.Key[0]); Assert.AreEqual(1, pair.Value.Length); Assert.AreEqual(1, pair.Value[0].Length); Assert.AreEqual("m1", pair.Value[0][0]); Assert.IsNull(hint.DataNodes); sql = "/*!cobar:$partitionOperand = ( 'member_id' = ['m1' , 'm2' ] ), $table='offer' , $replica= 2*/ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(2, hint.Replica); pair = hint.PartitionOperand; Assert.AreEqual(1, pair.Key.Length); Assert.AreEqual("MEMBER_ID", pair.Key[0]); Assert.AreEqual(2, pair.Value.Length); Assert.AreEqual(1, pair.Value[0].Length); Assert.AreEqual("m1", pair.Value[0][0]); Assert.AreEqual("m2", pair.Value[1][0]); Assert.IsNull(hint.DataNodes); sql = "/*!cobar:$partitionOperand=('member_id'=['m1', 'm2']),$table='offer',$replica=2*/ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(2, hint.Replica); pair = hint.PartitionOperand; Assert.AreEqual(1, pair.Key.Length); Assert.AreEqual("MEMBER_ID", pair.Key[0]); Assert.AreEqual(2, pair.Value.Length); Assert.AreEqual(1, pair.Value[0].Length); Assert.AreEqual("m1", pair.Value[0][0]); Assert.AreEqual("m2", pair.Value[1][0]); Assert.IsNull(hint.DataNodes); sql = "/*!cobar:$partitionOperand = ( ['offer_id','group_id'] = [123,'3c']), $table='offer'*/ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(RouteResultsetNode.DefaultReplicaIndex, hint.Replica); pair = hint.PartitionOperand; Assert.AreEqual(2, pair.Key.Length); Assert.AreEqual("OFFER_ID", pair.Key[0]); Assert.AreEqual("GROUP_ID", pair.Key[1]); Assert.AreEqual(1, pair.Value.Length); Assert.AreEqual(2, pair.Value[0].Length); Assert.AreEqual(123L, pair.Value[0][0]); Assert.AreEqual("3c", pair.Value[0][1]); Assert.IsNull(hint.DataNodes); sql = "/*!cobar:$partitionOperand=(['offer_id' , 'group_iD' ]=[ 123 , '3c' ]) ,$table = 'offer'*/ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(RouteResultsetNode.DefaultReplicaIndex, hint.Replica); pair = hint.PartitionOperand; Assert.AreEqual(2, pair.Key.Length); Assert.AreEqual("OFFER_ID", pair.Key[0]); Assert.AreEqual("GROUP_ID", pair.Key[1]); Assert.AreEqual(1, pair.Value.Length); Assert.AreEqual(2, pair.Value[0].Length); Assert.AreEqual(123L, pair.Value[0][0]); Assert.AreEqual("3c", pair.Value[0][1]); Assert.IsNull(hint.DataNodes); sql = "/*!cobar:$partitionOperand=(['offer_id','group_id']=[123,'3c']),$table='offer'*/ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(RouteResultsetNode.DefaultReplicaIndex, hint.Replica); pair = hint.PartitionOperand; Assert.AreEqual(2, pair.Key.Length); Assert.AreEqual("OFFER_ID", pair.Key[0]); Assert.AreEqual("GROUP_ID", pair.Key[1]); Assert.AreEqual(1, pair.Value.Length); Assert.AreEqual(2, pair.Value[0].Length); Assert.AreEqual(123L, pair.Value[0][0]); Assert.AreEqual("3c", pair.Value[0][1]); Assert.IsNull(hint.DataNodes); sql = "/*!cobar:$partitionOperand=(['offer_id','group_id']=[[123,'3c'],[234,'food']]), $table='offer'*/ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(RouteResultsetNode.DefaultReplicaIndex, hint.Replica); pair = hint.PartitionOperand; Assert.AreEqual(2, pair.Key.Length); Assert.AreEqual("OFFER_ID", pair.Key[0]); Assert.AreEqual("GROUP_ID", pair.Key[1]); Assert.AreEqual(2, pair.Value.Length); Assert.AreEqual(2, pair.Value[0].Length); Assert.AreEqual(2, pair.Value[1].Length); Assert.AreEqual(123L, pair.Value[0][0]); Assert.AreEqual("3c", pair.Value[0][1]); Assert.AreEqual(234L, pair.Value[1][0]); Assert.AreEqual("food", pair.Value[1][1]); Assert.IsNull(hint.DataNodes); sql = "/*!cobar:$partitionOperand= ( [ 'ofFER_id','groUp_id' ]= [ [123,'3c'],[ 234,'food']] ), $table='offer'*/select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual("select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(RouteResultsetNode.DefaultReplicaIndex, hint.Replica); pair = hint.PartitionOperand; Assert.AreEqual(2, pair.Key.Length); Assert.AreEqual("OFFER_ID", pair.Key[0]); Assert.AreEqual("GROUP_ID", pair.Key[1]); Assert.AreEqual(2, pair.Value.Length); Assert.AreEqual(2, pair.Value[0].Length); Assert.AreEqual(2, pair.Value[1].Length); Assert.AreEqual(123L, pair.Value[0][0]); Assert.AreEqual("3c", pair.Value[0][1]); Assert.AreEqual(234L, pair.Value[1][0]); Assert.AreEqual("food", pair.Value[1][1]); Assert.IsNull(hint.DataNodes); sql = "/*!cobar:$partitionOperand=(['offer_id']=[123,234]), $table='offer'*/ select * "; hint = CobarHint.ParserCobarHint(sql, 0); Assert.AreEqual(" select * ", hint.OutputSql); Assert.AreEqual("OFFER", hint.Table); Assert.AreEqual(RouteResultsetNode.DefaultReplicaIndex, hint.Replica); pair = hint.PartitionOperand; Assert.AreEqual(1, pair.Key.Length); Assert.AreEqual("OFFER_ID", pair.Key[0]); Assert.AreEqual(2, pair.Value.Length); Assert.AreEqual(1, pair.Value[0].Length); Assert.AreEqual(1, pair.Value[1].Length); Assert.AreEqual(123L, pair.Value[0][0]); Assert.AreEqual(234L, pair.Value[1][0]); Assert.IsNull(hint.DataNodes); }