Skip to content

Question about self join #2447

@StarGazerM

Description

@StarGazerM

In the compiled RAM of query contains self join for example:

path(from, to) :- edge(from, to).
path(from, to) :- path(from, mid), path(mid, to).

Recursive rule will be compiled into:

LOOP
   DEBUG "path(from,to) :- \n   path(from,mid),\n   path(mid,to).\nin file tc.dl [10:1-10:50]"
    QUERY
     IF ((NOT ISEMPTY(@delta_path)) AND (NOT ISEMPTY(path)))
      FOR t0 IN @delta_path
       FOR t1 IN path ON INDEX t1.0 = t0.1
        IF ((NOT (t0.0,t1.1) IN path) AND (NOT (t0.1,t1.1) IN @delta_path))
         INSERT (t0.0, t1.1) INTO @new_path
    END QUERY
   END DEBUG
   DEBUG "path(from,to) :- \n   path(from,mid),\n   path(mid,to).\nin file tc.dl [10:1-10:50]"
    QUERY
     IF ((NOT ISEMPTY(path)) AND (NOT ISEMPTY(@delta_path)))
      FOR t0 IN path
       FOR t1 IN @delta_path ON INDEX t1.0 = t0.1
        IF (NOT (t0.0,t1.1) IN path)
         INSERT (t0.0, t1.1) INTO @new_path
    END QUERY
   END DEBUG

The first RAM query is joining delta version of path with full version path and the second is reverse.
I have 2 question:

  1. why there is a (NOT (t0.1,t1.1) IN @delta_path)) in first query
  2. why the self join is not simple as join delta with delta and then delta with full? this should also contains all result, iterate over full seems unnecessary?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions