A multiset is an unordered container, and there is no ordinal position to reference individual elements of a multiset. Furthermore, it is also possible to declare a nested multiset i.e. a container with an unordered collection of multisets.
CREATE OR REPLACE PROCEDURE "MY_GRAPH_PROC"(
IN i_startNode NVARCHAR(100), -- the ID of the start node
IN i_endNode NVARCHAR(100), -- the ID of the end node
IN i_k INT, -- the ID of the end node
IN direction NVARCHAR(10) DEFAULT 'ANY',
OUT o_nodes "TT_NODES",
OUT o_edges "TT_EDGES",
OUT edge_attr NVARCHAR(5000),
OUT o_paths "PATHS"
)
LANGUAGE GRAPH READS SQL DATA AS
BEGIN
GRAPH g = Graph("SCHEMA", "GRAPH");
VERTEX v_s = Vertex(:g, :i_startNode);
VERTEX v_t = Vertex(:g, :i_endNode);
-------------------
-- Shortest Path --
-------------------
WeightedPath<BIGINT> p = Shortest_Path(:g, :v_s, :v_t, :direction);
SEQUENCE<VERTEX> sv = VERTICES(:p);
SEQUENCE<EDGE> se = EDGES(:p);
o_nodes = SELECT :v."ID", :v."NAME" FOREACH v IN Vertices(:p);
FOREACH ed in EDGES(:p) WITH ORDINALITY AS edge_order {
o_edges."EDGE_ORDER"[:edge_order] = :edge_order;
o_edges."EDGE_KEY"[:edge_order] = :ed."ID";
o_edges."SOURCE"[:edge_order] = :ed.NODE_SRC_ID;
o_edges."RELATION"[:edge_order] = :ed.TYPE_ID;
o_edges."TARGET"[:edge_order] = :ed.NODE_TGT_ID;
}
-- running top k shortest paths
SEQUENCE<WeightedPath<BIGINT>> s_paths = K_Shortest_Paths(
:g, :v_s, :v_t, :i_k);
BIGINT number_of_paths = 0L;
-- project result paths into a table
BIGINT currentResultRow = 1L;
FOREACH result_path IN (:s_paths) WITH ORDINALITY AS path_id {
MULTISET<NVARCHAR> nodes_in_path;
BOOLEAN cycle_in_path = FALSE;
-- Check if there is a cycle in the path
FOREACH p_edge in EDGES(:result_path) {
if(IS_EMPTY(:nodes_in_path)) {
-- Will enter only in the first iteration
nodes_in_path = {:p_edge.NODE_SRC_ID, :p_edge.NODE_TGT_ID};
} else {
if (:p_edge.NODE_SRC_ID in :nodes_in_path and :p_edge.NODE_TGT_ID in :nodes_in_path){
-- Both vertices are already in the multiset
cycle_in_path = TRUE;
}
else {
-- Only add the target vertex
nodes_in_path = :nodes_in_path UNION ALL {:p_edge.NODE_TGT_ID};
}
}
}
-- Add path to result set if there is no cycle
if (:cycle_in_path == FALSE){
number_of_paths = :number_of_paths + 1L;
FOREACH path_edge in EDGES(:result_path) WITH ORDINALITY AS edge_order {
o_paths."PATH_ID"[:currentResultRow] = INTEGER(:path_id);
o_paths."PATH_LENGTH"[:currentResultRow] = Length(:result_path);
o_paths."PATH_WEIGHT"[:currentResultRow] = Weight(:result_path);
o_paths."EDGE_ID"[:currentResultRow] = :path_edge."ID";
o_paths."EDGE_ORDER"[:currentResultRow] = INTEGER(:edge_order);
edge_attr = :edge_attr || :path_edge.NODE_SRC_ID || '-' || :path_edge."TYPE_ID" || '-' || :path_edge.NODE_TGT_ID || '. ';
currentResultRow = :currentResultRow + 1L;
}
}
}
END;
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
37 | |
25 | |
17 | |
13 | |
7 | |
7 | |
7 | |
6 | |
6 | |
6 |