server/msplanner.py
branchstable
changeset 7188 b2c45b7396fb
parent 6957 ffda12be2e9f
child 7191 1e2d8e4d2c7b
--- a/server/msplanner.py	Wed Apr 06 16:00:56 2011 +0200
+++ b/server/msplanner.py	Wed Apr 06 22:52:39 2011 +0200
@@ -1223,11 +1223,22 @@
     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 @@
                         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 @@
             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