From 71697bb2e8c9619a8509d2e1ae7e1e9d9a772476 Mon Sep 17 00:00:00 2001 From: LtWorf Date: Fri, 18 Feb 2011 18:11:39 +0000 Subject: [PATCH] - Implemented select_union_intersect_subtract general optimization - Added tests for the new optimization git-svn-id: http://galileo.dmi.unict.it/svn/relational/trunk@268 014f5005-505e-4b48-8d0a-63407b615a7c --- CHANGELOG | 1 + relational/optimizations.py | 23 ++++++++++++++++++++++- relational/parser.py | 2 +- test/union_and_select.query | 1 + test/union_and_select.result | 4 ++++ test/union_not_select.query | 1 + test/union_not_select.result | 3 +++ test/union_or_select.query | 1 + test/union_or_select.result | 3 +++ 9 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 test/union_and_select.query create mode 100644 test/union_and_select.result create mode 100644 test/union_not_select.query create mode 100644 test/union_not_select.result create mode 100644 test/union_or_select.query create mode 100644 test/union_or_select.result diff --git a/CHANGELOG b/CHANGELOG index 92f9c47..6a74818 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ - Fixed futile_union_intersection_subtraction optimization that didn't work when selection operator was in the left subtree (Rev 261) - Module parallel does something, can execute queries in parallel - Set hash method for the classes +- Implemented select_union_intersect_subtract general optimization 0.11 - Font is set only on windows (Rev 206) diff --git a/relational/optimizations.py b/relational/optimizations.py index 553de04..f374c2a 100644 --- a/relational/optimizations.py +++ b/relational/optimizations.py @@ -449,6 +449,27 @@ def swap_rename_select(n): return changes+recoursive_scan(swap_rename_select,n) +def select_union_intersect_subtract(n): + '''This function locates things like σ i(a) ᑌ σ q(a) + and replaces them with σ (i OR q) (a) + Removing a O² operation like the union''' + changes=0 + if n.name in ('ᑌ', 'ᑎ', '-') and n.left.name=='σ' and n.right.name=='σ' and n.left.child==n.right.child: + cahnges=1 + + d={'ᑌ':'or', 'ᑎ':'and', '-':'and not'} + op=d[n.name] + + newnode=parser.node() + + newnode.prop='((%s) %s (%s))' % (n.left.prop,op,n.right.prop) + newnode.name='σ' + newnode.child=n.left.child + newnode.kind=parser.UNARY + replace_node(n,newnode) + + return changes+recoursive_scan(select_union_intersect_subtract,n) + def selection_and_product(n,rels): '''This function locates things like σ k (R*Q) and converts them into σ l (σ j (R) * σ i (Q)). Where j contains only attributes belonging to R, @@ -549,7 +570,7 @@ def selection_and_product(n,rels): return changes+recoursive_scan(selection_and_product,n,rels) -general_optimizations=[duplicated_select,down_to_unions_subtractions_intersections,duplicated_projection,selection_inside_projection,subsequent_renames,swap_rename_select,futile_union_intersection_subtraction,swap_union_renames,swap_rename_projection] +general_optimizations=[duplicated_select,down_to_unions_subtractions_intersections,duplicated_projection,selection_inside_projection,subsequent_renames,swap_rename_select,futile_union_intersection_subtraction,swap_union_renames,swap_rename_projection,select_union_intersect_subtract] specific_optimizations=[selection_and_product] if __name__=="__main__": diff --git a/relational/parser.py b/relational/parser.py index cc3c184..f9e2564 100644 --- a/relational/parser.py +++ b/relational/parser.py @@ -132,7 +132,7 @@ class node (object): return '\n'+r def get_left_leaf(self): - '''This function returns the most left leaf in the tree. It is needed by some optimizations.''' + '''This function returns the leftmost leaf in the tree. It is needed by some optimizations.''' if self.kind==RELATION: return self elif self.kind==UNARY: diff --git a/test/union_and_select.query b/test/union_and_select.query new file mode 100644 index 0000000..4749312 --- /dev/null +++ b/test/union_and_select.query @@ -0,0 +1 @@ +σ skill=='C'(skills) ᑎ σ id%2==0 (skills) diff --git a/test/union_and_select.result b/test/union_and_select.result new file mode 100644 index 0000000..98379d8 --- /dev/null +++ b/test/union_and_select.result @@ -0,0 +1,4 @@ +id,skill +0,C +2,C +4,C diff --git a/test/union_not_select.query b/test/union_not_select.query new file mode 100644 index 0000000..84dde17 --- /dev/null +++ b/test/union_not_select.query @@ -0,0 +1 @@ +σ skill=='C' (skills) - σ id%2==0(skills) diff --git a/test/union_not_select.result b/test/union_not_select.result new file mode 100644 index 0000000..b92ce90 --- /dev/null +++ b/test/union_not_select.result @@ -0,0 +1,3 @@ +id,skill +5,C +7,C diff --git a/test/union_or_select.query b/test/union_or_select.query new file mode 100644 index 0000000..39a67dd --- /dev/null +++ b/test/union_or_select.query @@ -0,0 +1 @@ +σ age<21 (people) ᑌ σage >30(people) diff --git a/test/union_or_select.result b/test/union_or_select.result new file mode 100644 index 0000000..5386f2f --- /dev/null +++ b/test/union_or_select.result @@ -0,0 +1,3 @@ +id,name,chief,age +3,dean,1,33 +1,carl,0,20