Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IKKBZ Join ordering #1330

Open
wants to merge 51 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
a7e0bcc
JoinTree Imp.
Goblin80 Apr 21, 2024
a0784c3
IKKBZ Imp.
Goblin80 Apr 21, 2024
c07eb3f
IKKBZ sanity tests
Goblin80 Apr 21, 2024
a598baa
.clang-format
Goblin80 Apr 21, 2024
75d2194
split this up to a .h and .cpp
Goblin80 Apr 27, 2024
88eed17
std::span
Goblin80 Apr 27, 2024
407ee68
allow discard add_relation
Goblin80 Apr 27, 2024
9cc7139
.clang-format
Goblin80 Apr 27, 2024
963ed97
move out rank and test it separately
Goblin80 Apr 30, 2024
fd8fecd
make linker happy
Goblin80 Apr 30, 2024
29ae853
[skip ci] rank table with CostASI
Goblin80 Apr 30, 2024
653cc84
cleanup costfn
Goblin80 Apr 30, 2024
06e873e
link util
Goblin80 May 1, 2024
785361a
link engine
Goblin80 May 1, 2024
4319d58
[skip ci] argmin of all relations
Goblin80 May 1, 2024
2c34528
[skip ci] ASI comments
Goblin80 May 1, 2024
c17a3d5
[skip ci] IKKBZ par_unseq
Goblin80 May 1, 2024
a2ffca2
[skip ci] sprinkle const
Goblin80 May 1, 2024
788b7cf
[skip ci] iter relay
Goblin80 May 2, 2024
03055de
[skip ci] partial_sort
Goblin80 May 2, 2024
2d5354b
C span seq
Goblin80 May 3, 2024
0c353dd
.clang-format
Goblin80 May 3, 2024
94b8fa7
gcc11 compatible
Goblin80 May 3, 2024
c1861e1
linker stuff
Goblin80 May 4, 2024
a49414b
rm CostASITest.cpp
Goblin80 May 4, 2024
c837874
include .cpp
Goblin80 May 4, 2024
ba9498e
mac being annoying per uge
Goblin80 May 4, 2024
41b07c0
Merge branch 'ad-freiburg:master' into joinorder-ikkbz
Goblin80 May 5, 2024
3158e74
decouple cost fn and memorize rank
Goblin80 May 5, 2024
6f4ff38
ty abseil
Goblin80 May 6, 2024
1f5eabf
unpack paired rxs
Goblin80 May 7, 2024
b467956
inv default undirected
Goblin80 May 9, 2024
91ffc4a
init JoinTree
Goblin80 Oct 27, 2024
e9b0881
auto?
Goblin80 Oct 27, 2024
803fda7
JoinNode, JoinTree
Goblin80 Oct 27, 2024
ebc77b4
Cout
Goblin80 Oct 27, 2024
1e512e5
fixup! auto?
Goblin80 Oct 27, 2024
3316dca
init LinearizedDP
Goblin80 Oct 27, 2024
4eeb722
headers
Goblin80 Oct 27, 2024
9917300
TreeCostTest
Goblin80 Oct 27, 2024
40af54d
Merge branch 'ad-freiburg:master' into joinorder-ikkbz
Goblin80 Oct 27, 2024
9117b88
fmt
Goblin80 Oct 27, 2024
5f1492f
fixup! fmt
Goblin80 Oct 27, 2024
c89a33a
fix expanded macro
Goblin80 Oct 27, 2024
4c8ec01
codecov
Goblin80 Oct 27, 2024
25145da
unused
Goblin80 Oct 27, 2024
ff97031
empty JoinNode
Goblin80 Oct 27, 2024
1b69d07
fixup! empty JoinNode
Goblin80 Oct 27, 2024
c3040d5
fixup! unused
Goblin80 Oct 27, 2024
1f0f366
fixup! codecov
Goblin80 Oct 28, 2024
27f3269
codeconv stuck
Goblin80 Oct 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions src/engine/IKKBZ.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// Copyright 2024, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author:
// Mahmoud Khalaf (2024-, khalaf@cs.uni-freiburg.de)

