From 644d96dc635ce7d84524ea75eb8d4730af6c9c94 Mon Sep 17 00:00:00 2001 From: LtWorf Date: Fri, 22 May 2009 23:08:40 +0000 Subject: [PATCH] fixed subsequent_renames. Now handles cycling renames and completely futile ones like renaming attribute into itself git-svn-id: http://galileo.dmi.unict.it/svn/relational/trunk@176 014f5005-505e-4b48-8d0a-63407b615a7c --- relational/optimizations.py | 86 +++++++++++++++++++++++++++++++++---- relational/optimizer.py | 4 +- 2 files changed, 79 insertions(+), 11 deletions(-) diff --git a/relational/optimizations.py b/relational/optimizations.py index e667d42..fa1c20b 100644 --- a/relational/optimizations.py +++ b/relational/optimizations.py @@ -160,14 +160,65 @@ def selection_inside_projection(n): changes+=selection_inside_projection(n.left) return changes +def futile_renames(n): + '''This function removes redoundant subsequent renames''' + #TODO document in the wiki + changes=0 + + if n.name=='ρ': + #Located two nested renames. + changes=1 + + #Creating a dictionary with the attributes + _vars={} + for i in n.prop.split(','): + q=i.split('➡') + _vars[q[0].strip()]=q[1].strip() + #Scans dictionary to locate things like "a->b,b->c" and replace them with "a->c" + for key in list(_vars.keys()): + try: + value=_vars[key] + except: + value=None + if key==value: + _vars.pop(value) #Removes the unused one + #Reset prop var + n.prop="" + + #Generates new prop var + for i in _vars.items(): + n.prop+="%s➡%s," % (i[0],i[1]) + n.prop=n.prop[:-1] #Removing ending comma + + if len(n.prop)==0: #Nothing to rename, removing the rename op + n.name=n.child.name + n.kind=n.child.kind + if n.kind==optimizer.UNARY: + n.prop=n.child.prop + n.child=n.child.child + elif n.kind==optimizer.BINARY: + n.left=n.child.left + n.right=n.child.right + + #recoursive scan + if n.kind==optimizer.UNARY: + changes+=futile_renames(n.child) + elif n.kind==optimizer.BINARY: + changes+=futile_renames(n.right) + changes+=futile_renames(n.left) + return changes + def subsequent_renames(n): '''This function removes redoundant subsequent renames''' + + '''Purges renames like id->id Since it's needed to be performed BEFORE this one + so it is not in the list with the other optimizations''' + futile_renames(n) changes=0 if n.name=='ρ' and n.child.name==n.name: #Located two nested renames. changes=1 - #Joining the attribute into one n.prop+=','+n.child.prop n.child=n.child.child @@ -177,13 +228,20 @@ def subsequent_renames(n): for i in n.prop.split(','): q=i.split('➡') _vars[q[0].strip()]=q[1].strip() - #Scans dictionary to locate things like "a->b,b->c" and replace them with "a->c" - for i in list(_vars.keys()): - if _vars[i] in _vars.keys(): - #Double rename on attribute - _vars[i] = _vars[_vars[i]] #Sets value - _vars.pop(i) #Removes the unused one + for key in list(_vars.keys()): + try: + value=_vars[key] + except: + value=None + if value in _vars.keys(): + if _vars[value]!=key: + #Double rename on attribute + _vars[key] = _vars[_vars[key]] #Sets value + _vars.pop(value) #Removes the unused one + else: #Cycle rename a->b,b->a + _vars.pop(value) #Removes the unused one + _vars.pop(key) #Removes the unused one #Reset prop var n.prop="" @@ -191,7 +249,17 @@ def subsequent_renames(n): #Generates new prop var for i in _vars.items(): n.prop+="%s➡%s," % (i[0],i[1]) - n.prop=n.prop[:-1] #Removing ending comma + n.prop=n.prop[:-1] #Removing ending comma + + if len(n.prop)==0: #Nothing to rename, removing the rename op + n.name=n.child.name + n.kind=n.child.kind + if n.kind==optimizer.UNARY: + n.prop=n.child.prop + n.child=n.child.child + elif n.kind==optimizer.BINARY: + n.left=n.child.left + n.right=n.child.right #recoursive scan if n.kind==optimizer.UNARY: @@ -389,4 +457,4 @@ def selection_and_product(n,rels): return changes general_optimizations=[duplicated_select,down_to_unions_subtractions_intersections,duplicated_projection,selection_inside_projection,subsequent_renames,swap_rename_select,futile_union_intersection_subtraction] -specific_optimizations=[selection_and_product] \ No newline at end of file +specific_optimizations=[selection_and_product] diff --git a/relational/optimizer.py b/relational/optimizer.py index 81a102e..c376814 100644 --- a/relational/optimizer.py +++ b/relational/optimizer.py @@ -284,8 +284,8 @@ if __name__=="__main__": #print n #print n.result_format(rels) - a=general_optimize("ρ i➡index(ρ id➡i (people))") + a=general_optimize("ρ index➡index(ρ index➡id(ρ index➡index(σ index==3(ρ id➡index (people)))))") #a=general_optimize("σ i==2 (σ b>5 (d))") - #print a + print a #print node(a) #print tokenize("(a)") \ No newline at end of file