/// <summary> /// Constructs parameters for the edge table-valued function when translation the MATCH clause /// </summary> /// <param name="nodeAlias">Source node alias</param> /// <param name="nodeTableNameSet">Node table names mapping to the source node of the edge. /// If null, the source node is mapped to a physical table in the syntax tree. Otherewise, /// the source node is mapped to a node view</param> /// <param name="edgeNameTuples">A tuple (Node table name, Edge column name) mapping to the edge. /// If null, the edge is mapped to an edge column in a physical node table. Ohterwise, /// the edge is mapped to an edge view</param> /// <returns>Parameters in the table-valued function</returns> protected List <WScalarExpression> ConstructEdgeTvfParameters(string nodeAlias, HashSet <string> nodeTableNameSet = null, List <Tuple <string, string> > edgeNameTuples = null) { var edgeIdentifiers = EdgeColumn.MultiPartIdentifier.Identifiers; var edgeColIdentifier = edgeIdentifiers.Last(); Identifier srcNodeIdentifier = new Identifier { Value = nodeAlias }; List <WScalarExpression> parameters = new List <WScalarExpression>(); // The source is a physical node if (nodeTableNameSet == null) { // The edge is a physical edge if (edgeNameTuples == null) { parameters.Add(new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(srcNodeIdentifier, edgeColIdentifier) }); parameters.Add(new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(srcNodeIdentifier, new Identifier { Value = edgeColIdentifier.Value + "DeleteCol" }) }); } // The edge is an edge view else { foreach (var column in edgeNameTuples) { Identifier includedEdgeColumnIdentifier = new Identifier { Value = column.Item2 }; parameters.Add(new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(srcNodeIdentifier, includedEdgeColumnIdentifier) }); parameters.Add(new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(srcNodeIdentifier, new Identifier { Value = includedEdgeColumnIdentifier.Value + "DeleteCol" }) }); } } } // The source is a node view else { // The edge is a physical edge if (edgeNameTuples == null) { string srcTableName = BindNodeTableObjName.BaseIdentifier.Value; Identifier nodeViewEdgeColIdentifier = new Identifier { Value = srcTableName + "_" + edgeColIdentifier.Value }; parameters.Add(new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(srcNodeIdentifier, nodeViewEdgeColIdentifier) }); parameters.Add(new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(srcNodeIdentifier, new Identifier { Value = nodeViewEdgeColIdentifier.Value + "DeleteCol" }) }); } // The edge is an edge view else { foreach (var column in edgeNameTuples) { if (nodeTableNameSet.Contains(column.Item1)) { Identifier includedEdgeColumnIdentifier = new Identifier { Value = column.Item1 + "_" + column.Item2 }; parameters.Add(new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(srcNodeIdentifier, includedEdgeColumnIdentifier) }); parameters.Add(new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(srcNodeIdentifier, new Identifier { Value = includedEdgeColumnIdentifier.Value + "DeleteCol" }) }); } else { parameters.Add(new WValueExpression { Value = "null" }); parameters.Add(new WValueExpression { Value = "null" }); } } } } return(parameters); }
/// <summary> /// Converts the edge to the table-valued function /// </summary> /// <param name="nodeAlias">Source node alias</param> /// <param name="metaData">Meta data</param> /// <returns>A syntax tree node representing the table-valued function</returns> public override WSchemaObjectFunctionTableReference ToSchemaObjectFunction(string nodeAlias, GraphMetaData metaData) { var edgeIdentifiers = EdgeColumn.MultiPartIdentifier.Identifiers; var edgeColIdentifier = edgeIdentifiers.Last(); HashSet <string> nodeSet; if (!metaData.NodeViewMapping.TryGetValue( WNamedTableReference.SchemaNameToTuple(SourceNode.NodeTableObjectName), out nodeSet)) { nodeSet = null; } var sourceNodeColumns = metaData.ColumnsOfNodeTables[WNamedTableReference.SchemaNameToTuple(BindNodeTableObjName)]; var edgeInfo = sourceNodeColumns[edgeColIdentifier.Value].EdgeInfo; List <Tuple <string, string> > edgeTuples = edgeInfo.EdgeColumns; var parameters = ConstructEdgeTvfParameters(nodeAlias, nodeSet, edgeTuples); Identifier decoderFunction; if (ReferencePathInfo) { decoderFunction = new Identifier { Value = BindNodeTableObjName.SchemaIdentifier.Value + '_' + BindNodeTableObjName.BaseIdentifier.Value + '_' + EdgeColumn.MultiPartIdentifier.Identifiers.Last().Value + '_' + "bfsPathWithMessage" }; // Node view if (nodeSet != null) { parameters.Insert(0, new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(new Identifier() { Value = SourceNode.RefAlias }, new Identifier() { Value = "_NodeId" }) }); parameters.Insert(0, new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(new Identifier() { Value = SourceNode.RefAlias }, new Identifier() { Value = "_NodeType" }) }); } else { string nodeIdName = sourceNodeColumns.FirstOrDefault(e => e.Value.Role == WNodeTableColumnRole.NodeId).Key; if (string.IsNullOrEmpty(nodeIdName)) { parameters.Insert(0, new WValueExpression { Value = "null" }); } else { parameters.Insert(0, new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(new Identifier() { Value = SourceNode.RefAlias }, new Identifier() { Value = nodeIdName }) }); } parameters.Insert(0, new WValueExpression { Value = BindNodeTableObjName.BaseIdentifier.Value, SingleQuoted = true }); } } else { decoderFunction = new Identifier { Value = BindNodeTableObjName.SchemaIdentifier.Value + '_' + BindNodeTableObjName.BaseIdentifier.Value + '_' + EdgeColumn.MultiPartIdentifier.Identifiers.Last().Value + '_' + "bfsPath" }; } parameters.Insert(0, new WValueExpression { Value = MaxLength.ToString() }); parameters.Insert(0, new WValueExpression { Value = MinLength.ToString() }); parameters.Insert(0, new WColumnReferenceExpression { MultiPartIdentifier = new WMultiPartIdentifier(new[] { new Identifier { Value = nodeAlias }, new Identifier { Value = "GlobalNodeId" }, }) }); var attributes = edgeInfo.ColumnAttributes; if (AttributeValueDict == null) { WValueExpression nullExpression = new WValueExpression { Value = "null" }; for (int i = 0; i < attributes.Count; i++) { parameters.Add(nullExpression); } } else { foreach (var attribute in attributes) { string value; var valueExpression = new WValueExpression { Value = AttributeValueDict.TryGetValue(attribute, out value) ? value : "null" }; parameters.Add(valueExpression); } } return(new WSchemaObjectFunctionTableReference { SchemaObject = new WSchemaObjectName( new Identifier { Value = "dbo" }, decoderFunction), Parameters = parameters, Alias = new Identifier { Value = EdgeAlias, } }); }