<jupyter_start><jupyter_text>! Add Relations in BFS order!  DPccpWe first define a query graph for our examples:<jupyter_code>qg = QueryGraph() # add relations in BFS order!
r1= qg.add_relation('R1', 10)
r2 = qg.add_relation('R2', 20)
r3 = qg.add_relation('R3', 50)
r4 = qg.add_relation('R4', 20)
r5 = qg.add_relation('R5', 10)
qg.add_join(r1, r2, 0.1)
qg.add_join(r1, r3, 0.1)
qg.add_join(r2, r3, 0.1)
qg.add_join(r2, r4, 0.1)
qg.add_join(r3, r4, 0.1)
qg.add_join(r3, r5, 0.1)
qg.add_join(r4, r5, 0.1)

Source(querygraph_to_graphviz(qg, cardinalities=False, selectivities=False))<jupyter_output><empty_output><jupyter_text>Example 1 - Enumeration of all CSG-CMP pairsThis example comes from the 8th tutorial. The solution can be found in moodle.<jupyter_code>dpccp = Dpccp(qg)

table = []
# we're not using dpccp.get_csg_cmp_pairs here so we can also illustrate empty cmp sets.
for csg in dpccp.enumerate_csg():
    cmps = list(dpccp.enumerate_cmp(csg))
    if len(cmps) == 0:
        table.append({
            'csg':  str(list(map(str, csg))),
            'cmp': '[]'
        })
    else:
        for cmp in cmps:
            table.append({
                'csg':  str(list(map(str, csg))),
                'cmp': str(list(map(str,cmp)))
            })
pd.DataFrame.from_dict(table)<jupyter_output><empty_output><jupyter_text>Example 2 - Get the optimal join tree based on c_out<jupyter_code>t = dpccp.run()
Source(join_tree_to_graphviz(t))<jupyter_output><empty_output><jupyter_text>All dpccp combinations<jupyter_code>table = []
for key, tree_lst in dpccp.dpverbose.items():
    for tree in tree_lst:
        table.append({
            'l': len(tree.relations),
            'relations' : key,
            'tree': str(tree),
            'cost': tree.cost,
            'cheapest': 'Yes' if tree == dpccp.dptable[key] else 'No'
        })
pd.DataFrame.from_dict(table).sort_values(by=['l', 'relations'], ascending=True)<jupyter_output><empty_output><jupyter_text>ex13<jupyter_code>qg = QueryGraph() # add relations in BFS order!
r1= qg.add_relation('R1', 10)
r2 = qg.add_relation('R2', 10)
r3 = qg.add_relation('R3', 10)
r4 = qg.add_relation('R4', 10)
r5 = qg.add_relation('R5', 10)
qg.add_join(r1, r2, 0.1)
qg.add_join(r1, r3, 0.1)
qg.add_join(r1, r4, 0.1)
qg.add_join(r3, r5, 0.1)

Source(querygraph_to_graphviz(qg, cardinalities=False, selectivities=False))
dpccp = Dpccp(qg)

table = []
# we're not using dpccp.get_csg_cmp_pairs here so we can also illustrate empty cmp sets.
for csg in dpccp.enumerate_csg():
    cmps = list(dpccp.enumerate_cmp(csg))
    if len(cmps) == 0:
        table.append({
            'csg':  str(list(map(str, csg))),
            'cmp': '[]'
        })
    else:
        for cmp in cmps:
            table.append({
                'csg':  str(list(map(str, csg))),
                'cmp': str(list(map(str,cmp)))
            })
pd.DataFrame.from_dict(table)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15284441398217957, 'fraction_numerical': 0.031185743660041124, 'mean_word_length': 3.416036308623298, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '118898', 'license': 'Apache-2.0', 'n_tokens_mistral': 1251, 'n_tokens_neox': 1196, 'n_words': 239, 'path': 'Query Optimization/algorithms/ikkbz_hist/dpccp.ipynb', 'repo_name': 'sschaeffner/TUM', 'size': '2918'}