[Checkins] SVN: Sandbox/adamg/ocql/trunk/src/ocql/ introduced a central compile method, extended doctest

Adam Groszer agroszer at gmail.com
Wed Aug 13 11:57:07 EDT 2008


Log message for revision 89800:
  introduced a central compile method, extended doctest

Changed:
  U   Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py
  U   Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.txt
  U   Sandbox/adamg/ocql/trunk/src/ocql/rewriter/tests.py

-=-
Modified: Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py	2008-08-13 15:39:43 UTC (rev 89799)
+++ Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py	2008-08-13 15:57:07 UTC (rev 89800)
@@ -13,26 +13,38 @@
 from zope.component import provideAdapter
 
 from ocql.interfaces import IAlgebraCompiler
-#from ocql.interfaces import IAlgebraCompiler
 from ocql.interfaces import IOptimizedAlgebraObject
-#from ocql.interfaces import ICompiledAlgebraObject
 from ocql.rewriter.algebra import Head
 
 from ocql.rewriter.interfaces import *
 
 from ocql.compiler.runnablequery import RunnableQuery
 
+RELAX_COMPILE = False
+
+def compile(expr):
+    #nasty?? thing to allow compilation of not fully compliant algebra tree
+    #mostly required for demonstration purposes
+    try:
+        code = IAlgebraCompiler(expr)()
+    except TypeError:
+        if RELAX_COMPILE:
+            if isinstance(expr, basestring):
+                return expr
+            return unicode(expr)
+        else:
+            raise
+    return code
+
 class AlgebraCompiler(object):
     implements(IAlgebraCompiler)
     adapts(IOptimizedAlgebraObject)
 
     def __init__(self, context):
         self.context = context
-        #self.db = db
 
     def __call__(self, metadata, originalAlgebra):
-        adapter = IAlgebraCompiler(self.context.tree)
-        code = adapter()
+        code = compile(self.context.tree)
         run = RunnableQuery(metadata, originalAlgebra, code)
         return run
 
@@ -57,9 +69,9 @@
 
     def __call__(self):
         if self.context.klass == set:
-            return 'set(['+IAlgebraCompiler(self.context.expr)()+'])'
+            return 'set(['+compile(self.context.expr)+'])'
         elif self.context.klass == list:
-            return '['+IAlgebraCompiler(self.context.expr)()+']'
+            return '['+compile(self.context.expr)+']'
 
 class UnionCompiler(BaseCompiler):
     implements(IAlgebraCompiler)
@@ -68,12 +80,12 @@
     def __call__(self):
         if self.context.klass == set:
             return 'set.union(%s, %s)' % (
-                IAlgebraCompiler(self.context.coll1)(),
-                IAlgebraCompiler(self.context.coll2)())
+                compile(self.context.coll1),
+                compile(self.context.coll2))
         elif self.context.klass == list:
             return '(%s)+(%s)' % (
-                IAlgebraCompiler(self.context.coll1)(),
-                IAlgebraCompiler(self.context.coll2)())
+                compile(self.context.coll1),
+                compile(self.context.coll2))
 
 class DifferCompiler(BaseCompiler):
     implements(IAlgebraCompiler)
@@ -82,13 +94,13 @@
     def __call__(self):
         if self.context.klass == set:
             return 'set.differ(%s, %s)' % (
-                IAlgebraCompiler(self.context.coll1)(),
-                IAlgebraCompiler(self.context.coll2)())
+                compile(self.context.coll1),
+                compile(self.context.coll2))
 
         elif self.context.klass == list:
             return '(%s)-(%s)' % (
-                IAlgebraCompiler(self.context.coll1)(),
-                IAlgebraCompiler(self.context.coll2)())
+                compile(self.context.coll1),
+                compile(self.context.coll2))
 
 class IterCompiler(BaseCompiler):
     implements(IAlgebraCompiler)
@@ -97,12 +109,12 @@
     def __call__(self):
         if self.context.klass == set:
             return 'reduce(set.union, map(%s, %s), set())' % (
-                IAlgebraCompiler(self.context.func)(),
-                IAlgebraCompiler(self.context.coll)())
+                compile(self.context.func),
+                compile(self.context.coll))
         if self.context.klass == list:
             return 'reduce(operator.add, map(%s, %s), [])' % (
-                IAlgebraCompiler(self.context.func)(),
-                IAlgebraCompiler(self.context.coll)())
+                compile(self.context.func),
+                compile(self.context.coll))
 
 
 class SelectCompiler(BaseCompiler):
