Наследование: WSqlFragment
Пример #1
0
        internal WMatchClause GetMatchClause()
        {
            var newMatchClause = new WMatchClause();

            foreach (var path in PathList)
            {
                newMatchClause.Paths.Add(SqlUtil.GetMatchPath(path));
            }
            return(newMatchClause.Paths.Count == 0 ? null : newMatchClause);
        }
Пример #2
0
        internal WMatchClause GetMatchClause()
        {
            var newMatchClause = new WMatchClause();

            foreach (var path in PathList)
            {
                if (path.EdgeVariable is GremlinFreeEdgeTableVariable && VariableList.Contains(path.EdgeVariable))
                {
                    newMatchClause.Paths.Add(path.ToMatchPath());
                }
            }
            return(newMatchClause.Paths.Count == 0 ? null : newMatchClause);
        }
Пример #3
0
        // Greate the MatchGraph of this AggregationBlock. If some free nodes and free edges are connected, they are in the same ConnectedComponent
        internal HashSet <string> CreateMatchGraph(WMatchClause matchClause)
        {
            HashSet <string> freeNodesAndEdges = new HashSet <string>();
            Dictionary <string, MatchPath>          pathCollection     = new Dictionary <string, MatchPath>(StringComparer.OrdinalIgnoreCase);
            Dictionary <string, MatchNode>          nodeCollection     = new Dictionary <string, MatchNode>(StringComparer.OrdinalIgnoreCase);
            Dictionary <string, MatchEdge>          edgeCollection     = new Dictionary <string, MatchEdge>(StringComparer.OrdinalIgnoreCase);
            Dictionary <string, ConnectedComponent> subgraphCollection = new Dictionary <string, ConnectedComponent>(StringComparer.OrdinalIgnoreCase);

            // we use Disjoint-set data structure to determine whether tables are in the same component or not.
            UnionFind unionFind = new UnionFind();

            foreach (ConnectedComponent subgraph in this.GraphPattern.ConnectedSubgraphs)
            {
                foreach (KeyValuePair <string, MatchNode> pair in subgraph.Nodes)
                {
                    nodeCollection.Add(pair.Key, pair.Value);
                    unionFind.Add(pair.Key);
                }
            }

            if (matchClause != null)
            {
                foreach (WMatchPath path in matchClause.Paths)
                {
                    int       index         = 0;
                    bool      outOfBlock    = false;
                    MatchEdge edgeToSrcNode = null;

                    for (int count = path.PathEdgeList.Count; index < count; ++index)
                    {
                        WSchemaObjectName currentNodeTableRef = path.PathEdgeList[index].Item1;
                        WEdgeColumnReferenceExpression currentEdgeColumnRef = path.PathEdgeList[index].Item2;
                        WSchemaObjectName nextNodeTableRef = index != count - 1
                            ? path.PathEdgeList[index + 1].Item1
                            : path.Tail;
                        string currentNodeExposedName = currentNodeTableRef.BaseIdentifier.Value;
                        string edgeAlias           = currentEdgeColumnRef.Alias;
                        string nextNodeExposedName = nextNodeTableRef != null ? nextNodeTableRef.BaseIdentifier.Value : null;

                        // Get the source node of a path
                        if (!nodeCollection.ContainsKey(currentNodeExposedName))
                        {
                            continue;
                        }
                        MatchNode srcNode = nodeCollection[currentNodeExposedName];

                        // Get the edge of a path, and set required attributes
                        // Because the sourceNode is relative, we need to construct new edges or paths
                        // But they need to share the same predicates and proerties
                        MatchEdge edgeFromSrcNode;
                        if (currentEdgeColumnRef.MinLength == 1 && currentEdgeColumnRef.MaxLength == 1)
                        {
                            if (!edgeCollection.ContainsKey(edgeAlias))
                            {
                                edgeCollection[edgeAlias] = new MatchEdge()
                                {
                                    LinkAlias            = edgeAlias,
                                    SourceNode           = srcNode,
                                    EdgeType             = currentEdgeColumnRef.EdgeType,
                                    Predicates           = new List <WBooleanExpression>(),
                                    BindNodeTableObjName = new WSchemaObjectName(),
                                    IsReversed           = false,
                                    Properties           = new List <string>(GraphViewReservedProperties.ReservedEdgeProperties)
                                };
                                unionFind.Add(edgeAlias);
                            }

                            edgeFromSrcNode = new MatchEdge
                            {
                                LinkAlias            = edgeAlias,
                                SourceNode           = srcNode,
                                EdgeType             = edgeCollection[edgeAlias].EdgeType,
                                Predicates           = edgeCollection[edgeAlias].Predicates,
                                BindNodeTableObjName = edgeCollection[edgeAlias].BindNodeTableObjName,
                                IsReversed           = false,
                                Properties           = edgeCollection[edgeAlias].Properties
                            };
                        }
                        else
                        {
                            if (!pathCollection.ContainsKey(edgeAlias))
                            {
                                pathCollection[edgeAlias] = new MatchPath
                                {
                                    SourceNode           = srcNode,
                                    LinkAlias            = edgeAlias,
                                    Predicates           = new List <WBooleanExpression>(),
                                    BindNodeTableObjName = new WSchemaObjectName(),
                                    MinLength            = currentEdgeColumnRef.MinLength,
                                    MaxLength            = currentEdgeColumnRef.MaxLength,
                                    ReferencePathInfo    = false,
                                    AttributeValueDict   = currentEdgeColumnRef.AttributeValueDict,
                                    IsReversed           = false,
                                    EdgeType             = currentEdgeColumnRef.EdgeType,
                                    Properties           = new List <string>(GraphViewReservedProperties.ReservedEdgeProperties)
                                };
                            }

                            edgeFromSrcNode = new MatchPath
                            {
                                SourceNode           = srcNode,
                                LinkAlias            = edgeAlias,
                                Predicates           = pathCollection[edgeAlias].Predicates,
                                BindNodeTableObjName = pathCollection[edgeAlias].BindNodeTableObjName,
                                MinLength            = pathCollection[edgeAlias].MinLength,
                                MaxLength            = pathCollection[edgeAlias].MaxLength,
                                ReferencePathInfo    = false,
                                AttributeValueDict   = pathCollection[edgeAlias].AttributeValueDict,
                                IsReversed           = false,
                                EdgeType             = pathCollection[edgeAlias].EdgeType,
                                Properties           = pathCollection[edgeAlias].Properties
                            };
                        }

                        if (path.IsReversed)
                        {
                            unionFind.Union(edgeAlias, currentNodeExposedName);
                        }
                        else
                        {
                            unionFind.Union(currentNodeExposedName, edgeAlias);
                        }

                        if (edgeToSrcNode != null)
                        {
                            edgeToSrcNode.SinkNode = srcNode;

                            if (!(edgeToSrcNode is MatchPath))
                            {
                                // Construct reverse edge
                                MatchEdge reverseEdge = new MatchEdge
                                {
                                    SourceNode           = edgeToSrcNode.SinkNode,
                                    SinkNode             = edgeToSrcNode.SourceNode,
                                    LinkAlias            = edgeToSrcNode.LinkAlias,
                                    Predicates           = edgeToSrcNode.Predicates,
                                    BindNodeTableObjName = edgeToSrcNode.BindNodeTableObjName,
                                    IsReversed           = true,
                                    EdgeType             = edgeToSrcNode.EdgeType,
                                    Properties           = edgeToSrcNode.Properties,
                                };
                                srcNode.ReverseNeighbors.Add(reverseEdge);
                            }
                        }

                        edgeToSrcNode = edgeFromSrcNode;

                        // Add this edge to node's neightbors
                        if (nextNodeExposedName != null)
                        {
                            if (path.IsReversed)
                            {
                                unionFind.Union(nextNodeExposedName, edgeAlias);
                            }
                            else
                            {
                                unionFind.Union(edgeAlias, nextNodeExposedName);
                            }

                            srcNode.Neighbors.Add(edgeFromSrcNode);
                        }
                        // Add this edge to node's dangling edges
                        else
                        {
                            srcNode.DanglingEdges.Add(edgeFromSrcNode);
                        }
                    }

                    if (path.Tail == null)
                    {
                        continue;
                    }

                    // Get destination node of a path
                    string tailExposedName = path.Tail.BaseIdentifier.Value;

                    if (!nodeCollection.ContainsKey(tailExposedName))
                    {
                        continue;
                    }

                    MatchNode destNode = nodeCollection[tailExposedName];

                    if (edgeToSrcNode != null)
                    {
                        edgeToSrcNode.SinkNode = destNode;
                        if (!(edgeToSrcNode is MatchPath))
                        {
                            // Construct reverse edge
                            MatchEdge reverseEdge = new MatchEdge
                            {
                                SourceNode           = edgeToSrcNode.SinkNode,
                                SinkNode             = edgeToSrcNode.SourceNode,
                                LinkAlias            = edgeToSrcNode.LinkAlias,
                                Predicates           = edgeToSrcNode.Predicates,
                                BindNodeTableObjName = edgeToSrcNode.BindNodeTableObjName,
                                IsReversed           = true,
                                EdgeType             = edgeToSrcNode.EdgeType,
                                Properties           = edgeToSrcNode.Properties,
                            };
                            destNode.ReverseNeighbors.Add(reverseEdge);
                        }
                    }
                }
            }

            // Use union find algorithmn to define which subgraph does a node belong to and put it into where it belongs to.
            foreach (var node in nodeCollection)
            {
                freeNodesAndEdges.Add(node.Key);
                string root = unionFind.Find(node.Key);

                ConnectedComponent subGraph;
                if (!subgraphCollection.ContainsKey(root))
                {
                    subGraph = new ConnectedComponent();
                    subgraphCollection[root] = subGraph;
                }
                else
                {
                    subGraph = subgraphCollection[root];
                }

                subGraph.Nodes[node.Key] = node.Value;

                subGraph.IsTailNode[node.Value] = false;

                foreach (MatchEdge edge in node.Value.Neighbors)
                {
                    subGraph.Edges[edge.LinkAlias] = edge;
                    freeNodesAndEdges.Add(edge.LinkAlias);
                }

                foreach (MatchEdge edge in node.Value.DanglingEdges)
                {
                    subGraph.Edges[edge.LinkAlias] = edge;
                    edge.IsDanglingEdge            = true;
                    freeNodesAndEdges.Add(edge.LinkAlias);
                }

                if (node.Value.Neighbors.Count + node.Value.ReverseNeighbors.Count + node.Value.DanglingEdges.Count > 0)
                {
                    node.Value.Properties.Add(GremlinKeyword.Star);
                }
            }

            this.GraphPattern = new MatchGraph(subgraphCollection.Values.ToList());

            return(freeNodesAndEdges);
        }
