Inheritance: WColumnReferenceExpression
Example #1
0
        public override void Visit(WMatchPath node)
        {
            foreach (var sourceEdge in node.PathEdgeList)
            {
                WSchemaObjectName source            = sourceEdge.Item1;
                string            tableAlias        = source.BaseIdentifier.Value;
                WEdgeColumnReferenceExpression edge = sourceEdge.Item2;

                if (accessedColumns.ContainsKey(tableAlias))
                {
                    switch (edge.EdgeType)
                    {
                    case WEdgeType.OutEdge:
                        accessedColumns[tableAlias].Add(ColumnGraphType.OutAdjacencyList.ToString());
                        break;

                    case WEdgeType.InEdge:
                        accessedColumns[tableAlias].Add(ColumnGraphType.InAdjacencyList.ToString());
                        break;

                    case WEdgeType.BothEdge:
                        accessedColumns[tableAlias].Add(ColumnGraphType.BothAdjacencyList.ToString());
                        break;

                    default:
                        break;
                    }
                }
            }
        }
 public void AddEdgeReference(string name, WSchemaObjectName sourceNodeName, WEdgeColumnReferenceExpression edgeReference)
 {
     if (_nodeTableDictionary.ContainsKey(name) || _edgeDictionary.ContainsKey(name))
     {
         throw new GraphViewException("Duplicate Alias");
     }
     _edgeDictionary.Add(name,
                         new Tuple <WSchemaObjectName, WEdgeColumnReferenceExpression>(sourceNodeName, edgeReference));
 }
 public WDeleteEdgeSpecification(WSelectQueryBlock deleteSpec)
 {
     SelectDeleteExpr = deleteSpec;
     //FromClause = new WFromClause
     //{
     //    TableReferences = new List<WTableReference>
     //    {
     //        new WQueryDerivedTable
     //        {
     //            QueryExpr = deleteSpec
     //        }
     //    }
     //};
     EdgeColumn = deleteSpec.MatchClause.Paths[0].PathEdgeList[0].Item2;
 }
Example #4
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);
        }
 public virtual void Visit(WEdgeColumnReferenceExpression node)
 {
     node.AcceptChildren(this);
 }
        public override void Visit(WEdgeColumnReferenceExpression node)
        {
            string nodeStr = string.IsNullOrEmpty(node.Alias) ? node.MultiPartIdentifier.ToString() : $"{node.MultiPartIdentifier} AS {node.Alias}";

            this.dfsStack.Push(nodeStr);
        }
Example #7
0
        private static bool ParseMatchPathEdge(
            IList<TSqlParserToken> tokens,
            ref int nextToken,
            ref WEdgeColumnReferenceExpression result,
            ref int farestError)
        {
            var currentToken = nextToken;
            Identifier edgeIdentifier = null;
            if (!ParseQuotedIdentifier(tokens, ref currentToken, ref edgeIdentifier, ref farestError))
                return false;

            nextToken = currentToken;
            var spiltEdgeIdentifier = edgeIdentifier.Value.Split(' ');
            string alias = null;
            if (spiltEdgeIdentifier.Length > 1)
            {
                alias = spiltEdgeIdentifier.Last();
                if (GraphViewKeywords._keywords.Contains(alias))
                    throw new SyntaxErrorException(string.Format("System restricted Name {0} cannot be used",
                        alias));
                edgeIdentifier.Value = spiltEdgeIdentifier.First();
            }
            result = new WEdgeColumnReferenceExpression
            {
                ColumnType = ColumnType.Regular,
                MultiPartIdentifier = new WMultiPartIdentifier(edgeIdentifier),
                FirstTokenIndex = currentToken - 1,
                LastTokenIndex = currentToken - 1,
                Alias = alias,
                AliasRole = AliasType.UserSpecified
            };
            return true;
        }
 public virtual void Visit(WEdgeColumnReferenceExpression node)
 {
     node.AcceptChildren(this);
 }