@@ -112,12 +124,12 @@
     def __call__(self):
         if self.context.klass == set:
             return 'set(filter(%s, %s))' % (
-                IAlgebraCompiler(self.context.func)(),
-                IAlgebraCompiler(self.context.call)())
+                compile(self.context.func),
+                compile(self.context.call))
         if self.context.klass == list:
             return 'filter()%s, %s' % (
-                IAlgebraCompiler(self.context.func)(),
-                IAlgebraCompiler(self.context.call)())
+                compile(self.context.func),
+                compile(self.context.call))
 
 
 class ReduceCompiler(BaseCompiler):
@@ -127,16 +139,16 @@
     def __call__(self):
         if self.context.klass == set:
             return 'reduce(%s, map(%s, %s), %s)' % (
-                IAlgebraCompiler(self.context.aggreg)(),
-                IAlgebraCompiler(self.context.func)(),
-                IAlgebraCompiler(self.context.coll)(),
-                IAlgebraCompiler(self.context.expr)())
+                compile(self.context.aggreg),
+                compile(self.context.func),
+                compile(self.context.coll),
+                compile(self.context.expr))
         elif self.context.klass == list:
             return 'reduce(%s, map(%s, %s), %s)'% (
-                IAlgebraCompiler(self.context.aggreg)(),
-                IAlgebraCompiler(self.context.func)(),
-                IAlgebraCompiler(self.context.coll)(),
-                IAlgebraCompiler(self.context.expr)())
+                compile(self.context.aggreg),
+                compile(self.context.func),
+                compile(self.context.coll),
+                compile(self.context.expr))
 
 
 class RangeCompiler(BaseCompiler):
@@ -146,12 +158,12 @@
     def __call__(self):
         if self.context.klass == set:
             return 'set(range(%s,%s))' % (
-                IAlgebraCompiler(self.context.start)(),
-                IAlgebraCompiler(self.context.end)())
+                compile(self.context.start),
+                compile(self.context.end))
         elif self.context.klass == list:
             return 'range(%s,%s)' % (
-                IAlgebraCompiler(self.context.start)(),
-                IAlgebraCompiler(self.context.end)())
+                compile(self.context.start),
+                compile(self.context.end))
 
 
 class MakeCompiler(BaseCompiler):
@@ -161,7 +173,7 @@
     def __call__(self):
         return '%s(metadata.getAll("%s"))' % (
             self.context.coll1.__name__,
-            IAlgebraCompiler(self.context.expr)())
+            compile(self.context.expr))
 
 
 class MakeFromIndexCompiler(BaseCompiler):
@@ -183,9 +195,9 @@
 
     def __call__(self):
         return '((%s) and (%s) or (%s))' % (
-            IAlgebraCompiler(self.context.cond)(),
-            IAlgebraCompiler(self.context.expr1)(),
-            IAlgebraCompiler(self.context.expr2)())
+            compile(self.context.cond),
+            compile(self.context.expr1),
+            compile(self.context.expr2))
 
 
 class LambdaCompiler(BaseCompiler):
@@ -195,7 +207,7 @@
     def __call__(self):
         return 'lambda %s: %s' % (
             self.context.var,
-            IAlgebraCompiler(self.context.expr)())
+            compile(self.context.expr))
 
 
 class ConstantCompiler(BaseCompiler):
@@ -220,9 +232,9 @@
 
     def __call__(self):
         return '%s%s%s' % (
-            IAlgebraCompiler(self.context.left)(),
+            compile(self.context.left),
             self.context.op.op,
-            IAlgebraCompiler(self.context.right)())
+            compile(self.context.right))
 
 
 class OperatorCompiler(BaseCompiler):

Modified: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.txt	2008-08-13 15:39:43 UTC (rev 89799)
+++ Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.txt	2008-08-13 15:57:07 UTC (rev 89800)
@@ -1,23 +1,60 @@
 
