[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