Example #9
0
 public WDeleteEdgeSpecification(WSelectQueryBlock deleteSpec)
 {
     SelectDeleteExpr = deleteSpec;
     //FromClause = new WFromClause
     //{
     //    TableReferences = new List<WTableReference>
     //    {
     //        new WQueryDerivedTable
     //        {
     //            QueryExpr = deleteSpec
     //        }
     //    }
     //};
     EdgeColumn = deleteSpec.MatchClause.Paths[0].PathEdgeList[0].Item2;
 }
        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;
        }
        private WMultiCommonTableExpression ConstructDeleteEdgeSelect(WSelectQueryBlock node, WEdgeColumnReferenceExpression edgeCol, string tempTableName
            ,out WTableReference sinkTable, out WTableReference sourceTable, ref bool hasReversedEdge)
        {
            sourceTable = null;
            sinkTable = null;
            string sourceTableName = null;
            string sinkTableName = null;
            var sourceTableScalar = node.SelectElements[0] as WSelectScalarExpression;
            if (sourceTableScalar == null)
                return null;
            var sourceTableColumn = sourceTableScalar.SelectExpr as WColumnReferenceExpression;
            if (sourceTableColumn == null)
                return null;
            sourceTableName = sourceTableColumn.MultiPartIdentifier.Identifiers.Last().Value;

            var sourceNodeIdExpr = new WColumnReferenceExpression();
            foreach (var identifier in sourceTableColumn.MultiPartIdentifier.Identifiers)
                sourceNodeIdExpr.Add(identifier);
            sourceNodeIdExpr.AddIdentifier("GlobalNodeId");

            var collectVarVisitor = new CollectVariableVisitor();
            var context = collectVarVisitor.Invoke(node);
            if (!context.NodeTableDictionary.Any())
            {
                throw new GraphViewException("Missing From Clause in Delete Edge statement");
            }
            WColumnReferenceExpression sinkNodeIdExpr = null;
            sourceTable = context[sourceTableName];

            var groupByParams = new List<WScalarExpression>();
            for (var index = 1; index < node.SelectElements.Count; ++index)
            {
                var element = node.SelectElements[index] as WSelectScalarExpression;
                if (element == null)
                    return null;
                //sink table
                if (index == 1)
                {
                    var sinkTableColumn = element.SelectExpr as WColumnReferenceExpression;
                    if (sinkTableColumn == null)
                        return null;

                    sinkTableName = sinkTableColumn.MultiPartIdentifier.Identifiers.Last().Value;
                    sinkTable = context[sinkTableName];

                    sinkNodeIdExpr = new WColumnReferenceExpression();
                    foreach (var identifier in sinkTableColumn.MultiPartIdentifier.Identifiers)
                        sinkNodeIdExpr.Add(identifier);
                    sinkNodeIdExpr.AddIdentifier("GlobalNodeId");
                }
            }

            var sourceNodeId = new WSelectScalarExpression
            {
                SelectExpr = sourceNodeIdExpr,
                ColumnName = "src",
            };
            var sinkNodeId = new WSelectScalarExpression
            {
                SelectExpr = sinkNodeIdExpr,
                ColumnName = "sink"
            };
            var edgeId = new WSelectScalarExpression
            {
                SelectExpr = new WColumnReferenceExpression
                {
                    MultiPartIdentifier = new WMultiPartIdentifier(
                        new Identifier[]
                        {
                            new Identifier {Value = edgeCol.Alias??string.Format("{0}_{1}_{2}",sourceTableName,edgeCol.MultiPartIdentifier.Identifiers.Last().Value,sinkTableName)},
                            new Identifier {Value = "Edgeid"}
                        })
                },
                ColumnName = "edgeid"
            };

            var sourceTableNameRef = sourceTable as WNamedTableReference;
            if (sourceTableNameRef == null)
                throw new GraphViewException("Source table of DELETE EDGE statement should be a named table reference.");
            var sinkTableNameRef = sinkTable as WNamedTableReference;
            if (sinkTableNameRef == null)
                throw new GraphViewException("Sink table of DELETE EDGE statement should be a named table reference.");
            int compare = string.CompareOrdinal(sourceTableNameRef.TableObjectName.ToString(), sinkTableNameRef.TableObjectName.ToString());

            using (var command = Tx.Connection.CreateCommand())
            {
                command.Transaction = Tx;
                command.Parameters.AddWithValue("@schema", WNamedTableReference.SchemaNameToTuple(sourceTableNameRef.TableObjectName).Item1);
                command.Parameters.AddWithValue("@tableName", sourceTableNameRef.TableObjectName.Identifiers.Last().Value);
                command.Parameters.AddWithValue("@colName", edgeCol.MultiPartIdentifier.Identifiers.Last().Value);
                command.Parameters.AddWithValue("@role", WNodeTableColumnRole.Edge);
                command.CommandText = string.Format(@"
                    SELECT NodeColumn.HasReversedEdge
                    FROM [{0}] AS NodeColumn
                    WHERE NodeColumn.TableSchema = @schema and
                          NodeColumn.TableName = @tableName and
                          NodeColumn.ColumnName = @colName and
                          NodeColumn.ColumnRole = @role",
                    GraphViewConnection.MetadataTables[1]);
                using (var reader = command.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        hasReversedEdge = bool.Parse(reader[0].ToString());
                    }
                }
            }

            var reversedEdgeName = sourceTableNameRef.TableObjectName.Identifiers.Last().Value +
                                    "_" + edgeCol.MultiPartIdentifier.Identifiers.Last().Value + "Reversed";
            var reversedEdgeId = new WSelectScalarExpression
            {
                SelectExpr = new WColumnReferenceExpression
                {
                    MultiPartIdentifier = new WMultiPartIdentifier(
                        new Identifier[]
                        {
                            new Identifier {Value = edgeCol.Alias??string.Format("{0}_{1}_{2}",sourceTableName,edgeCol.MultiPartIdentifier.Identifiers.Last().Value,sinkTableName)},
                            new Identifier {Value = "Edgeid"}
                        })
                },
                ColumnName = "edgeid"
            };

            var elements = new List<WSelectElement>
            {
                sourceNodeId,
                sinkNodeId,
                edgeId
            };

            var reversedElements = new List<WSelectElement>
            {
                sourceNodeId,
                sinkNodeId,
                reversedEdgeId,
            };

            return new WMultiCommonTableExpression
            {
                WCommonTableExpressions = new List<WCommonTableExpression>()
                {
                    new WCommonTableExpression
                    {
                        ExpressionName = new Identifier
                        {
                            Value = hasReversedEdge && compare == 0 ? tempTableName + "_1" : tempTableName
                        },
                        QueryExpression = new WSelectQueryBlock
                        {
                            FromClause = node.FromClause,
                            WhereClause = new WWhereClause
                            {
                                SearchCondition = node.WhereClause.SearchCondition
                            },
                            HavingClause = node.HavingClause,
                            OrderByClause = node.OrderByClause,
                            TopRowFilter = node.TopRowFilter,
                            UniqueRowFilter = node.UniqueRowFilter,
                            SelectElements = elements,
                            MatchClause = node.MatchClause,
                        }
                    },
                    new WCommonTableExpression
                    {
                        ExpressionName = new Identifier
                        {
                            Value = hasReversedEdge && compare == 0 ? tempTableName + "_2" : tempTableName
                        },
                        QueryExpression = new WSelectQueryBlock
                        {
                            FromClause = node.FromClause,
                            WhereClause = hasReversedEdge ?
                                new WWhereClause { SearchCondition = ObjectExtensions.Copy(node.WhereClause.SearchCondition), }
                                : node.WhereClause,
                            HavingClause = node.HavingClause,
                            OrderByClause = node.OrderByClause,
                            TopRowFilter = node.TopRowFilter,
                            UniqueRowFilter = node.UniqueRowFilter,
                            SelectElements = hasReversedEdge ? reversedElements : elements,
                            MatchClause = hasReversedEdge? ConstructReversedMatchClause(node, context) : node.MatchClause,
                        }
                    },
                }
            };
        }
