Commit ba9e4924 authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

[ms planner] use an index to avoid doing the same step twice

--HG--
branch : stable
parent 287f2273917f
......@@ -1223,11 +1223,22 @@ class PartPlanInformation(object):
def build_non_final_part(self, select, solindices, sources, insertedvars,
table):
"""non final step, will have to store results in a temporary table"""
inputmapkey = tuple(sorted(solindices))
solutions = [self._solutions[i] for i in solindices]
rqlst = self.plan.finalize(select, solutions, insertedvars)
step = FetchStep(self.plan, rqlst, sources, table, False)
# XXX be smarter vs rql comparison
idx_key = (select.as_string(), inputmapkey,
tuple(sorted(sources)), tuple(sorted(insertedvars)))
try:
# if a similar step has already been process, simply backport its
# input map
step = self.plan.ms_steps_idx[idx_key]
except KeyError:
# processing needed
rqlst = self.plan.finalize(select, solutions, insertedvars)
step = FetchStep(self.plan, rqlst, sources, table, False)
self.plan.ms_steps_idx[idx_key] = step
self.plan.add_step(step)
# update input map for following steps, according to processed solutions
inputmapkey = tuple(sorted(solindices))
inputmap = self._inputmaps.setdefault(inputmapkey, {})
for varname, mapping in step.outputmap.iteritems():
if varname in inputmap and not '.' in varname and \
......@@ -1235,7 +1246,6 @@ class PartPlanInformation(object):
self._schema.eschema(solutions[0][varname]).final):
self._conflicts.append((varname, inputmap[varname]))
inputmap.update(step.outputmap)
self.plan.add_step(step)
class MSPlanner(SSPlanner):
......@@ -1259,6 +1269,7 @@ class MSPlanner(SSPlanner):
print 'PLANNING', rqlst
ppis = [PartPlanInformation(plan, select, self.rqlhelper)
for select in rqlst.children]
plan.ms_steps_idx = {}
steps = self._union_plan(plan, ppis)
if server.DEBUG & server.DBG_MS:
from pprint import pprint
......
......@@ -2383,6 +2383,56 @@ class MSPlannerTC(BaseMSPlannerTC):
None, None, [self.system], {}, [])],
{'x': 999999, 'u': 999998})
def test_nonregr_similar_subquery(self):
repo._type_source_cache[999999] = ('Personne', 'system', 999999)
self._test('Any T,TD,U,T,UL WITH T,TD,U,UL BEING ('
'(Any T,TD,U,UL WHERE X eid %(x)s, T comments X, T content TD, T created_by U?, U login UL)'
' UNION '
'(Any T,TD,U,UL WHERE X eid %(x)s, X connait P, T comments P, T content TD, T created_by U?, U login UL))',
# XXX optimization: use a OneFetchStep with a UNION of both queries
[('FetchStep', [('Any U,UL WHERE U login UL, U is CWUser',
[{'U': 'CWUser', 'UL': 'String'}])],
[self.ldap, self.system], None,
{'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
[]),
('UnionFetchStep',
[('FetchStep',
[('Any T,TD,U,UL WHERE T comments 999999, T content TD, T created_by U?, U login UL, T is Comment, U is CWUser',
[{'T': 'Comment', 'TD': 'String', 'U': 'CWUser', 'UL': 'String'}])],
[self.system],
{'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
{'T': 'table1.C0',
'T.content': 'table1.C1',
'TD': 'table1.C1',
'U': 'table1.C2',
'U.login': 'table1.C3',
'UL': 'table1.C3'},
[]),
('FetchStep',
[('Any T,TD,U,UL WHERE 999999 connait P, T comments P, T content TD, T created_by U?, U login UL, P is Personne, T is Comment, U is CWUser',
[{'P': 'Personne',
'T': 'Comment',
'TD': 'String',
'U': 'CWUser',
'UL': 'String'}])],
[self.system],
{'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
{'T': 'table1.C0',
'T.content': 'table1.C1',
'TD': 'table1.C1',
'U': 'table1.C2',
'U.login': 'table1.C3',
'UL': 'table1.C3'},
[])]),
('OneFetchStep',
[('Any T,TD,U,T,UL',
[{'T': 'Comment', 'TD': 'String', 'U': 'CWUser', 'UL': 'String'}])],
None, None,
[self.system],
{'T': 'table1.C0', 'TD': 'table1.C1', 'U': 'table1.C2', 'UL': 'table1.C3'},
[])],
{'x': 999999})
class MSPlannerTwoSameExternalSourcesTC(BasePlannerTC):
"""test planner related feature on a 3-sources repository:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment