Example #1
0
 private static WColumnReferenceExpression GetNodeColumnReferenceExprFromLink(CompileLink link)
 {
     if (link is MatchEdge)
     {
         MatchEdge edge = link as MatchEdge;
         if (edge.EdgeType == WEdgeType.OutEdge)
         {
             return(SqlUtil.GetColumnReferenceExpr(edge.LinkAlias,
                                                   edge.IsReversed ? GremlinKeyword.EdgeSinkV : GremlinKeyword.EdgeSourceV));
         }
         else if (edge.EdgeType == WEdgeType.InEdge)
         {
             return(SqlUtil.GetColumnReferenceExpr(edge.LinkAlias,
                                                   edge.IsReversed ? GremlinKeyword.EdgeSourceV : GremlinKeyword.EdgeSinkV));
         }
         else
         {
             return(SqlUtil.GetColumnReferenceExpr(edge.LinkAlias, GremlinKeyword.EdgeOtherV));
         }
     }
     else if (link is PredicateLink)
     {
         PredicateLink predicateLink = link as PredicateLink;
         if (predicateLink.BooleanExpression is WEdgeVertexBridgeExpression)
         {
             return((predicateLink.BooleanExpression as WEdgeVertexBridgeExpression).FirstExpr as WColumnReferenceExpression);
         }
     }
     throw new QueryCompilationException("Cannot support " + link + " as a traversal link or an edge");
 }