#pragma once
#include <iostream>

#include "JoinTree.hpp"

namespace JoinOrdering {

void _toPrecedenceGraph(JoinTree& g, const Relation& n) { // NOLINT
for (auto& [x, e] : g.r[n]) {
if (g.r[n][x].direction != Direction::UNDIRECTED) continue;
g.rm_rjoin(n, x);
g.add_rjoin(n, x, g.selectivity[x], Direction::PARENT);
_toPrecedenceGraph(g, x);
}
}

/**
* The precedence graph describes the (partial) ordering of joins
* implied by the query graph.
*
* z.B:
*

R1 -+ +- R5
| |

R3 --- R4

| |
R2 -+ +- R6

query graph



R1

|
|
v

R3 --> R2

|
|
v

R4 --> R6

|
|
v

R5


precedence graph rooted in R1

*
* 106/637
*
* @param g query graph
* @param root starting relation
* @return directed query graph
*/
[[nodiscard("use mutated graph")]] auto toPrecedenceGraph(JoinTree& g,
const Relation& root)
-> JoinTree {
g.root = root;
_toPrecedenceGraph(g, root);
// TODO: std::move?
return g; // graph copy
}

/**
* continued process of building compound relations until
* no contradictory sequences exist.
*
* merges relations that would have been reorder if only considering the rank
* guarantees that rank is ascending in each subchain
*
*
* ref: 119,122/637
* @param g
* @param subtree_root
* @return
* @see JoinOrdering::combine
*/
// FIXME: unbelievably stupid
[[nodiscard("check pre-merge")]] bool IKKBZ_Normalized(
JoinTree& g, const Relation& subtree_root) {
for (auto const& d : g.get_descendents(subtree_root)) {
auto pv = g.get_parent(d);
if (pv.empty()) continue;
auto p = pv.front();

if (p == g.root) continue; // TODO: check skip norm root
if (d == subtree_root || p == subtree_root) continue;

auto cxs = g.get_children(p);
for (auto const& c : cxs)
// 118/637
// precedence graph demands A -> B but rank(A) > rank(B),
// we speak of contradictory sequences.
if (g.rank(p) > g.rank(c)) {
// a new node representing compound relation
g.combine(p, c);
return false;
}
}
return true; // ready to merge
}

/**
* the opposite step of JoinOrdering::IKKBZ_Normalized.
*
* replacing every compound relation by the sequence of relations
* it was derived from
*
* ref: 119/637
* @param g
* @see JoinOrdering::uncombine
*/
void IKKBZ_denormalize(JoinTree& g) {
// TODO: garbage
// TODO: check against rooted at R3 before refactor
while (
!std::ranges::all_of(g.get_descendents(g.root), [g](const Relation& n) {
if (g.hist.contains(n)) return g.hist.at(n).empty();
return true;
}))
// std::ranges::for_each(g.get_descendents(g.root),
// [g](const Relation& x) { return g.uncombine(x);
// });

for (auto const& x : g.get_descendents(g.root)) g.uncombine(x);
}

/**
* transform precedence graph into chain
*
* ref: 121/637
* @param g acyclic query graph
*/
void IKKBZ_Sub(JoinTree& g) {
while (!g.is_chain(g.root)) {
auto subtree = g.get_chained_subtree(g.root);

while (!IKKBZ_Normalized(g, subtree))
;
g.merge(subtree);
}
IKKBZ_denormalize(g);
}

/**
* Polynomial algorithm for join ordering
*
* produces optimal left-deep trees without cross products
* requires acyclic join graphs
*
* Can be used as heuristic if the requirements are violated
*
* ref: 103,120/637
*
* @param g acyclic query graph
* @param n relation used as root for the JoiningOrder::toPrecedenceGraph
* @return optimal left-deep tree
*/
auto IKKBZ(JoinTree g, const Relation& n) -> JoinTree {
// TODO: argmin over all rooted relations
auto new_g = toPrecedenceGraph(g, n);
IKKBZ_Sub(new_g);
return new_g;
}

} // namespace JoinOrdering
Loading
Loading