func buildIteratorTree(tree *peg.ExpressionTree, ts graph.TripleStore) graph.Iterator { switch tree.Name { case "Start": return buildIteratorTree(tree.Children[0], ts) case "NodeIdentifier": var out graph.Iterator nodeID := getIdentString(tree) if tree.Children[0].Name == "Variable" { allIt := ts.GetNodesAllIterator() allIt.AddTag(nodeID) out = allIt } else { n := nodeID if tree.Children[0].Children[0].Name == "ColonIdentifier" { n = nodeID[1:] } fixed := ts.MakeFixed() fixed.AddValue(ts.GetIdFor(n)) out = fixed } return out case "PredIdentifier": i := 0 if tree.Children[0].Name == "Reverse" { //Taken care of below i++ } it := buildIteratorTree(tree.Children[i], ts) lto := graph.NewLinksToIterator(ts, it, "p") return lto case "RootConstraint": constraintCount := 0 and := graph.NewAndIterator() for _, c := range tree.Children { switch c.Name { case "NodeIdentifier": fallthrough case "Constraint": it := buildIteratorTree(c, ts) and.AddSubIterator(it) constraintCount++ continue default: continue } } return and case "Constraint": var hasa *graph.HasaIterator topLevelDir := "s" subItDir := "o" subAnd := graph.NewAndIterator() isOptional := false for _, c := range tree.Children { switch c.Name { case "PredIdentifier": if c.Children[0].Name == "Reverse" { topLevelDir = "o" subItDir = "s" } it := buildIteratorTree(c, ts) subAnd.AddSubIterator(it) continue case "PredicateKeyword": switch c.Children[0].Name { case "OptionalKeyword": isOptional = true } case "NodeIdentifier": fallthrough case "RootConstraint": it := buildIteratorTree(c, ts) l := graph.NewLinksToIterator(ts, it, subItDir) subAnd.AddSubIterator(l) continue default: continue } } hasa = graph.NewHasaIterator(ts, subAnd, topLevelDir) if isOptional { optional := graph.NewOptionalIterator(hasa) return optional } return hasa default: return &graph.NullIterator{} } panic("Not reached") }
func (m *MqlQuery) buildResultIterator(path MqlPath) graph.Iterator { all := m.ses.ts.GetNodesAllIterator() all.AddTag(string(path)) return graph.NewOptionalIterator(all) }