132 lines
4.9 KiB
Plaintext
132 lines
4.9 KiB
Plaintext
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"]
|
||
}
|