示例#1
0
            /// <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);
                }
            }
示例#2
0
        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);
        }