private void CheckValidity(WSelectQueryBlock node)
{
if (node.MatchClause == null)
return;
// Checks validity of the source node/node view
if (node.MatchClause.Paths.All(
path => path.PathEdgeList.All(
part => _context.CheckTable(part.Item1.BaseIdentifier.Value) &&
IsNodeTable(_context[part.Item1.BaseIdentifier.Value])
)
))
{
foreach (var path in node.MatchClause.Paths)
{
var index = 0;
for (var count = path.PathEdgeList.Count; index < count; ++index)
{
var pathNode = path.PathEdgeList[index];
var table = _context[pathNode.Item1.BaseIdentifier.Value] as WNamedTableReference;
var edgeCol = pathNode.Item2;
var edge =
edgeCol.MultiPartIdentifier.Identifiers.Last().Value.ToLower();
var nodeTableTuple = WNamedTableReference.SchemaNameToTuple(table.TableObjectName);
var schema = nodeTableTuple.Item1;
// Binds edge/edge view to node/node view and check validity
string bindNode = _context.BindEdgeToNode(schema, edge, nodeTableTuple.Item2, _graphMetaData);
if (string.IsNullOrEmpty(bindNode))
throw new GraphViewException(string.Format("Edge/EdgeView {0} cannot be bind to {1}.{2}",
edge,
nodeTableTuple.Item1, nodeTableTuple.Item2));
// Check edge length
if (edgeCol.MinLength<0)
throw new GraphViewException(
string.Format(
"The minimal length of the path {0} should be non-negative integer",
edge));
if (edgeCol.MaxLength!=-1 && edgeCol.MinLength > edgeCol.MaxLength)
throw new GraphViewException(
string.Format(
"The minimal length of the path {0} should not be larger than the maximal length",
edge));
// Checks whether the sink of the edge/edge view exist
HashSet<string> edgeSinkNodes =
_graphMetaData.ColumnsOfNodeTables[new Tuple<string, string>(schema, bindNode)][edge].EdgeInfo
.SinkNodes;
HashSet<string> sinkNodes;
if (
!edgeSinkNodes.All(
e =>
_graphMetaData.ColumnsOfNodeTables.ContainsKey(new Tuple<string, string>(
schema.ToLower(), e))))
throw new GraphViewException(String.Format(CultureInfo.CurrentCulture,
"Node Table Referenced by the Edge {0} not exists", edge));
// Checks validity of sink node(s)
var nextNode = index != count - 1
? path.PathEdgeList[index + 1].Item1
: path.Tail;
var getNextTable = _context[nextNode.BaseIdentifier.Value];
if (!IsNodeTable(getNextTable))
throw new GraphViewException("Node table expected in MATCH clause");
// Checks whether the intersection of the edge sink and sink node(s) is empty
var nextTable = getNextTable as WNamedTableReference;
if (nextTable == null ||
!_graphMetaData.NodeViewMapping.TryGetValue(
WNamedTableReference.SchemaNameToTuple(nextTable.TableObjectName), out sinkNodes))
sinkNodes = new HashSet<string> {nextTable.TableObjectName.BaseIdentifier.Value};
if (sinkNodes.All(e => !edgeSinkNodes.Contains(e)))
{
throw new GraphViewException(String.Format(CultureInfo.CurrentCulture,
"Wrong Reference Table {0}", nextTable.TableObjectName.BaseIdentifier.Value));
}
}
}
}
else
{
throw new GraphViewException("Node table/view expected in MATCH clause");
}
}