-Following algebra operation descriptions extracted from http://citeseer.ist.psu.edu/359340.html
+Algebra
+=======
+
+The design of the canonical algebra aims for simplicity, regularity, and
+extensibility. The canonical algebra consists of a small number of collection
+and non-collection operations. Some of the operations are parameterised with
+functional arguments. This treatment makes the operations more regular as
+variations can be captured in the functional arguments. Unlike methods found
+in the object-oriented paradigm, these functions are system-defined and hence
+amenable to reasoning and therefore optimisation. The use of functional arguments
+together with a regular set of collection operations makes the algebra more
+extensible as a new collection can be integrated by providing a set of the
+regular operations. However, it should be noted that the canonical algebra is
+not a minimal set of operations, some operations can be defined by others,
+for example, select is introduced to capture well-known evaluation strategies.
+
+
+Following algebra operation descriptions extracted from
+http://citeseer.ist.psu.edu/359340.html
 Corresponding Python implementations are used in this project
 
+The samples use simplified expressions instead of a full complicated algebra
+tree to be able to focus on the meat.
+But still the results should pass.
+
 Binary Operations
 -----------------
 
-The union and differ operations take two operands of the same collection kind and return
-a resultant collection of that kind. The most specific unique common superclass of the
-operand element classes will become the class of the elements in the resultant collection.
+The union and differ operations take two operands of the same collection kind
+and return a resultant collection of that kind. The most specific unique common
+superclass of the operand element classes will become the class of the elements
+in the resultant collection.
 
 Union ( C1, C2 )
 -----------------
-The union operations combine two collections. The cardinality of each resultant element
-is the sum of its cardinalities in the operand collections except in the case of sets
-where all elements are unique. Ordering, if respected, will be preserved.
+The union operations combine two collections. The cardinality of each resultant
+element is the sum of its cardinalities in the operand collections except in the
+case of sets where all elements are unique. Ordering, if respected, will be
+preserved.
 
 	>>> from ocql.rewriter.algebra import Union
-	>>> x = Union()
+	>>> x = Union(set, set([1, 2]), set([2, 3]))
+	>>> x
+	Union(<type 'set'>, set([1, 2]), set([2, 3]))
 
+	>>> run(x)
+	set([1, 2, 3])
+
+
+	>>> x = Union(list, [1, 2], [2, 3])
+	>>> x
+	Union(<type 'list'>, [1, 2], [2, 3])
+
+	>>> run(x)
+	[1, 2, 2, 3]
+
 Differ ( C1, C2 )
 ------------------
 The differ operations form a collection by removing elements of the second operand
@@ -45,7 +82,7 @@
 ---------------------------------
 The reduce operations are used to combine elements in a collection. If the operand
 collection C is empty, E0 is returned. When the operand collection is not empty, F1 is
-applied to each element of C and the results are supplied pairwise to Faggregate which 
+applied to each element of C and the results are supplied pairwise to Faggregate which
 accumulates the results to give a single value.
 	>>> from ocql.rewriter.algebra import Reduce
 	>>> x = Reduce()

Modified: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/tests.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/rewriter/tests.py	2008-08-13 15:39:43 UTC (rev 89799)
+++ Sandbox/adamg/ocql/trunk/src/ocql/rewriter/tests.py	2008-08-13 15:57:07 UTC (rev 89800)
@@ -2,16 +2,31 @@
 import doctest
 from zope.testing.doctestunit import DocTestSuite,DocFileSuite
 
+from ocql.compiler import compiler
+
+def run(expr):
+    return eval(compiler.compile(expr))
+
+def setup(test):
+    test.__save_relax = compiler.RELAX_COMPILE
+    compiler.RELAX_COMPILE = True
+
+    compiler.registerAdapters()
+
+def teardown(test):
+    compiler.RELAX_COMPILE = test.__save_relax
+
 def test_suite():
     flags =  doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
     return unittest.TestSuite((
         DocFileSuite('rewriter.txt',
             optionflags=flags),
         DocFileSuite('algebra.txt',
+            optionflags=flags,
+            globs={'run': run},
+            setUp = setup, tearDown = teardown),
+        DocFileSuite('algebra_checks.txt',
             optionflags=flags),
-        DocFileSuite('algebra_checks.txt',
-            optionflags=flags),            
-        DocTestSuite('ocql.rewriter.algebra')
         ))
 
 



More information about the Checkins mailing list