Example #2
0
        /// <summary>
        /// Given a node / TVF, a traversalLink and backwardEdges, try to find all predicates that can be evaluated
        /// </summary>
        /// <param name="node"></param>
        /// <param name="traversalLink"></param>
        /// <param name="backwardEdges"></param>
        /// <param name="predicateLinksAccessedTableAliases"></param>
        private List <Tuple <PredicateLink, int> > FindPredicates(
            CompileNode node,
            CompileLink traversalLink,
            List <Tuple <MatchEdge, int> > backwardEdges,
            List <Tuple <PredicateLink, HashSet <string> > > predicateLinksAccessedTableAliases)
        {
            // Record temporary aliases and predicates
            HashSet <string> temporaryAliases               = new HashSet <string>(this.ExistingNodesAndEdges);
            HashSet <string> temporaryPredicates            = new HashSet <string>(this.ExistingPredicateLinks);
            List <Tuple <PredicateLink, int> > forwardLinks = new List <Tuple <PredicateLink, int> >();

            // priority = 1
            // retrieve traversalLink and add predicates
            if (traversalLink != null && !this.ExistingNodesAndEdges.Contains(traversalLink.LinkAlias))
            {
                // Find predicates that can be evaluated after retrieving this traversalLink
                if (traversalLink is MatchEdge)
                {
                    temporaryAliases.Add(traversalLink.LinkAlias);
                }
                else if (traversalLink is PredicateLink)
                {
                    temporaryPredicates.Add(traversalLink.LinkAlias);
                }
                else
                {
                    throw new QueryCompilationException("Cannot support " + traversalLink + " as a traversal link or an edge");
                }

                foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases)
                {
                    if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) &&
                        temporaryAliases.IsSupersetOf(tuple.Item2))
                    {
                        temporaryPredicates.Add(tuple.Item1.LinkAlias);
                        forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 1));
                    }
                }

                // Make sure the all existing edges and this traversalLink are consistent
                // Because all existing edges are consistent, we just need make one exstring edge and this traversalLink consistent
                MatchNode matchNode = node as MatchNode;
                WColumnReferenceExpression nodeColumnReferenceExprFromTraversalLink  = GetNodeColumnReferenceExprFromLink(traversalLink);
                WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(matchNode, this.ExistingNodesAndEdges);
                if (nodeColumnReferenceExprFromTraversalLink != null &&
                    nodeColumnReferenceExprFromAnExistingEdge != null)
                {
                    forwardLinks.Add(
                        new Tuple <PredicateLink, int>(
                            new PredicateLink(
                                SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromTraversalLink,
                                                                      nodeColumnReferenceExprFromAnExistingEdge)), 1));
                }
            }

            // priority = 2
            // retrieve node and some edges and add predicates
            temporaryAliases.Add(node.NodeAlias);
            foreach (Tuple <MatchEdge, int> tuple in backwardEdges)
            {
                if (tuple.Item2 == 2)
                {
                    temporaryAliases.Add(tuple.Item1.LinkAlias);
                    MatchNode otherNode = tuple.Item1.SinkNode;
                    WColumnReferenceExpression nodeColumnReferenceExprFromBackwardEdge   = null;
                    WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(otherNode, this.ExistingNodesAndEdges);
                    if (nodeColumnReferenceExprFromAnExistingEdge != null)
                    {
                        foreach (MatchEdge edge in otherNode.Neighbors)
                        {
                            if (edge.LinkAlias == tuple.Item1.LinkAlias)
                            {
                                nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                break;
                            }
                        }
                        if (nodeColumnReferenceExprFromBackwardEdge == null)
                        {
                            foreach (MatchEdge edge in otherNode.ReverseNeighbors)
                            {
                                if (edge.LinkAlias == tuple.Item1.LinkAlias)
                                {
                                    nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                    break;
                                }
                            }
                        }
                        if (nodeColumnReferenceExprFromBackwardEdge == null)
                        {
                            foreach (MatchEdge edge in otherNode.DanglingEdges)
                            {
                                if (edge.LinkAlias == tuple.Item1.LinkAlias)
                                {
                                    nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                    break;
                                }
                            }
                        }
                    }
                    // Because all existing edges are consistent, we just need make one exstring edge and this edge consistent
                    if (nodeColumnReferenceExprFromBackwardEdge != null &&
                        nodeColumnReferenceExprFromAnExistingEdge != null)
                    {
                        temporaryPredicates.Add(tuple.Item1.LinkAlias);
                        forwardLinks.Add(
                            new Tuple <PredicateLink, int>(
                                new PredicateLink(
                                    SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromBackwardEdge,
                                                                          nodeColumnReferenceExprFromAnExistingEdge)), 2));
                    }
                }
            }

            // Check predicates
            foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases)
            {
                if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) &&
                    temporaryAliases.IsSupersetOf(tuple.Item2))
                {
                    temporaryPredicates.Add(tuple.Item1.LinkAlias);
                    forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 2));
                }
            }

            // priority = 3
            // retrieve another edges and add predicates
            foreach (Tuple <MatchEdge, int> tuple in backwardEdges)
            {
                if (tuple.Item2 == 3)
                {
                    temporaryAliases.Add(tuple.Item1.LinkAlias);
                    MatchNode otherNode = tuple.Item1.SinkNode;
                    WColumnReferenceExpression nodeColumnReferenceExprFromBackwardEdge   = null;
                    WColumnReferenceExpression nodeColumnReferenceExprFromAnExistingEdge = GetNodeColumnReferenceExprFromAnExistingEdge(otherNode, this.ExistingNodesAndEdges);
                    if (nodeColumnReferenceExprFromAnExistingEdge != null)
                    {
                        foreach (MatchEdge edge in otherNode.Neighbors)
                        {
                            if (edge.LinkAlias == tuple.Item1.LinkAlias)
                            {
                                nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                break;
                            }
                        }
                        if (nodeColumnReferenceExprFromBackwardEdge == null)
                        {
                            foreach (MatchEdge edge in otherNode.ReverseNeighbors)
                            {
                                if (edge.LinkAlias == tuple.Item1.LinkAlias)
                                {
                                    nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                    break;
                                }
                            }
                        }
                        if (nodeColumnReferenceExprFromBackwardEdge == null)
                        {
                            foreach (MatchEdge edge in otherNode.DanglingEdges)
                            {
                                if (edge.LinkAlias == tuple.Item1.LinkAlias)
                                {
                                    nodeColumnReferenceExprFromBackwardEdge = GetNodeColumnReferenceExprFromLink(edge);
                                    break;
                                }
                            }
                        }
                    }
                    // Because all existing edges are consistent, we just need make one exstring edge and this edge consistent
                    if (nodeColumnReferenceExprFromBackwardEdge != null &&
                        nodeColumnReferenceExprFromAnExistingEdge != null)
                    {
                        temporaryPredicates.Add(tuple.Item1.LinkAlias);
                        forwardLinks.Add(
                            new Tuple <PredicateLink, int>(
                                new PredicateLink(
                                    SqlUtil.GetEqualBooleanComparisonExpr(nodeColumnReferenceExprFromBackwardEdge,
                                                                          nodeColumnReferenceExprFromAnExistingEdge)), 3));
                    }
                }
            }

            // Check predicates
            foreach (Tuple <PredicateLink, HashSet <string> > tuple in predicateLinksAccessedTableAliases)
            {
                if (!temporaryPredicates.Contains(tuple.Item1.LinkAlias) &&
                    temporaryAliases.IsSupersetOf(tuple.Item2))
                {
                    temporaryPredicates.Add(tuple.Item1.LinkAlias);
                    forwardLinks.Add(new Tuple <PredicateLink, int>(tuple.Item1, 3));
                }
            }
            return(forwardLinks);
        }