Example #12
0
        private static bool ParseMatchPathEdge(
            IList<TSqlParserToken> tokens,
            ref int nextToken,
            ref WEdgeColumnReferenceExpression result,
            ref int farestError)
        {
            var currentToken = nextToken;
            Identifier edgeIdentifier = null;
            if (!ParseQuotedIdentifier(tokens, ref currentToken, ref edgeIdentifier, ref farestError))
                return false;

            int line = tokens[currentToken].Line;
            nextToken = currentToken;
            string alias = null;
            int maxLen = 1;
            int minLen = 1;

            string errorKey = "";
            var edgeTokens = LexicalAnalyzer.Tokenize(edgeIdentifier.Value, ref errorKey);
            if (!string.IsNullOrEmpty(errorKey))
                throw new SyntaxErrorException(line, errorKey);
            int curEdgeToken = 0;
            int edgeFareastError = 0;
            string edgeName = null;
            string strValue = null;
            Dictionary<string, string> attributeValueDict = null;

            // Gets edge name
            if (!ReadToken(edgeTokens, AnnotationTokenType.NameToken, ref curEdgeToken, ref edgeName, ref edgeFareastError))
                throw new SyntaxErrorException(line, edgeTokens[edgeFareastError].value);
            edgeIdentifier.Value = edgeName;

            // Gets path info
            if (ReadToken(edgeTokens, "*", ref curEdgeToken, ref strValue, ref edgeFareastError))
            {
                string lengStr = "";

                // Gets path minimal length
                if (ReadToken(edgeTokens, AnnotationTokenType.Integer, ref curEdgeToken, ref lengStr,
                    ref edgeFareastError))
                {
                    if (!int.TryParse(lengStr, out minLen) || minLen<0)
                        throw new SyntaxErrorException(line, lengStr, "Min length should be an integer no less than zero");
                    for (int i = 0; i < 2; i++)
                    {
                        if (!ReadToken(edgeTokens, ".", ref curEdgeToken, ref strValue,
                            ref edgeFareastError))
                            throw new SyntaxErrorException(line, lengStr,
                                "Two dots should be followed by the minimal length integer");
                    }

                    // Gets path maximal length
                    if (!ReadToken(edgeTokens, AnnotationTokenType.Integer, ref curEdgeToken, ref lengStr,
                        ref edgeFareastError) || !int.TryParse(lengStr, out maxLen) || maxLen < minLen)
                        throw new SyntaxErrorException(line, lengStr,
                            "Max length should be an integer no less than the min length");
                }
                else
                {
                    minLen = 0;
                    maxLen = -1;
                }
                // Gets edge alias
                if (ReadToken(edgeTokens, "as", ref curEdgeToken, ref strValue, ref edgeFareastError))
                {
                    if (!ReadToken(edgeTokens, AnnotationTokenType.NameToken, ref curEdgeToken, ref alias, ref edgeFareastError))
                        throw new SyntaxErrorException(line, edgeTokens[edgeFareastError].value);
                }

                // Gets predicates on attributes
                NestedObject jsonNestedObject = null;
                int braceToken = curEdgeToken;
                if (ReadToken(edgeTokens, AnnotationTokenType.LeftBrace, ref curEdgeToken, ref strValue,
                    ref edgeFareastError))
                {
                    if (!ParseNestedObject(edgeTokens, ref braceToken, ref jsonNestedObject, ref edgeFareastError, true))
                        throw new SyntaxErrorException(line, "{", "Invalid json string");
                    else
                        attributeValueDict =
                            (jsonNestedObject as CollectionObject).Collection.ToDictionary(e => e.Key.ToLower(),
                                e =>
                                    (e.Value is StringObject)
                                        ? "'" + ((StringObject) e.Value).Value + "'"
                                        : (e.Value as NormalObject).Value);
                }
            }

            // Gets edge alias
            if (ReadToken(edgeTokens, "as", ref curEdgeToken, ref strValue, ref edgeFareastError))
            {
                if (!ReadToken(edgeTokens, AnnotationTokenType.NameToken, ref curEdgeToken, ref alias, ref edgeFareastError))
                    throw new SyntaxErrorException(line, edgeTokens[edgeFareastError].value);
            }

            result = new WEdgeColumnReferenceExpression
            {
                ColumnType = ColumnType.Regular,
                Alias = alias,
                LastTokenIndex = currentToken - 1,
                FirstTokenIndex = currentToken - 1,
                MaxLength = maxLen,
                MinLength = minLen,
                MultiPartIdentifier = new WMultiPartIdentifier(edgeIdentifier),
                AttributeValueDict = attributeValueDict
            };
            return true;
        }
        private WCommonTableExpression ConstructDeleteEdgeSelect(WSelectQueryBlock node, WEdgeColumnReferenceExpression edgeCol, string tempTableName
            ,out WTableReference sinkTable, out WTableReference sourceTable)
        {
            sourceTable = null;
            sinkTable = null;
            string sourceTableName = null;
            string sinkTableName = null;
            var sourceTableScalar = node.SelectElements[0] as WSelectScalarExpression;
            if (sourceTableScalar == null)
                return null;
            var sourceTableColumn = sourceTableScalar.SelectExpr as WColumnReferenceExpression;
            if (sourceTableColumn == null)
                return null;
            sourceTableName = sourceTableColumn.MultiPartIdentifier.Identifiers.Last().Value;

            var sourceNodeIdExpr = new WColumnReferenceExpression();
            foreach (var identifier in sourceTableColumn.MultiPartIdentifier.Identifiers)
                sourceNodeIdExpr.Add(identifier);
            sourceNodeIdExpr.AddIdentifier("GlobalNodeId");

            var collectVarVisitor = new CollectVariableVisitor();
            var context = collectVarVisitor.Invoke(node);
            if (!context.NodeTableDictionary.Any())
            {
                throw new GraphViewException("Missing From Clause in Delete Edge statement");
            }
            WColumnReferenceExpression sinkNodeIdExpr = null;
            sourceTable = context[sourceTableName];

            var groupByParams = new List<WScalarExpression>();
            for (var index = 1; index < node.SelectElements.Count; ++index)
            {
                var element = node.SelectElements[index] as WSelectScalarExpression;
                if (element == null)
                    return null;
                //sink table
                if (index == 1)
                {
                    var sinkTableColumn = element.SelectExpr as WColumnReferenceExpression;
                    if (sinkTableColumn == null)
                        return null;

                    sinkTableName = sinkTableColumn.MultiPartIdentifier.Identifiers.Last().Value;
                    sinkTable = context[sinkTableName];

                    sinkNodeIdExpr = new WColumnReferenceExpression();
                    foreach (var identifier in sinkTableColumn.MultiPartIdentifier.Identifiers)
                        sinkNodeIdExpr.Add(identifier);
                    sinkNodeIdExpr.AddIdentifier("GlobalNodeId");
                }
            }

            var sourceNodeId = new WSelectScalarExpression
            {
                SelectExpr = sourceNodeIdExpr,
                ColumnName = "src",
            };
            var sinkNodeId = new WSelectScalarExpression
            {
                SelectExpr = sinkNodeIdExpr,
                ColumnName = "sink"
            };
            var edgeId = new WSelectScalarExpression
            {
                SelectExpr = new WColumnReferenceExpression
                {
                    MultiPartIdentifier = new WMultiPartIdentifier(
                        new Identifier[]
                        {
                            new Identifier {Value = edgeCol.Alias??string.Format("{0}_{1}_{2}",sourceTableName,edgeCol.MultiPartIdentifier.Identifiers.Last().Value,sinkTableName)},
                            new Identifier {Value = "Edgeid"}
                        }
                        )
                },
                ColumnName = "edgeid"
            };

            var elements = new List<WSelectElement>
            {
                sourceNodeId,
                sinkNodeId,
                edgeId
            };

            return new WCommonTableExpression
            {
                ExpressionName = new Identifier { Value = tempTableName },
                QueryExpression = new WSelectQueryBlock
                {
                    FromClause = node.FromClause,
                    WhereClause = new WWhereClause
                    {
                        SearchCondition = node.WhereClause.SearchCondition
                    },
                    HavingClause = node.HavingClause,
                    OrderByClause = node.OrderByClause,
                    TopRowFilter = node.TopRowFilter,
                    UniqueRowFilter = node.UniqueRowFilter,
                    SelectElements = elements,
                    MatchClause = node.MatchClause,
                }

            };
        }
Example #14
0
 public void AddEdgeReference(string name, WSchemaObjectName sourceNodeName, WEdgeColumnReferenceExpression edgeReference)
 {
     if (_nodeTableDictionary.ContainsKey(name) || _edgeDictionary.ContainsKey(name))
         throw new GraphViewException("Duplicate Alias");
     _edgeDictionary.Add(name,
         new Tuple<WSchemaObjectName, WEdgeColumnReferenceExpression>(sourceNodeName, edgeReference));
 }