'''This module optimizes relational expressions into ones that require less time to be executed
Fornowitishighlyexperimental,anditshouldn't be used in 3rd party applications.'''
RELATION=0
UNARY=1
BINARY=2
classnode(object):
'''This class is a node of a relational expression. Leaves are relations and internal nodes are operations.'''
RELATION=0
UNARY=1
BINARY=2
def__init__(self,expression):
expression=expression.strip()
print"Parsing: ",expression
'''expression must be a valid relational algrbra expression that would be accepted by the parser
andmustbeutf16'''
self.kind=0
self.name="a"
self.prop=""
'''*-ᑌᑎᐅᐊᐅLEFTᐊᐅRIGHTᐊᐅFULLᐊπσρ'''
binary=(u"*",u"-",u"ᑌ",u"ᑎ")
unary=(u"π",u"σ",u"ρ")
'''(a ᑌ (a ᑌ b ᑌ c ᑌ d)) ᑎ c - σ i==3(πa,b(aᑌ b ᑎ c))'''
level=0#Current parentesis level
start=-1#Start of the parentesis
end=-1#End of the parentesis.
tokens=list(expression)#Splitted expression
r=range(len(tokens))
r.reverse()
lev_non_zero_chars=0#Number of chars inside parentesis
foriinr:#Parses expression from end to begin, to preserve operation's order
iftokens[i]==u"(":
iflevel==0:
start=i
printstart
level+=1
eliftokens[i]==u")":
level-=1
iflevel==0:
end=i
printend
iflevel!=0:
lev_non_zero_chars+=1
ifi==0andlevel==0andtokens[i]inunary:#Unary operator found, must grab its parameters and its child relation they
child=""
forqintokens[start+1:end]:
child+=q
self.name=tokens[i]
print"-----",tokens[i]
print"---",start,end,lev_non_zero_chars
printchild
#print prop
#self.child=node(child)
iflevel==0andtokens[i]inbinary:#Binary operator found, everything on left will go in the left subree and everhthing on the right will go in the right subtree
self.kind=BINARY
left=""
right=""
ifstart==end==-1:#No parentesis before
end=i
forqintokens[start+1:end]:
left+=q
self.name=tokens[i]
forqintokens[i+1:]:
right+=q
print"self: ",tokens[i]
print"left: ",left
print"right:",right
self.left=node(left)
self.right=node(right)
return
iflev_non_zero_chars!=0andlev_non_zero_chars+1==len(expression):#Expression is entirely contained in parentesis, removing them
n=node(expression[1:-1])
self.name=n.name
self.kind=n.kind
ifn.kind==UNARY:
self.child=n.child
elifn.kind==BINARY:
self.left=n.left
self.right=n.right
self.prop=n.prop
return
self.kind=RELATION
self.name=expression
pass
def__str__(self):
if(self.kind==RELATION):
@ -207,6 +129,11 @@ def tokenize(expression):
returnitems
deftree(expression):
'''This function parses a relational algebra expression into a tree and returns