Query splitter complete

This commit is contained in:
Salvo 'LtWorf' Tomaselli 2016-08-21 11:03:45 +02:00
parent 47bc995fd9
commit f0d50eabee
2 changed files with 60 additions and 2 deletions

View File

@ -25,6 +25,7 @@
from relational import optimizations
from relational import parser
from relational import querysplit
from relational.maintenance import UserInterface
@ -57,8 +58,8 @@ def optimize_program(code, rels):
parsed = parser.tree(query)
optimizations.replace_leaves(parsed, context)
context[res] = parsed
result = optimize_all(context[last_res], rels)
return result
node = optimize_all(context[last_res], rels, tostr=False)
return querysplit.split(node, rels)
def optimize_all(expression, rels, specific=True, general=True, debug=None,tostr=True):

View File

@ -19,6 +19,52 @@
# This module splits a query into a program.
from relational import parser
class Program:
def __init__(self, rels):
self.queries = []
self.dictionary = {} # Key is the query, value is the relation
self.vgen = vargen(rels, 'optm_')
def __str__(self):
r = ''
for q in self.queries:
r += '%s = %s' % (q[0], q[1]) + '\n'
return r.rstrip()
def append_query(self, node):
strnode = str(node)
rel = self.dictionary.get(strnode)
if rel:
return rel
qname = next(self.vgen)
self.queries.append((qname, node))
n = parser.Node()
n.kind = parser.RELATION
n.name = qname
self.dictionary[strnode] = n
return n
def _separate(node, program):
if node.kind == parser.UNARY and node.child.kind != parser.RELATION:
_separate(node.child, program)
rel = program.append_query(node.child)
node.child = rel
elif node.kind == parser.BINARY:
if node.left.kind != parser.RELATION:
_separate(node.left, program)
rel = program.append_query(node.left)
node.left = rel
if node.right.kind != parser.RELATION:
_separate(node.right, program)
rel = program.append_query(node.right)
node.right = rel
program.append_query(node)
def vargen(avoid, prefix=''):
'''
Generates temp variables.
@ -40,3 +86,14 @@ def vargen(avoid, prefix=''):
if r not in avoid:
yield r
count += 1
def split(node, rels):
'''
Split a query into a program.
The idea is that if there are duplicated subdtrees they
get executed only once.
'''
p = Program(rels)
_separate(node, p)
return str(p)