Пример #4
0
 public virtual void Visit(WMatchClause node)
 {
     node.AcceptChildren(this);
 }
Пример #5
0
 private static bool ParseMatchClause(
     IList<TSqlParserToken> tokens,
     ref int nextToken,
     ref WMatchClause result,
     ref int farestError)
 {
     var currentToken = nextToken;
     var firstToken = nextToken;
     var paths = new List<WMatchPath>();
     WMatchPath path = null;
     if (!ReadToken(tokens, "MATCH", ref currentToken, ref farestError))
         return false;
     while (ParseMatchPath(tokens, ref currentToken, ref path, ref farestError))
     {
         paths.Add(path);
         if (!ReadToken(tokens, ",", ref currentToken, ref farestError))
             break;
     }
     if (paths.Count == 0)
         return false;
     result = new WMatchClause
     {
         Paths = paths,
         FirstTokenIndex = firstToken,
         LastTokenIndex = currentToken - 1,
     };
     nextToken = currentToken;
     return true;
 }
Пример #6
0
 public virtual void Visit(WMatchClause node)
 {
     node.AcceptChildren(this);
 }
        private WMatchClause ConstructReversedMatchClause(WSelectQueryBlock node, WSqlTableContext context)
        {
            var result = new WMatchClause()
            {
                Paths = new List<WMatchPath>(),
            };

            foreach (var path in node.MatchClause.Paths)
            {
                var reversedEdgeNameList = new List<string>();
                var nodeList = new List<Tuple<WSchemaObjectName, WEdgeColumnReferenceExpression>>();
                var edgeList = path.PathEdgeList;

                for (var i = 0; i < edgeList.Count; ++i)
                {
                    var sourceTableName = edgeList[i].Item1.Identifiers.Last().Value;
                    var edgeName = edgeList[i].Item2.MultiPartIdentifier.Identifiers.Last().Value;
                    WTableReference sourceTable = context[sourceTableName];
                    var sourceTableObjectName =
                        (sourceTable as WNamedTableReference).TableObjectName.Identifiers.Last().Value;

                    reversedEdgeNameList.Add(sourceTableObjectName + "_" + edgeName + "Reversed");
                }

                var sinkIdentifier = path.Tail.Identifiers.Last();

                for (var i = edgeList.Count - 1; i >= 0; --i)
                {
                    var nodeName = new WSchemaObjectName()
                    {
                        Identifiers = new List<Identifier>
                        {
                            new Identifier()
                            {
                                Value = sinkIdentifier.Value,
                                QuoteType = sinkIdentifier.QuoteType,
                            }
                        },
                    };

                    var originalPath = edgeList[i].Item2;
                    var edgeCol = new WEdgeColumnReferenceExpression()
                    {
                        ColumnType = ColumnType.Regular,
                        Alias = originalPath.Alias,
                        MaxLength = originalPath.MaxLength,
                        MinLength = originalPath.MinLength,
                        AttributeValueDict = originalPath.AttributeValueDict,
                        MultiPartIdentifier = new WMultiPartIdentifier(new Identifier()
                        {
                            QuoteType = originalPath.MultiPartIdentifier.Identifiers.Last().QuoteType,
                            Value = reversedEdgeNameList[i],
                        }),
                    };

                    nodeList.Add(new Tuple<WSchemaObjectName, WEdgeColumnReferenceExpression>(nodeName, edgeCol));
                    sinkIdentifier = edgeList[i].Item1.Identifiers.Last();
                }

                result.Paths.Add(new WMatchPath
                                 {
                                     PathEdgeList = nodeList,
                                     Tail = edgeList[0].Item1,
                                     IsReversed = true,
                                 });
            }

            return result;
        }