diff --git a/CHANGELOG b/CHANGELOG index 5044c50..04abe36 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ - Added again make install target - Ctrl+C in the terminal will terminate the GUI - Blurs UI while processing +- Added new optimization 2.1 - Introduced sessions; GUI loads the same relations of the previous time diff --git a/relational/optimizations.py b/relational/optimizations.py index 3b5886d..49aff5a 100644 --- a/relational/optimizations.py +++ b/relational/optimizations.py @@ -508,6 +508,41 @@ def select_union_intersect_subtract(n): return changes + recoursive_scan(select_union_intersect_subtract, n) +def union_and_product(n): + ''' + A * B ∪ A * C = A * (B ∪ C) + Same thing with inner join + ''' + + changes = 0 + if n.name == UNION and n.left.name in {PRODUCT, JOIN} and n.left.name == n.right.name: + + newnode = parser.node() + newnode.kind = parser.BINARY + newnode.name = n.left.name + + newchild = parser.node() + newchild.kind = parser.BINARY + newchild.name = UNION + + if n.left.left == n.right.left or n.left.left == n.right.right: + newnode.left = n.left.left + newnode.right = newchild + + newchild.left = n.left.right + newchild.right = n.right.left if n.left.left == n.right.right else n.right.right + replace_node(n, newnode) + changes = 1 + elif n.left.right == n.right.left or n.left.left == n.right.right: + newnode.left = n.left.right + newnode.right = newchild + + newchild.left = n.left.left + newchild.right = n.right.left if n.right.left == n.right.right else n.right.right + replace_node(n, newnode) + changes = 1 + return changes + recoursive_scan(union_and_product, n) + def selection_and_product(n, rels): '''This function locates things like σ k (R*Q) and converts them into @@ -616,7 +651,8 @@ general_optimizations = [ futile_union_intersection_subtraction, swap_union_renames, swap_rename_projection, - select_union_intersect_subtract + select_union_intersect_subtract, + union_and_product ] specific_optimizations = [selection_and_product] diff --git a/test/union_join.query b/test/union_join.query new file mode 100644 index 0000000..f75deee --- /dev/null +++ b/test/union_join.query @@ -0,0 +1 @@ +people⋈σ skill == 'Perl' (skills) ∪ (people⋈σ skill == 'C' (skills)) diff --git a/test/union_join.result b/test/union_join.result new file mode 100644 index 0000000..df2f9b0 --- /dev/null +++ b/test/union_join.result @@ -0,0 +1,8 @@ +id,name,chief,age,skill +4,eve,0,25,C +5,duncan,4,30,C +2,john,1,30,C +7,alia,1,28,C +4,eve,0,25,Perl +5,duncan,4,30,Perl +0,jack,0,22,C