132 lines
4.9 KiB
Plaintext
Raw Normal View History

digraph QueryOpsHandPlan {
fontname = "Helvetica,Arial,sans-serif"
layout = dot
rankdir = LR
ranksep = 0.9;
nodesep = 0.7;
splines = true;
compound = true;
bgcolor = "white"
node [
fontname = "Helvetica,Arial,sans-serif",
shape = box,
style = "filled,rounded",
color = "#555555",
fillcolor = "white",
penwidth = 1.5
]
edge [
fontname = "Helvetica,Arial,sans-serif",
color = "#333333",
fontsize = 9,
fontcolor = "#555555",
labeldistance = 2.0,
penwidth = 1.2
]
subgraph cluster_inputs {
label = "Inputs (positional tables)"
style = "dashed"
color = "#888888"
fontcolor = "#555555"
margin = 18
edge_table [label = <<table border="0" cellborder="0" cellspacing="0" cellpadding="4">
<tr><td align="center"><b>Table: edge</b></td></tr>
<tr><td align="left" balign="left">• arity 2</td></tr>
<tr><td align="left" balign="left">• rows: (src, dst)</td></tr>
</table>>, fillcolor = "#E8F4FD", color = "#2196F3"]
labeled_table [label = <<table border="0" cellborder="0" cellspacing="0" cellpadding="4">
<tr><td align="center"><b>Table: labeled</b></td></tr>
<tr><td align="left" balign="left">• arity 1</td></tr>
<tr><td align="left" balign="left">• rows: (node)</td></tr>
</table>>, fillcolor = "#E8F4FD", color = "#2196F3"]
}
subgraph cluster_atoms {
label = "Atom Scans (scan_atom: Table × AtomPattern → Relation)"
style = "dashed"
color = "#9C27B0"
fontcolor = "#7B1FA2"
margin = 14
self_loops [label = <<table border="0" cellborder="0" cellspacing="0" cellpadding="4">
<tr><td align="center"><b>self_loops</b></td></tr>
<tr><td align="left" balign="left">pattern: [Var X, Var X]</td></tr>
<tr><td align="left" balign="left">filter: row[0] == row[1]</td></tr>
<tr><td align="left" balign="left">cols: [X]</td></tr>
</table>>, fillcolor = "#F3E5F5", color = "#9C27B0"]
edge_xy [label = <<table border="0" cellborder="0" cellspacing="0" cellpadding="4">
<tr><td align="center"><b>edge_xy</b></td></tr>
<tr><td align="left" balign="left">pattern: [Var X, Var Y]</td></tr>
<tr><td align="left" balign="left">filter: none</td></tr>
<tr><td align="left" balign="left">cols: [X, Y]</td></tr>
</table>>, fillcolor = "#F3E5F5", color = "#9C27B0"]
labeled_x [label = <<table border="0" cellborder="0" cellspacing="0" cellpadding="4">
<tr><td align="center"><b>labeled_x</b></td></tr>
<tr><td align="left" balign="left">pattern: [Var X]</td></tr>
<tr><td align="left" balign="left">cols: [X]</td></tr>
</table>>, fillcolor = "#F3E5F5", color = "#9C27B0"]
labeled_y [label = <<table border="0" cellborder="0" cellspacing="0" cellpadding="4">
<tr><td align="center"><b>labeled_y</b></td></tr>
<tr><td align="left" balign="left">pattern: [Var Y]</td></tr>
<tr><td align="left" balign="left">cols: [Y]</td></tr>
</table>>, fillcolor = "#F3E5F5", color = "#9C27B0"]
}
subgraph cluster_joins {
label = "Joins (shared cols = matching column names)"
style = "dashed"
color = "#4CAF50"
fontcolor = "#388E3C"
margin = 14
q1 [label = <<table border="0" cellborder="0" cellspacing="0" cellpadding="4">
<tr><td align="center"><b>Q1: semijoin</b></td></tr>
<tr><td align="left" balign="left">edge(X, X), labeled(X)</td></tr>
<tr><td align="left" balign="left">keep left rows whose [X] is in right</td></tr>
<tr><td align="left" balign="left">cols: [X]</td></tr>
</table>>, fillcolor = "#E8F5E9", color = "#4CAF50"]
q2 [label = <<table border="0" cellborder="0" cellspacing="0" cellpadding="4">
<tr><td align="center"><b>Q2: natural_join</b></td></tr>
<tr><td align="left" balign="left">edge(X, Y), labeled(Y)</td></tr>
<tr><td align="left" balign="left">emit left ++ (right \ shared) per match</td></tr>
<tr><td align="left" balign="left">cols: [X, Y]</td></tr>
</table>>, fillcolor = "#E8F5E9", color = "#4CAF50"]
}
subgraph cluster_outputs {
label = "Outputs (binding relations)"
style = "dashed"
color = "#888888"
fontcolor = "#555555"
margin = 18
q1_out [label = <<table border="0" cellborder="0" cellspacing="0" cellpadding="4">
<tr><td align="center"><b>Q1 result</b></td></tr>
<tr><td align="left" balign="left">labeled self-loops</td></tr>
<tr><td align="left" balign="left">cols: [X]</td></tr>
</table>>, fillcolor = "#ECEFF1", color = "#607D8B"]
q2_out [label = <<table border="0" cellborder="0" cellspacing="0" cellpadding="4">
<tr><td align="center"><b>Q2 result</b></td></tr>
<tr><td align="left" balign="left">edges into labeled nodes</td></tr>
<tr><td align="left" balign="left">cols: [X, Y]</td></tr>
</table>>, fillcolor = "#ECEFF1", color = "#607D8B"]
}
// Atom scans consume tables
edge_table -> self_loops [color = "#2196F3"]
edge_table -> edge_xy [color = "#2196F3"]
labeled_table -> labeled_x [color = "#2196F3"]
labeled_table -> labeled_y [color = "#2196F3"]
// Q1: edge(X, X), labeled(X) -> semijoin
self_loops -> q1 [label = "left", color = "#9C27B0"]
labeled_x -> q1 [label = "right", color = "#9C27B0"]
// Q2: edge(X, Y), labeled(Y) -> natural_join
edge_xy -> q2 [label = "left", color = "#9C27B0"]
labeled_y -> q2 [label = "right", color = "#9C27B0"]
// Final outputs
q1 -> q1_out [color = "#4CAF50"]
q2 -> q2_out [color = "#4CAF50"]
}