Exemplo n.º 1
0
def contexts(all_relations, base, dependencies):
    """
    Build Contexts - sets of relations that satisfy Lossless join property
    based on the `base` relations provided.

    :param all_relations: list of all relations to add to the context
    :param base: list of strings - names of the relations that are initially in
        the context
    :param dependencies: list of dependencies held in the DB
    :return yield list of relations representing context
    """
    base_relations = [r for r in all_relations if r['name'] in base]
    relations_to_check = [r for r in all_relations if r['name'] not in base]

    relations_to_check, priorities = zip(*prioritized_relations(
        relations_to_check, base_relations, dependencies))

    n = len(relations_to_check)
    for k in range(n + 1):
        relation_packs = itertools.combinations(relations_to_check, k)
        for relations in relation_packs:
            context = base_relations + list(relations)
            satisfied_deps = filter(
                lambda d: set(d['left'] | d['right']).issubset(
                    all_attributes(context)), dependencies)
            if is_lossless(context, satisfied_deps):
                yield context
Exemplo n.º 2
0
 def test_simplest_case(self):
     """
     Test chase algorithm in the simplest succeeding case with single
     dependency held on same attribute value
     """
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT', 'C': 'INT'}}
     r2 = {'name': 'R2', 'attributes': {'C': 'INT', 'D': 'INT'}}
     deps = [{'left': ('C', ), 'right': ('D', )}]
     self.assertTrue(is_lossless([r1, r2], deps))
Exemplo n.º 3
0
 def test_simplest_case(self):
     """
     Test chase algorithm in the simplest succeeding case with single
     dependency held on same attribute value
     """
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT', 'C': 'INT'}}
     r2 = {'name': 'R2', 'attributes': {'C': 'INT', 'D': 'INT'}}
     deps = [{'left': ('C',), 'right': ('D',)}]
     self.assertTrue(is_lossless([r1, r2], deps))
Exemplo n.º 4
0
 def test_advanced_lossless_not_held(self):
     """
     This example was also taken from the Ullman's "Database Systems - The
     Complete book"
     """
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT'}}
     r2 = {'name': 'R2', 'attributes': {'B': 'INT', 'C': 'INT'}}
     r3 = {'name': 'R3', 'attributes': {'C': 'INT', 'D': 'INT'}}
     deps = [{'left': ('B', ), 'right': ('A', 'D')}]
     self.assertFalse(is_lossless([r1, r2, r3], deps))
Exemplo n.º 5
0
 def test_cartesian_product_separate_deps(self):
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT'}}
     r2 = {'name': 'R2', 'attributes': {'C': 'INT', 'D': 'INT'}}
     deps = [{
         'left': ('A', ),
         'right': ('B', )
     }, {
         'left': ('C', ),
         'right': ('D', )
     }]
     self.assertFalse(is_lossless([r1, r2], deps))
Exemplo n.º 6
0
 def test_single_relation(self):
     r1 = {
         'name': 'R1',
         'attributes': {
             'pk': 'INT',
             'A_1': 'INT',
             'A_2': 'INT'
         }
     }
     deps = [{'left': {'pk'}, 'right': {'A_1', 'A_2'}}]
     self.assertTrue(is_lossless([r1], deps))
Exemplo n.º 7
0
 def test_separate_deps_common_attributes(self):
     """
     Check the case when relations intersect over some attributes but don't
     have any dependencies uniting them
     """
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT', 'C': 'INT'}}
     r2 = {'name': 'R2', 'attributes': {'B': 'INT', 'D': 'INT', 'E': 'INT'}}
     deps = [
         {'left': ('A', 'B'), 'right': ('C',)},  # R1 primary key
         {'left': ('B', 'D'), 'right': ('E',)},  # R2 primary key
     ]
     self.assertFalse(is_lossless([r1, r2], deps))
Exemplo n.º 8
0
 def test_advanced_lossless_not_held(self):
     """
     This example was also taken from the Ullman's "Database Systems - The
     Complete book"
     """
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT'}}
     r2 = {'name': 'R2', 'attributes': {'B': 'INT', 'C': 'INT'}}
     r3 = {'name': 'R3', 'attributes': {'C': 'INT', 'D': 'INT'}}
     deps = [
         {'left': ('B',), 'right': ('A', 'D')}
     ]
     self.assertFalse(is_lossless([r1, r2, r3], deps))
Exemplo n.º 9
0
def lossless_combinations(relations, dependencies):
    n = len(relations)
    for k in range(n + 1):
        combinations = itertools.combinations(relations, k)
        for combination in combinations:

            def is_dependency_held(dep):
                attributes = set(dep['left'] | dep['right'])
                return attributes.issubset(all_attributes(combination))

            satisfied_deps = filter(is_dependency_held, dependencies)
            if is_lossless(combination, satisfied_deps):
                yield list(combination)
Exemplo n.º 10
0
 def test_separate_deps_common_attributes(self):
     """
     Check the case when relations intersect over some attributes but don't
     have any dependencies uniting them
     """
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT', 'C': 'INT'}}
     r2 = {'name': 'R2', 'attributes': {'B': 'INT', 'D': 'INT', 'E': 'INT'}}
     deps = [
         {
             'left': ('A', 'B'),
             'right': ('C', )
         },  # R1 primary key
         {
             'left': ('B', 'D'),
             'right': ('E', )
         },  # R2 primary key
     ]
     self.assertFalse(is_lossless([r1, r2], deps))
Exemplo n.º 11
0
 def test_cartesian_product_no_deps(self):
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT'}}
     r2 = {'name': 'R2', 'attributes': {'C': 'INT', 'D': 'INT'}}
     deps = []
     self.assertFalse(is_lossless([r1, r2], deps))
Exemplo n.º 12
0
 def test_single_relation_no_deps(self):
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT'}}
     deps = []
     self.assertTrue(is_lossless([r1], deps))
Exemplo n.º 13
0
 def test_cartesian_product_separate_deps(self):
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT'}}
     r2 = {'name': 'R2', 'attributes': {'C': 'INT', 'D': 'INT'}}
     deps = [{'left': ('A',), 'right': ('B',)},
             {'left': ('C',), 'right': ('D',)}]
     self.assertFalse(is_lossless([r1, r2], deps))
Exemplo n.º 14
0
 def test_cartesian_product_no_deps(self):
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT'}}
     r2 = {'name': 'R2', 'attributes': {'C': 'INT', 'D': 'INT'}}
     deps = []
     self.assertFalse(is_lossless([r1, r2], deps))
Exemplo n.º 15
0
 def test_single_relation(self):
     r1 = {'name': 'R1', 'attributes': {'pk': 'INT', 'A_1': 'INT',
                                        'A_2': 'INT'}}
     deps = [{'left': {'pk'}, 'right': {'A_1', 'A_2'}}]
     self.assertTrue(is_lossless([r1], deps))
Exemplo n.º 16
0
 def test_single_relation_no_deps(self):
     r1 = {'name': 'R1', 'attributes': {'A': 'INT', 'B': 'INT'}}
     deps = []
     self.assertTrue(is_lossless([r1], deps))