func (qs *queryShape) MakeNode(it graph.Iterator) *Node { n := Node{Id: qs.nodeId} for _, tag := range it.Tags() { n.Tags = append(n.Tags, tag) } for k, _ := range it.FixedTags() { n.Tags = append(n.Tags, k) } switch it.Type() { case "and": for _, sub := range it.GetSubIterators() { qs.nodeId++ newNode := qs.MakeNode(sub) if sub.Type() != "or" { qs.StealNode(&n, newNode) } else { qs.AddNode(newNode) qs.AddLink(&Link{n.Id, newNode.Id, 0, 0}) } } case "fixed": n.IsFixed = true for { val, more := it.Next() if !more { break } n.Values = append(n.Values, qs.ts.GetNameFor(val)) } case "hasa": hasa := it.(*HasA) qs.PushHasa(n.Id, hasa.dir) qs.nodeId++ newNode := qs.MakeNode(hasa.primaryIt) qs.AddNode(newNode) qs.RemoveHasa() case "or": for _, sub := range it.GetSubIterators() { qs.nodeId++ newNode := qs.MakeNode(sub) if sub.Type() == "or" { qs.StealNode(&n, newNode) } else { qs.AddNode(newNode) qs.AddLink(&Link{n.Id, newNode.Id, 0, 0}) } } case "linksto": n.IsLinkNode = true lto := it.(*LinksTo) qs.nodeId++ newNode := qs.MakeNode(lto.primaryIt) hasaID, hasaDir := qs.LastHasa() if (hasaDir == graph.Subject && lto.dir == graph.Object) || (hasaDir == graph.Object && lto.dir == graph.Subject) { qs.AddNode(newNode) if hasaDir == graph.Subject { qs.AddLink(&Link{hasaID, newNode.Id, 0, n.Id}) } else { qs.AddLink(&Link{newNode.Id, hasaID, 0, n.Id}) } } else if lto.primaryIt.Type() == "fixed" { qs.StealNode(&n, newNode) } else { qs.AddNode(newNode) } case "optional": // Unsupported, for the moment fallthrough case "all": } return &n }