[Checkins] SVN: Sandbox/adamg/ocql/trunk/src/ocql/ merge of branch
optimize-with-index
Adam Groszer
agroszer at gmail.com
Fri Aug 8 05:13:05 EDT 2008
Log message for revision 89534:
merge of branch optimize-with-index
Changed:
U Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.py
U Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.txt
A Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer_new.txt
U Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/tests.py
U Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py
U Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.txt
A Sandbox/adamg/ocql/trunk/src/ocql/compiler/optimize_index.txt
U Sandbox/adamg/ocql/trunk/src/ocql/compiler/runnablequery.py
U Sandbox/adamg/ocql/trunk/src/ocql/compiler/tests.py
U Sandbox/adamg/ocql/trunk/src/ocql/database/metadata.py
U Sandbox/adamg/ocql/trunk/src/ocql/engine.py
D Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py
A Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py
U Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.py
U Sandbox/adamg/ocql/trunk/src/ocql/rewriter/interfaces.py
U Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.txt
U Sandbox/adamg/ocql/trunk/src/ocql/testing/database.py
U Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/interfaces.py
U Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/project.py
U Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/student.py
U Sandbox/adamg/ocql/trunk/src/ocql/testing/stubs.py
U Sandbox/adamg/ocql/trunk/src/ocql/testing/utils.py
A Sandbox/adamg/ocql/trunk/src/ocql/testing/utils_opt.py
U Sandbox/adamg/ocql/trunk/src/ocql/tests/run.txt
U Sandbox/adamg/ocql/trunk/src/ocql/tests/test_old.py
U Sandbox/adamg/ocql/trunk/src/ocql/tests/test_zope.py
-=-
Modified: Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -5,9 +5,10 @@
$Id$
"""
-
+from collections import deque
from zope.component import adapts
from zope.interface import implements
+from zope.location import locate
#from zope.security.proxy import removeSecurityProxy
from zope.interface import directlyProvidedBy
from zope.interface import directlyProvides
@@ -16,7 +17,74 @@
from ocql.interfaces import IAlgebraObjectHead
from ocql.interfaces import IOptimizedAlgebraObject
+from ocql.rewriter.algebra import *
+def bfsFind(tree):
+ """Breadth-first search to find a Iter Algebra object."""
+ visited = set()
+ queue = [tree]
+ while len(queue):
+ curr_node = queue.pop(0)
+ if isinstance(curr_node, Iter):
+ return curr_node
+ if isinstance(curr_node, BaseAlgebra):
+ visited.add(curr_node)
+ queue.extend(c for c in curr_node.children
+ if c not in visited and c not in queue)
+
+
+def findItrTreePattern(tree):
+ """Checks whole Iter tree pattern exists stating from the Iter algebra object"""
+ iter_obj = bfsFind(tree)
+ if iter_obj is not None:
+ #need to check If and Make objects present
+ if (isinstance(iter_obj.func, Lambda) and isinstance(iter_obj.coll, Make)):
+ if isinstance(iter_obj.func.expr, If):
+ if isinstance(iter_obj.func.expr.cond , Binary):
+ return iter_obj
+ return None
+
+
+def iterPatternMatcher(metadata, tree):
+ """Replaces the identified Iter tree pattern """
+ coll = tree.klass
+ single = tree.func.expr.expr1
+ var = tree.func.var
+ interface = tree.coll.expr.name
+ cond = tree.func.expr.cond.left.name
+ operator = tree.func.expr.cond.op.op
+ if isinstance(tree.func.expr.cond.right, Constant):
+ value = tree.func.expr.cond.right.value
+ elif isinstance(tree.func.expr.cond.right, Identifier):
+ value = tree.func.expr.cond.right.name
+ else:
+ return tree.__parent__
+
+ if not metadata.hasPropertyIndex(interface, cond.split(".")[1]):
+ return tree.__parent__
+
+ #new algebra objects
+ if operator:
+ makeFromIndex = MakeFromIndex(coll , coll, interface,
+ cond.split(".")[1],
+ operator, value=value)
+ else:
+ return tree.__parent__
+
+ newlambda = Lambda(var, single)
+ newTree = Iter(coll, newlambda, makeFromIndex)
+ parent = tree.__parent__
+ if isinstance(parent, Head):
+ return Head(newTree)
+ else:
+ for c in parent.children:
+ if isinstance(c, Iter):
+ del c
+ parent.children.append(newTree)
+ locate(newTree, parent, 'iter')
+ return newTree
+
+
def addMarkerIF(obj, marker):
#obj = removeSecurityProxy(obj)
if not marker.providedBy(obj):
@@ -30,6 +98,13 @@
self.context = context
#self.db = db
- def __call__(self):
+ def __call__(self, metadata):
+ results = findItrTreePattern(self.context.tree)
+
+ if results is not None:
+ alg = iterPatternMatcher(metadata, results)
+ addMarkerIF(alg, IOptimizedAlgebraObject)
+ return alg
+
addMarkerIF(self.context, IOptimizedAlgebraObject)
return self.context
Modified: Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.txt 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer.txt 2008-08-08 09:13:02 UTC (rev 89534)
@@ -1,24 +1,31 @@
+ >>> from zope.interface.verify import verifyObject
+ >>> from ocql.interfaces import IAlgebraOptimizer
>>> from ocql.aoptimizer.aoptimizer import AlgebraOptimizer
>>> from ocql.interfaces import IOptimizedAlgebraObject
+ >>> from ocql.interfaces import IDB
-Currently the optimizer is doing NOTHING, it just returns what it gets.
-(And adds the interface IOptimizedAlgebraObject)
+#Currently the optimizer is doing NOTHING, it just returns what it gets.
+#(And adds the interface IOptimizedAlgebraObject)
>>> class Dummy(object):
- ... def __init__(self, value):
- ... self.value = value
+ ... def __init__(self, tree):
+ ... self.tree = tree
>>> in_=Dummy('foo-bar')
- >>> in_.value
+ >>> in_.tree
'foo-bar'
- >>> out = AlgebraOptimizer(in_)()
+ >>> obj = AlgebraOptimizer(in_)
+ >>> verifyObject(IAlgebraOptimizer, obj)
+ True
+ >>> out = obj(None)
+
>>> print out
<Dummy object at ...>
- >>> out.value
+ >>> out.tree
'foo-bar'
>>> IOptimizedAlgebraObject.providedBy(out)
Copied: Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer_new.txt (from rev 89533, Sandbox/adamg/ocql/branches/optimize-with-index/src/ocql/aoptimizer/aoptimizer_new.txt)
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer_new.txt (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/aoptimizer_new.txt 2008-08-08 09:13:02 UTC (rev 89534)
@@ -0,0 +1,59 @@
+
+Queries in the rewriter.txt are extended to AlgebraOptimization
+
+ >>> from ocql.aoptimizer.aoptimizer import AlgebraOptimizer
+ >>> from ocql.interfaces import IOptimizedAlgebraObject
+ >>> from ocql.parser.queryparser import QueryParser
+ >>> from ocql.qoptimizer.qoptimizer import QueryOptimizer
+ >>> from ocql.rewriter.rewriter import Rewriter
+
+ >>> from ocql.testing.database import TestMetadata
+
+ >>> import ocql.compiler.compiler
+ >>> ocql.compiler.compiler.registerAdapters()
+
+ >>> import ocql.rewriter.rewriter
+ >>> ocql.rewriter.rewriter.registerAdapters()
+
+
+ >>> qo = QueryParser("set [ | 1 ]")(TestMetadata())
+ >>> opt = QueryOptimizer(qo)()
+ >>> alg = Rewriter(opt)()
+ >>> out = AlgebraOptimizer(alg)(TestMetadata())
+ >>> print str(out)
+ Single(<type 'set'>, `1`)
+
+ >>> qo = QueryParser("set [ | 1 ] union set [|2]")(TestMetadata())
+ >>> opt = QueryOptimizer(qo)()
+ >>> alg = Rewriter(opt)()
+ >>> out = AlgebraOptimizer(alg)(TestMetadata())
+ >>> print str(out)
+ Union(<type 'set'>, Single(<type 'set'>, `1`), Single(<type 'set'>, `2`))
+
+ #Differ not implemented
+ #>>> qo = QueryParser("set [ | 1 ] differ set [|2]")(TestMetadata())
+ #>>> opt = QueryOptimizer(qo)()
+ #>>> alg = Rewriter(opt)()
+ #>>> print str(alg)
+ #Union(<type 'set'>, Single(<type 'set'>, `1`), Single(<type 'set'>, `2`))
+
+ >>> qo = QueryParser("set [ i in ICourse | i ]")(TestMetadata())
+ >>> opt = QueryOptimizer(qo)()
+ >>> alg = Rewriter(opt)()
+ >>> out = AlgebraOptimizer(alg)(TestMetadata())
+ >>> print str(out)
+ Iter(<type 'set'>, Lambda i: Single(<type 'set'>, i), Make(<type 'set'>, <type 'set'>, ICourse))
+
+ #>>> qo = QueryParser("set [ c in ICourse; c.credits>3 | c.code ]")(TestMetadata())
+ #>>> opt = QueryOptimizer(qo)()
+ #>>> alg = Rewriter(opt)()
+ #>>> out = AlgebraOptimizer(alg)(TestMetadata())
+ #>>> print str(out)
+ #Iter(<type 'set'>, Lambda c: If(c.credits>`3`, Single(<type 'set'>, c.code), Empty(<type 'set'>)), Make(<type 'set'>, <type 'set'>, ICourse))
+
+ #bag not implemented
+ #>>> qo = QueryParser("size set [ i in ICourse | i ]")(TestMetadata())
+ #>>> opt = QueryOptimizer(qo)()
+ #>>> alg = Rewriter(opt)()
+ #>>> print str(alg)
+ #Iter(<type 'set'>, Lambda i: Single(<type 'set'>, i), Make(<type 'set'>, <type 'set'>, ICourse))
\ No newline at end of file
Modified: Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/tests.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/tests.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/aoptimizer/tests.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -5,8 +5,12 @@
def test_suite():
flags = doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
return unittest.TestSuite((
+# avoid this tests for convenient while adding new implementation to the algebra optimizer
+#need to add aoptimizer.txt
DocFileSuite('aoptimizer.txt',
optionflags=flags),
+ DocFileSuite('aoptimizer_new.txt',
+ optionflags=flags),
))
Modified: Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -102,7 +102,7 @@
self.context.expr is IfCompiler:
if self.context.klass == set:
- return 'reduce(set.union, map(%s,%s), set())' % (
+ return 'reduce(set.union, map(%s, %s), set())' % (
IAlgebraCompiler(self.context.func)(),
IAlgebraCompiler(self.context.coll)())
if self.context.klass == list:
@@ -111,7 +111,7 @@
IAlgebraCompiler(self.context.coll)())
else:
if self.context.klass == set:
- return 'reduce(set.union, map(%s,%s), set())' % (
+ return 'reduce(set.union, map(%s, %s), set())' % (
IAlgebraCompiler(self.context.func)(),
IAlgebraCompiler(self.context.coll)())
if self.context.klass == list:
@@ -179,6 +179,19 @@
IAlgebraCompiler(self.context.expr)())
+class MakeFromIndexCompiler(BaseCompiler):
+ implements(IAlgebraCompiler)
+ adapts(IMakeFromIndex)
+
+ def __call__(self):
+ return '%s(metadata.getFromIndex("%s", "%s", "%s", %s))' % (
+ self.context.coll1.__name__,
+ self.context.expr1,
+ self.context.expr2,
+ self.context.operator,
+ self.context.value)
+
+
class IfCompiler(BaseCompiler):
implements(IAlgebraCompiler)
adapts(IIf)
@@ -256,6 +269,7 @@
provideAdapter(ReduceCompiler)
provideAdapter(RangeCompiler)
provideAdapter(MakeCompiler)
+ provideAdapter(MakeFromIndexCompiler)
provideAdapter(IfCompiler)
provideAdapter(LambdaCompiler)
provideAdapter(ConstantCompiler)
Modified: Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.txt 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/compiler/compiler.txt 2008-08-08 09:13:02 UTC (rev 89534)
@@ -21,7 +21,7 @@
>>> qo = QueryParser("set [ | 1 ]")(metadata)
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
- >>> aopt = AlgebraOptimizer(alg)()
+ >>> aopt = AlgebraOptimizer(alg)(metadata)
>>> run = AlgebraCompiler(aopt)(metadata, alg)
>>> print str(run)
RunnableQuery: set([1])
@@ -30,7 +30,7 @@
>>> qo = QueryParser("list [ | 1 ]")(metadata)
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
- >>> aopt = AlgebraOptimizer(alg)()
+ >>> aopt = AlgebraOptimizer(alg)(metadata)
>>> run = AlgebraCompiler(aopt)(metadata, alg)
>>> print str(run)
RunnableQuery: [1]
@@ -39,7 +39,7 @@
>>> qo = QueryParser("set [ | 1 ] union set [|2]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
- >>> aopt = AlgebraOptimizer(alg)()
+ >>> aopt = AlgebraOptimizer(alg)(metadata)
>>> run = AlgebraCompiler(aopt)(metadata, alg)
>>> print str(run)
RunnableQuery: set.union(set([1]), set([2]))
@@ -48,7 +48,7 @@
>>> qo = QueryParser("list [ | 1 ] union list [|2]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
- >>> aopt = AlgebraOptimizer(alg)()
+ >>> aopt = AlgebraOptimizer(alg)(metadata)
>>> run = AlgebraCompiler(aopt)(metadata, alg)
>>> print str(run)
RunnableQuery: ([1])+([2])
@@ -56,7 +56,7 @@
>>> qo = QueryParser("set [ | 1 ] differ set [|2]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
- >>> aopt = AlgebraOptimizer(alg)()
+ >>> aopt = AlgebraOptimizer(alg)(metadata)
>>> run = AlgebraCompiler(aopt)(metadata, alg)
>>> print str(run)
RunnableQuery: set.differ(set([1]), set([2]))
@@ -64,7 +64,7 @@
>>> qo = QueryParser("list [ | 1 ] differ list [|2]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
- >>> aopt = AlgebraOptimizer(alg)()
+ >>> aopt = AlgebraOptimizer(alg)(metadata)
>>> run = AlgebraCompiler(aopt)(metadata, alg)
>>> print str(run)
RunnableQuery: ([1])-([2])
@@ -73,16 +73,16 @@
>>> qo = QueryParser("set [ i in ICourse | i ]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
- >>> aopt = AlgebraOptimizer(alg)()
+ >>> aopt = AlgebraOptimizer(alg)(metadata)
>>> run = AlgebraCompiler(aopt)(metadata, alg)
>>> print str(run)
- RunnableQuery: reduce(set.union, map(lambda i: set([i]),set(metadata.getAll("ICourse"))), set())
+ RunnableQuery: reduce(set.union, map(lambda i: set([i]), set(metadata.getAll("ICourse"))), set())
>>> metadata = TestMetadata()
>>> qo = QueryParser("list [ i in ICourse | i ]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
- >>> aopt = AlgebraOptimizer(alg)()
+ >>> aopt = AlgebraOptimizer(alg)(metadata)
>>> run = AlgebraCompiler(aopt)(metadata, alg)
>>> print str(run)
RunnableQuery: reduce(operator.add, map(lambda i: [i], list(metadata.getAll("ICourse"))), [])
@@ -98,16 +98,16 @@
>>> qo = QueryParser("set [ c in ICourse | c.code ]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
- >>> aopt = AlgebraOptimizer(alg)()
+ >>> aopt = AlgebraOptimizer(alg)(metadata)
>>> run = AlgebraCompiler(aopt)(metadata, alg)
>>> print str(run)
- RunnableQuery: reduce(set.union, map(lambda c: set([c.code]),set(metadata.getAll("ICourse"))), set())
+ RunnableQuery: reduce(set.union, map(lambda c: set([c.code]), set(metadata.getAll("ICourse"))), set())
>>> metadata = TestMetadata()
>>> qo = QueryParser("list [ c in ICourse | c.code ]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
- >>> aopt = AlgebraOptimizer(alg)()
+ >>> aopt = AlgebraOptimizer(alg)(metadata)
>>> run = AlgebraCompiler(aopt)(metadata, alg)
>>> print str(run)
RunnableQuery: reduce(operator.add, map(lambda c: [c.code], list(metadata.getAll("ICourse"))), [])
Copied: Sandbox/adamg/ocql/trunk/src/ocql/compiler/optimize_index.txt (from rev 89533, Sandbox/adamg/ocql/branches/optimize-with-index/src/ocql/compiler/optimize_index.txt)
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/compiler/optimize_index.txt (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/compiler/optimize_index.txt 2008-08-08 09:13:02 UTC (rev 89534)
@@ -0,0 +1,153 @@
+
+Checking here how a compiled query can be optimized for zope indexes
+
+ >>> from zope.component import provideAdapter
+
+ >>> from ocql.parser.queryparser import QueryParser
+ >>> from ocql.qoptimizer.qoptimizer import QueryOptimizer
+ >>> from ocql.rewriter.rewriter import Rewriter
+ >>> from ocql.aoptimizer.aoptimizer import AlgebraOptimizer
+ >>> from ocql.compiler.compiler import AlgebraCompiler
+ >>> from ocql.database.metadata import Metadata
+
+ >>> provideAdapter(QueryParser)
+ >>> provideAdapter(QueryOptimizer)
+ >>> provideAdapter(Rewriter)
+ >>> provideAdapter(AlgebraOptimizer)
+ >>> provideAdapter(AlgebraCompiler)
+ >>> provideAdapter(Metadata)
+
+ >>> from ocql.engine import OCQLEngine
+
+ >>> import ocql.compiler.compiler
+ >>> ocql.compiler.compiler.registerAdapters()
+
+ >>> import ocql.rewriter.rewriter
+ >>> ocql.rewriter.rewriter.registerAdapters()
+
+ >>> from ocql.testing.utils_opt import setupInterfaces
+ >>> setupInterfaces(None)
+ >>> from ocql.testing.utils_opt import setupCatalog
+ >>> setupCatalog(None)
+
+
+Simple thing:
+
+ #>>> engine = OCQLEngine()
+ #>>> run = engine.compile("set [ | 1 ]")
+ #>>> run
+ #RunnableQuery: set([1])
+ #
+ #>>> result = run.execute()
+ #>>> result
+ #set([1])
+
+
+Let's use the IUnOptimizedClass:
+
+# >>> engine = OCQLEngine()
+# >>> run = engine.compile("set [ i in IUnOptimizedClass | i ]")
+# >>> run
+# RunnableQuery: reduce(set.union, map(lambda i: set([i]), set(metadata.getAll("IUnOptimizedClass"))), set())
+#
+## >>> result = run.execute()
+## >>> result
+## set([UnOpt: 0, UnOpt: 1, UnOpt: 3, UnOpt: 4, UnOpt: 5, UnOpt: 6, UnOpt: 7, UnOpt: 2, UnOpt: 8, UnOpt: 9])
+
+
+IUnOptimizedClass with a filter condition:
+(parser is not working, therefore the complicated query definition)
+
+ >>> from ocql.queryobject.queryobject import *
+ >>> from ocql.interfaces import IDB
+ >>> from ocql.parser.queryparser import SymbolContainer
+
+ >>> metadata = IDB(None)
+ >>> symbols = SymbolContainer()
+ >>> qo = Head(Query(
+ ... metadata, symbols,
+ ... set,
+ ... [
+ ... In(
+ ... metadata, symbols,
+ ... Identifier(metadata,symbols,'i'),
+ ... Identifier(metadata,symbols, 'IUnOptimizedClass')),
+ ... Eq(
+ ... metadata,symbols,
+ ... Identifier(metadata, symbols, 'i.value'),
+ ... Identifier(metadata, symbols, '5'))
+ ... ], Identifier(metadata, symbols, 'i.name')))
+
+
+ >>> engine = OCQLEngine()
+ >>> run = engine.compile(qo)
+ >>> run
+ RunnableQuery:
+ reduce(set.union,
+ map(lambda i: ((i.value==5) and (set([i.name])) or (set())),
+ set(metadata.getAll("IUnOptimizedClass"))), set())
+
+Here is the algebra tree:
+
+ >>> run.alg
+ Iter(<type 'set'>,
+ Lambda i: If(i.value==5, Single(<type 'set'>, i.name), Empty(<type 'set'>)),
+ Make(<type 'set'>, <type 'set'>, IUnOptimizedClass))
+
+Results of the query:
+
+ >>> result = run.execute()
+ >>> result
+ set([u'5'])
+
+
+
+IOptimizedClass with a filter condition:
+(parser is not working, therefore the complicated query definition)
+
+ >>> from ocql.queryobject.queryobject import *
+ >>> from ocql.interfaces import IDB
+ >>> from ocql.parser.queryparser import SymbolContainer
+
+ >>> metadata = IDB(None)
+ >>> symbols = SymbolContainer()
+ >>> qo = Head(Query(
+ ... metadata, symbols,
+ ... set,
+ ... [
+ ... In(
+ ... metadata, symbols,
+ ... Identifier(metadata,symbols,'i'),
+ ... Identifier(metadata,symbols, 'IOptimizedClass')),
+ ... Eq(
+ ... metadata,symbols,
+ ... Identifier(metadata, symbols, 'i.value'),
+ ... Identifier(metadata, symbols, '5'))
+ ... ], Identifier(metadata, symbols, 'i.name')))
+
+
+ >>> engine = OCQLEngine()
+ >>> run = engine.compile(qo)
+ >>> run
+ RunnableQuery:
+ reduce(set.union,
+ map(lambda i: set([i.name]),
+ set(metadata.getFromIndex("IOptimizedClass", "value", "==", 5))), set())
+
+
+
+ >>> result = run.execute()
+ >>> result
+ set([u'5'])
+
+
+
+
+ #>>> engine = OCQLEngine()
+ #>>> run = engine.compile("set [ i in IUnOptimizedClass; i.value==5 | i.name ]")
+ #>>> run
+ #RunnableQuery: reduce(set.union, map(lambda i: set([i]),set(metadata.getAll("IUnOptimizedClass"))), set())
+
+# >>> result = run.execute()
+# >>> result
+# set([UnOpt: 0, UnOpt: 1, UnOpt: 3, UnOpt: 4, UnOpt: 5, UnOpt: 6, UnOpt: 7, UnOpt: 2, UnOpt: 8, UnOpt: 9])
Modified: Sandbox/adamg/ocql/trunk/src/ocql/compiler/runnablequery.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/compiler/runnablequery.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/compiler/runnablequery.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -60,8 +60,8 @@
self.code)
def reanalyze(self):
- optimizedalgebra = IAlgebraOptimizer(self.alg)()
- runnable = IAlgebraCompiler(optimizedalgebra)(self.metadata, self.alg)
+ optimizedalgebra = IAlgebraOptimizer(self.alg)(self.metadata)
+ runnable = IAlgebraCompiler(optimizedalgebra)(self.metadata, optimizedalgebra)
return runnable
def execute(self, debug=False):
Modified: Sandbox/adamg/ocql/trunk/src/ocql/compiler/tests.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/compiler/tests.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/compiler/tests.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -5,6 +5,8 @@
def test_suite():
flags = doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
return unittest.TestSuite((
+ DocFileSuite('optimize_index.txt',
+ optionflags=flags),
DocFileSuite('compiler.txt',
optionflags=flags),
))
Modified: Sandbox/adamg/ocql/trunk/src/ocql/database/metadata.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/database/metadata.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/database/metadata.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -5,8 +5,10 @@
from zope.component import getUtility
from zope.component import getUtilitiesFor
from zope.app.catalog.interfaces import ICatalog
+from zope.app.catalog.field import FieldIndex
from zope.app.intid import IIntIds
-import zc.relation.interfaces
+#import zc.relation.interfaces
+from BTrees.IFBTree import difference
from ocql.interfaces import IDB
from ocql.database.index import AllIndex
@@ -88,13 +90,56 @@
for iname, index in catalog.items():
if isinstance(index, AllIndex):
if index.interface.__name__ == klassname:
- interface = index.interface
results = catalog.apply({iname:(1,1)})
obj_list = [intids.getObject(result) for result in results]
return obj_list
return None
+ def getFromIndex(self, klass, property, operator, value):
+ catalogs = getUtilitiesFor(ICatalog)
+ intids = getUtility(IIntIds)
+ for name, catalog in catalogs:
+ for iname, index in catalog.items():
+ if isinstance(index, FieldIndex) and \
+ index.field_name == property and \
+ index.interface.__name__ == klass:
+ if operator == '==':
+ results = catalog.apply({iname:(value, value)})
+ elif operator == '!=':
+ all = catalog.apply({iname:(None, None)})
+ temp = catalog.apply({iname:(value, value)})
+ results = difference(all, temp)
+ elif operator == '<=':
+ results = catalog.apply({iname:(value, None)})
+ elif operator == '<':
+ lt_eq = catalog.apply({iname:(value, None)})
+ temp = catalog.apply({iname:(value, value)})
+ results = difference(lt_eq, temp)
+ elif operator == '>=':
+ results = catalog.apply({iname:(None, value)})
+ elif operator == '>':
+ gt_eq = catalog.apply({iname:(None, value)})
+ temp = catalog.apply({iname:(value, value)})
+ results = difference(gt_eq, temp)
+
+ obj_list = [intids.getObject(result) for result in results]
+ return obj_list
+ #I could check whether property has an index by hasPropertyIndex.
+ #But by this approach this always returns IF objects
+ return self.getAll(klass)
+
+ def hasPropertyIndex(self, klass, property):
+ catalogs = getUtilitiesFor(ICatalog)
+ for name, catalog in catalogs:
+ for iname, index in catalog.items():
+ if isinstance(index, FieldIndex) and \
+ index.field_name == property and \
+ index.interface.__name__ == klass:
+ return True
+ return False
+
+
def get_class(self, klassname):
"""Returns a MetaType instance for the class."""
return self.classes[klassname]
Modified: Sandbox/adamg/ocql/trunk/src/ocql/engine.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/engine.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/engine.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -17,11 +17,11 @@
from ocql.interfaces import IAlgebraCompiler
from ocql.interfaces import IDB
-from ocql.interfaces import IObjectQuery
from ocql.interfaces import IOptimizedObjectQuery
from ocql.interfaces import IAlgebraObject
from ocql.interfaces import IOptimizedAlgebraObject
from ocql.interfaces import IRunnableQuery
+from ocql.interfaces import IObjectQueryHead
class OCQLEngine:
implements(IEngine)
@@ -32,11 +32,14 @@
def compile(self, query):
#TODO: later use maybe named adapters
metadata = IDB(None)
-
- objectquery = IQueryParser(query)(metadata)
+ if IObjectQueryHead.providedBy(query):
+ objectquery = query
+ else:
+ objectquery = IQueryParser(query)(metadata)
+
optimizedoq = IQueryOptimizer(objectquery)()
algebra = IRewriter(optimizedoq)()
- optimizedalgebra = IAlgebraOptimizer(algebra)()
- runnable = IAlgebraCompiler(optimizedalgebra)(metadata, algebra)
+ optimizedalgebra = IAlgebraOptimizer(algebra)(metadata)
+ runnable = IAlgebraCompiler(optimizedalgebra)(metadata, optimizedalgebra)
- return runnable
\ No newline at end of file
+ return runnable
Deleted: Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -1,651 +0,0 @@
-# -*- coding: UTF-8 -*-
-
-"""Parse a string to Query Object
-
-"""
-
-#TODOs:
-#add metadata into the picture!!!
-#remove shift/reduce conflicts, when possible
-#look after raise "Help"
-#revise according to new grammar
-
-from ply import lex, yacc
-from collections import deque
-from threading import local
-
-from zope.component import adapts
-from zope.component import provideAdapter
-from zope.interface import implements
-
-from ocql.queryobject.queryobject import *
-from ocql.interfaces import IQueryParser
-
-DEBUG = 0
-
-class SymbolContainer:
- def __init__(self):
- self.stack = deque()
- self.stack.append(dict())
-
- def addlevel(self):
- top = self.current()
- new = dict(top)
- self.stack.append(new)
-
- def dellevel(self):
- self.stack.pop()
-
- def current(self):
- return self.stack[-1]
-
-tokens = ('SET', 'LIST', 'COMMA', 'NOT_EQUAL', 'UNION', 'AS', 'EVERY', 'ATMOST', 'LT', 'GT', 'ELLIPSIS', 'BRACKET_R', 'OR', 'PIPE', 'DOT', 'IN', 'LTE', 'SOME', 'AND', 'CBRACKET_L', 'CONSTANT', 'EQUAL', 'GTE', 'ISINSTANCE', 'SEMI_COLON', 'BRACKET_L', 'ASSIGN', 'NOT_ASSIGN', 'FOR', 'CBRACKET_R', 'JUST', 'IDENTIFIER', 'DIFFER', 'LEN', 'BAG', 'SBRACKET_L', 'NOT', 'ATLEAST', 'SBRACKET_R')
-
-precedence = (
- ('left', 'UNION'),
- ('left', 'DIFFER'),
-# ('token', 'SQUAREL'),
-# ('token', 'PIPE'),
-# ('token', 'SQUARER'),
- ('left', 'AND'),
- ('left', 'OR'),
- ('right', 'NOT'),
- #('left', 'COND_OP'),
-# ('left', 'PLUS', 'MINUS'),
-# ('left', 'MUL', 'DIV'),
-# ('token', 'IDENTIFIER'),
-# ('token', 'BRACEL'),
-# ('token', 'BRACER'),
-# ('token', 'CONSTANT'),
-# ('token', 'TYPE'),
-# ('token', 'CURLYL'),
-# ('token', 'CURLYR'),
-# ('token', 'ELLIPSIS'),
- ('left', 'DOT'),
-# ('token', 'COMMA'),
- ('left', 'SEMI_COLON'),
-
- ('left', 'IN'),
- ('left', 'AS'),
-
-# ('token', 'MODIFIER'),
-# ('token', 'QUANTOR'),
-
-# ('left', 'SIZE'),
-)
-
-class Lexer(object):
- tokens = tokens
- t_ignore = ' \t\n\r'
-
- def t_error(self, t):
- print "Illegal character '%s'" % t.value[0]
- t.lexer.skip(1)
-
- def t_UNION(self, t):
- r'union'
- return t
-
- def t_DIFFER(self, t):
- r'differ'
- return t
-
- def t_SET(self, t):
- r'set'
- return t
-
- def t_LIST(self, t):
- r'list'
- return t
-
- def t_BAG(self, t):
- r'bag'
- return t
-
- def t_FOR(self, t):
- r'for'
- return t
-
- def t_LEN(self, t):
- r'len'
- return t
-
- def t_AS(self, t):
- r'as'
- return t
-
- def t_IN(self, t):
- r'in'
- return t
-
- def t_OR(self, t):
- r'or'
- return t
-
- def t_AND(self, t):
- r'and'
- return t
-
- def t_NOT(self, t):
- r'not'
- return t
-
- def t_ISINSTANCE(self, t):
- r'isinstance'
- return t
-
- def t_EVERY(self, t):
- r'every'
- return t
-
- def t_ATMOST(self, t):
- r'atmost'
- return t
-
- def t_ATLEAST(self, t):
- r'atleast'
- return t
-
- def t_SOME(self, t):
- r'some'
- return t
-
- def t_JUST(self, t):
- r'just'
- return t
-
- def t_CONSTANT(self, t):
- r'(\'(\\.|[^\'])*\'|"(\\.|[^"])*"|[0-9]+)'
- return t
-
- def t_IDENTIFIER(self, t):
- r'[a-zA-Z][0-9a-zA-Z_]*'
- return t
-
- def t_COMMA(self, t):
- r','
- return t
-
-#this may be != sign
- def t_NOT_EQUAL(self, t):
- r'~=='
- return t
-
- def t_LT(self, t):
- r'<'
- return t
-
- def t_GT(self, t):
- r'>'
- return t
-
- def t_ELLIPSIS(self, t):
- r'\.\.\.'
- return t
-
- def t_PIPE(self, t):
- r'\|'
- return t
-
- def t_DOT(self, t):
- r'\.'
- return t
-
- def t_MUL(self, t):
- r'\*'
- return t
-
- def t_CBRACKET_L(self, t):
- r'{'
- return t
-
- def t_CBRACKET_R(self, t):
- r'}'
- return t
-
- def t_EQUAL(self, t):
- r'=='
- return t
-
- def t_GTE(self, t):
- r'>='
- return t
-
- def t_LTE(self, t):
- r'<='
- return t
-
- def t_SEMI_COLON(self, t):
- r';'
- return t
-
- def t_BRACKET_L(self, t):
- r'\('
- return t
-
- def t_BRACKET_R(self, t):
- r'\)'
- return t
-
- def t_ASSIGN(self, t):
- r'='
- return t
-
- def t_NOT_ASSIGN(self, t):
- r'~='
- return t
-
-# def t_DIV(self, t):
-# r'/'
-# return t
-
-# def t_PLUS(self, t):
-# r'\+'
-# return t
-
-# def t_MINUS(self, t):
-# r'-'
-# return t
-
- def t_SBRACKET_L(self, t):
- r'\['
- return t
-
- def t_SBRACKET_R(self, t):
- r'\]'
- return t
-
-
-
-class Parser(object):
- tokens = tokens
- precedence = precedence
- metadata = None
- symbols = None
- types = { 'set' : set, 'list': list }
- start = 'expression'
-
- def __init__(self, metadata):
- self.metadata = metadata
- self.symbols = SymbolContainer()
-
- def p_error(self, t):
- print "Syntax error at '%s' (%s)" % (t.value, t.lexpos)
-
- def p_expr_union(self, t):
- r'''expression : expression UNION expression
- '''
- t[0] = Union(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "expression UNION expression" to "expression"', t[0]
-
- def p_expr_differ(self, t):
- r'''expression : expression DIFFER expression
- '''
- t[0] = Differ(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "expression DIFFER expression" to "expression"', t[0]
-
-# def p_expr_3(self, t):
-# r'''expression : collection SBRACKET_L expression SBRACKET_R
-# '''
-# t[0] = Query(self.metadata, self.symbols, t[1], [], t[3])
-# if DEBUG: print 'reducing "collection SBRACKET_L qualifier PIPE expression SBRACKET_R" to "expression"'
-
- def p_expr_query(self, t):
- r'''expression : collection SBRACKET_L qualifier PIPE expression SBRACKET_R
- '''
- t[0] = Query(self.metadata, self.symbols, t[1], t[3], t[5])
- if DEBUG: print 'reducing "collection SBRACKET_L qualifier PIPE expression SBRACKET_R" to "expression"', t[0]
-
-#TODO add a test
- def p_expr_for_query(self, t):
- r'''expression : collection SBRACKET_L qualifier FOR expression SBRACKET_R
- '''
- t[0] = Query(self.metadata, self.symbols, t[1], t[3], t[5])
- if DEBUG: print 'reducing "collection SBRACKET_L qualifier FOR expression SBRACKET_R" to "expression"', t[0]
-
- def p_expr_literal(self, t):
- r'''expression : literal
- '''
- t[0] = t[1]
- if DEBUG: print 'reducing "literal" to "expression"', t[0]
-
- def p_expr_path(self, t):
- r'''expression : path
- '''
- t[0] = t[1]
- if DEBUG: print 'reducing "path" to "expression"', t[0]
-
- def p_expr_call(self, t):
- r'''expression : call
- '''
- t[0] = t[1]
- if DEBUG: print 'reducing "path" to "expression"', t[0]
-
- def p_expr_len(self, t):
- r'''expression : LEN BRACKET_L expression BRACKET_R
- '''
- t[0] = Count(self.metadata, self.symbols, t[3])
- if DEBUG: print 'reducing "LEN BRACKET_L expression BRACKET_R" to "expression"', t[0]
-
- def p_collection_set(self, t):
- r'''collection : SET
- '''
- t[0] = self.types['set']
- if DEBUG: print 'reducing "set" to "collection"', t[0]
-
- def p_collection_list(self, t):
- r'''collection : LIST
- '''
- t[0] = self.types['list']
- if DEBUG: print 'reducing "list" to "collection"', t[0]
-
- def p_collection_bag(self, t):
- r'''collection : BAG
- '''
- raise NotImplementedError('bag')
- if DEBUG: print 'reducing "bag" to "collection"', t[0]
-
- def p_qualifier_null(self, t):
- r'''qualifier :
- '''
- t[0] = []
- if DEBUG: print 'reducing "" to "qualifier"', t[0]
-
- def p_qualifier_generator(self, t):
- r'''qualifier : generator
- '''
- t[0] = [t[1]]
- if DEBUG: print 'reducing "generator" to "qualifier"', t[0]
-
- def p_qualifier_definition(self, t):
- r'''qualifier : definition
- '''
- t[0] = [t[1]]
- if DEBUG: print 'reducing "definition" to "qualifier"', t[0]
-
- def p_qualifier_filter(self, t):
- r'''qualifier : filter
- '''
- t[0] = [t[1]]
- if DEBUG: print 'reducing "filter" to "qualifier"', t[0]
-
- def p_qualifier_qualifier(self, t):
- r'''qualifier : qualifier SEMI_COLON qualifier
- '''
- t[0] = t[0].extend(t[1])
- t[0] = t[0].extend(t[3])
- if DEBUG: print 'reducing "qualifier SEMI_COLON qualifier" to "qualifier"', t[0]
-
-# def p_qualifier_6(self, t):
-# r'''qualifier : expression
-# '''
-# t[0] = t[1]
-# if DEBUG: print 'reducing "expression" to "qualifier"'
-
- def p_generator_in(self, t):
- r'''generator : IDENTIFIER IN expression
- '''
- t[0] = In(self.metadata,
- self.symbols,
- Identifier(self.metadata,
- self.symbols,
- t[1]),
- t[3])
- if DEBUG: print 'reducing "IDENTIFIER IN expression" to "generator"', t[0]
-
- def p_filter_and(self, t):
- r'''filter : filter AND filter
- '''
- t[0] = And(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "filter AND filter" to "filter"', t[0]
-
- def p_filter_or(self, t):
- r'''filter : filter OR filter
- '''
- t[0] = Or(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "filter OR filter" to "filter"', t[0]
-
- def p_filter_not(self, t):
- r'''filter : NOT condition
- '''
- t[0] = Not(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "NOT condition" to "filter"', t[0]
-
- def p_filter_condition(self, t):
- r'''filter : condition
- '''
- t[0] = t[1]
- if DEBUG: print 'reducing "condition" to "filter"', t[0]
-
- def p_condition_filter(self, t):
- r'''condition : BRACKET_L filter BRACKET_R
- '''
- t[0] = t[2]
- if DEBUG: print 'reducing "BRACKET_L filter BRACKET_R" to "condition"', t[0]
-
- def p_condition_assign(self, t):
- r'''condition : quantified ASSIGN quantified
- '''
- raise NotImplementedError('assign')
- if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
-
- def p_condition_not_assign(self, t):
- r'''condition : quantified NOT_ASSIGN quantified
- '''
- raise NotImplementedError('not assign')
- if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
-
- def p_condition_lt(self, t):
- r'''condition : quantified LT quantified
- '''
- t[0] = Lt(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
-
- def p_condition_lte(self, t):
- r'''condition : quantified LTE quantified
- '''
- t[0] = Le(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
-
- def p_condition_gt(self, t):
- r'''condition : quantified GT quantified
- '''
- t[0] = Gt(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
-
- def p_condition_gte(self, t):
- r'''condition : quantified GTE quantified
- '''
- t[0] = Ge(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
-
- def p_condition_equal(self, t):
- r'''condition : quantified EQUAL quantified
- '''
- t[0] = Eq(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
-
- def p_condition_not_equal(self, t):
- r'''condition : quantified NOT_EQUAL quantified
- '''
- t[0] = Ne(self.metadata, self.symbols, t[1], t[3])
- if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
-
- #need to extend this for collection of types
- def p_condition_isinstance(self, t):
- r'''condition : ISINSTANCE BRACKET_L expression COMMA IDENTIFIER BRACKET_R
- '''
- raise NotImplementedError('isinstance')
- if DEBUG: print 'reducing "ISINSTANCE BRACKET_L expression COMMA IDENTIFIER BRACKET_R" to "condition"', t[0]
-
- def p_quantified_expression(self, t):
- r'''quantified : expression
- '''
- t[0] = t[1]
- if DEBUG: print 'reducing "expression" to "quantified"', t[0]
-
- def p_quantified_some(self, t):
- r'''quantified : SOME expression
- '''
- t[0] = Some(self.metadata, self.symbols, t[2])
- if DEBUG: print 'reducing "quantification expression" to "quantified"', t[0]
-
- def p_quantified_just(self, t):
- r'''quantified : JUST expression
- '''
- t[0] = Just(self.metadata, self.symbols, t[2])
- if DEBUG: print 'reducing "quantification expression" to "quantified"', t[0]
-
- def p_quantified_every(self, t):
- r'''quantified : EVERY expression
- '''
- t[0] = Every(self.metadata, self.symbols, t[2])
- if DEBUG: print 'reducing "quantification expression" to "quantified"', t[0]
-
- def p_quantified_atleast(self, t):
- r'''quantified : ATLEAST expression
- '''
- t[0] = Atleast(self.metadata, self.symbols, t[2])
- if DEBUG: print 'reducing "quantification expression" to "quantified"', t[0]
-
- def p_quantified_almost(self, t):
- r'''quantified : ATMOST expression
- '''
- t[0] = Atmost(self.metadata, self.symbols, t[2])
- if DEBUG: print 'reducing "quantification expression" to "quantified"', t[0]
-
- def p_definition_as(self, t):
- r'''definition : IDENTIFIER AS expression
- '''
- #t[0]=''
- if DEBUG: print 'reducing "IDENTIFIER AS expression" to "definition"', t[0]
-
- def p_literal_constant(self, t):
- r'''literal : CONSTANT
- '''
- t[0] = Constant(self.metadata, self.symbols, t[1])
- if DEBUG: print 'reducing "CONSTANT" to "literal"', t[0]
-
- def p_literal_element(self, t):
- r'''literal : collection CBRACKET_L element CBRACKET_R
- '''
- raise NotImplementedError('collection set')
- if DEBUG: print 'reducing "collection CBRACKET_L element CBRACKET_R" to "literal"', t[0]
-
- def p_element_null(self, t):
- r'''element :
- '''
- t[0] = None
- if DEBUG: print 'reducing "" to "element"', t[0]
-
- def p_element_expression(self, t):
- r'''element : expression
- '''
- t[0] = t[1]
- if DEBUG: print 'reducing "expression" to "element"', t[0]
-
-# Why this raise a shift/reduce conflict
-# def p_element_comma(self, t):
-# r'''element : element COMMA element
-# '''
-# raise NotImplementedError('element list')
-# if DEBUG: print 'reducing "element COMMA element" to "element"', t[0]
-
- def p_element_ellipsis(self, t):
- r'''element : expression ELLIPSIS expression
- '''
- raise NotImplementedError('range')
- if DEBUG: print 'reducing "expression ELLIPSIS expression" to "element"', t[0]
-
- def p_path_identifier(self, t):
- r'''path : IDENTIFIER
- '''
- t[0] = Identifier(self.metadata, self.symbols, t[1])
- if DEBUG: print 'reducing "IDENTIFIER" to "path"', t[0]
-
- def p_path_method(self, t):
- r'''path : IDENTIFIER DOT method
- '''
- t[0] = Property(self.metadata, self.symbols, Identifier(self.metadata, self.symbols, t[1]), t[3])
- if DEBUG: print 'reducing "IDENTIFIER DOT method" to "path"', t[0]
-
- def p_method_identifier(self, t):
- r'''method : IDENTIFIER
- '''
- t[0] = Identifier(self.metadata, self.symbols, t[1])
- if DEBUG: print 'reducing "IDENTIFIER" to "method"', t[0]
-
- def p_method_arguments(self, t):
- r'''method : IDENTIFIER BRACKET_L argument_list BRACKET_R
- '''
- raise NotImplementedError('function call')
- if DEBUG: print 'reducing "IDENTIFIER BRACKET_L argument_list BRACKET_R" to "method"', t[0]
-
- def p_argument_list_null(self, t):
- r'''argument_list :
- '''
- t[0] = None
- if DEBUG: print 'reducing "" to "argument_list"', t[0]
-
- def p_argument_list_expression(self, t):
- r'''argument_list : expression
- '''
- t[0] = t[1]
- if DEBUG: print 'reducing "expression" to "argument_list"', t[0]
-
- def p_argument_list_set(self, t):
- r'''argument_list : expression COMMA argument_list
- '''
- t[0]=''
- if DEBUG: print 'reducing "expression COMMA argument_list" to "argument_list"', t[0]
-
- def p_call(self, t):
- r'''call : IDENTIFIER BRACKET_L argument_list BRACKET_R
- '''
- raise NotImplementedError('function call')
- if DEBUG: print 'reducing "IDENTIFIER BRACKET_L argument_list BRACKET_R" to "call"', t[0]
-
-#these are here, to keep lexer and parser instantiation to a minimum possible
-#level because they are quite expensive operations
-#parsers must be thread safe on the other hand!
-LEXER = lex.lex(object=Lexer(), debug=0)
-#PARSERS = local()
-
-def parse(str, metadata):
- lexer = LEXER.clone()
-
- #global PARSERS
- #try:
- # parser = PARSERS.parser
- #
- # try:
- # parser.restart()
- # except AttributeError:
- # pass
- #
- #except AttributeError:
- # parser = yacc.yacc(module = Parser(metadata))
- # PARSERS.parser = parser
-
- try:
- parser = yacc.yacc(module = Parser(metadata))
-
- retval = parser.parse(str, lexer = lexer)
- except Exception, e:
- if DEBUG: print e
- raise
- return retval
-
-class QueryParser(object):
- implements(IQueryParser)
- adapts(basestring)
-
- def __init__(self, context):
- self.context = context
- #self.db = db
-
- def __call__(self, metadata):
- strg = self.context
- tree = parse(strg, metadata)
- return Head(tree)
- #return parse(strg, None)
\ No newline at end of file
Copied: Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py (from rev 89533, Sandbox/adamg/ocql/branches/optimize-with-index/src/ocql/parser/queryparser.py)
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/parser/queryparser.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -0,0 +1,651 @@
+# -*- coding: UTF-8 -*-
+
+"""Parse a string to Query Object
+
+"""
+
+#TODOs:
+#add metadata into the picture!!!
+#remove shift/reduce conflicts, when possible
+#look after raise "Help"
+#revise according to new grammar
+
+from ply import lex, yacc
+from collections import deque
+from threading import local
+
+from zope.component import adapts
+from zope.component import provideAdapter
+from zope.interface import implements
+
+from ocql.queryobject.queryobject import *
+from ocql.interfaces import IQueryParser
+
+DEBUG = 0
+
+class SymbolContainer:
+ def __init__(self):
+ self.stack = deque()
+ self.stack.append(dict())
+
+ def addlevel(self):
+ top = self.current()
+ new = dict(top)
+ self.stack.append(new)
+
+ def dellevel(self):
+ self.stack.pop()
+
+ def current(self):
+ return self.stack[-1]
+
+tokens = ('SET', 'LIST', 'COMMA', 'NOT_EQUAL', 'UNION', 'AS', 'EVERY', 'ATMOST', 'LT', 'GT', 'ELLIPSIS', 'BRACKET_R', 'OR', 'PIPE', 'DOT', 'IN', 'LTE', 'SOME', 'AND', 'CBRACKET_L', 'CONSTANT', 'EQUAL', 'GTE', 'ISINSTANCE', 'SEMI_COLON', 'BRACKET_L', 'ASSIGN', 'NOT_ASSIGN', 'FOR', 'CBRACKET_R', 'JUST', 'IDENTIFIER', 'DIFFER', 'LEN', 'BAG', 'SBRACKET_L', 'NOT', 'ATLEAST', 'SBRACKET_R')
+
+precedence = (
+ ('left', 'UNION'),
+ ('left', 'DIFFER'),
+# ('token', 'SQUAREL'),
+# ('token', 'PIPE'),
+# ('token', 'SQUARER'),
+ ('left', 'AND'),
+ ('left', 'OR'),
+ ('right', 'NOT'),
+ #('left', 'COND_OP'),
+# ('left', 'PLUS', 'MINUS'),
+# ('left', 'MUL', 'DIV'),
+# ('token', 'IDENTIFIER'),
+# ('token', 'BRACEL'),
+# ('token', 'BRACER'),
+# ('token', 'CONSTANT'),
+# ('token', 'TYPE'),
+# ('token', 'CURLYL'),
+# ('token', 'CURLYR'),
+# ('token', 'ELLIPSIS'),
+ ('left', 'DOT'),
+# ('token', 'COMMA'),
+ ('left', 'SEMI_COLON'),
+
+ ('left', 'IN'),
+ ('left', 'AS'),
+
+# ('token', 'MODIFIER'),
+# ('token', 'QUANTOR'),
+
+# ('left', 'SIZE'),
+)
+
+class Lexer(object):
+ tokens = tokens
+ t_ignore = ' \t\n\r'
+
+ def t_error(self, t):
+ print "Illegal character '%s'" % t.value[0]
+ t.lexer.skip(1)
+
+ def t_UNION(self, t):
+ r'union'
+ return t
+
+ def t_DIFFER(self, t):
+ r'differ'
+ return t
+
+ def t_SET(self, t):
+ r'set'
+ return t
+
+ def t_LIST(self, t):
+ r'list'
+ return t
+
+ def t_BAG(self, t):
+ r'bag'
+ return t
+
+ def t_FOR(self, t):
+ r'for'
+ return t
+
+ def t_LEN(self, t):
+ r'len'
+ return t
+
+ def t_AS(self, t):
+ r'as'
+ return t
+
+ def t_IN(self, t):
+ r'in'
+ return t
+
+ def t_OR(self, t):
+ r'or'
+ return t
+
+ def t_AND(self, t):
+ r'and'
+ return t
+
+ def t_NOT(self, t):
+ r'not'
+ return t
+
+ def t_ISINSTANCE(self, t):
+ r'isinstance'
+ return t
+
+ def t_EVERY(self, t):
+ r'every'
+ return t
+
+ def t_ATMOST(self, t):
+ r'atmost'
+ return t
+
+ def t_ATLEAST(self, t):
+ r'atleast'
+ return t
+
+ def t_SOME(self, t):
+ r'some'
+ return t
+
+ def t_JUST(self, t):
+ r'just'
+ return t
+
+ def t_CONSTANT(self, t):
+ r'(\'(\\.|[^\'])*\'|"(\\.|[^"])*"|[0-9]+)'
+ return t
+
+ def t_IDENTIFIER(self, t):
+ r'[a-zA-Z][0-9a-zA-Z_]*'
+ return t
+
+ def t_COMMA(self, t):
+ r','
+ return t
+
+#this may be != sign
+ def t_NOT_EQUAL(self, t):
+ r'~=='
+ return t
+
+ def t_LT(self, t):
+ r'<'
+ return t
+
+ def t_GT(self, t):
+ r'>'
+ return t
+
+ def t_ELLIPSIS(self, t):
+ r'\.\.\.'
+ return t
+
+ def t_PIPE(self, t):
+ r'\|'
+ return t
+
+ def t_DOT(self, t):
+ r'\.'
+ return t
+
+ def t_MUL(self, t):
+ r'\*'
+ return t
+
+ def t_CBRACKET_L(self, t):
+ r'{'
+ return t
+
+ def t_CBRACKET_R(self, t):
+ r'}'
+ return t
+
+ def t_EQUAL(self, t):
+ r'=='
+ return t
+
+ def t_GTE(self, t):
+ r'>='
+ return t
+
+ def t_LTE(self, t):
+ r'<='
+ return t
+
+ def t_SEMI_COLON(self, t):
+ r';'
+ return t
+
+ def t_BRACKET_L(self, t):
+ r'\('
+ return t
+
+ def t_BRACKET_R(self, t):
+ r'\)'
+ return t
+
+ def t_ASSIGN(self, t):
+ r'='
+ return t
+
+ def t_NOT_ASSIGN(self, t):
+ r'~='
+ return t
+
+# def t_DIV(self, t):
+# r'/'
+# return t
+
+# def t_PLUS(self, t):
+# r'\+'
+# return t
+
+# def t_MINUS(self, t):
+# r'-'
+# return t
+
+ def t_SBRACKET_L(self, t):
+ r'\['
+ return t
+
+ def t_SBRACKET_R(self, t):
+ r'\]'
+ return t
+
+
+
+class Parser(object):
+ tokens = tokens
+ precedence = precedence
+ metadata = None
+ symbols = None
+ types = { 'set' : set, 'list': list }
+ start = 'expression'
+
+ def __init__(self, metadata):
+ self.metadata = metadata
+ self.symbols = SymbolContainer()
+
+ def p_error(self, t):
+ print "Syntax error at '%s' (%s)" % (t.value, t.lexpos)
+
+ def p_expr_union(self, t):
+ r'''expression : expression UNION expression
+ '''
+ t[0] = Union(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "expression UNION expression" to "expression"', t[0]
+
+ def p_expr_differ(self, t):
+ r'''expression : expression DIFFER expression
+ '''
+ t[0] = Differ(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "expression DIFFER expression" to "expression"', t[0]
+
+# def p_expr_3(self, t):
+# r'''expression : collection SBRACKET_L expression SBRACKET_R
+# '''
+# t[0] = Query(self.metadata, self.symbols, t[1], [], t[3])
+# if DEBUG: print 'reducing "collection SBRACKET_L qualifier PIPE expression SBRACKET_R" to "expression"'
+
+ def p_expr_query(self, t):
+ r'''expression : collection SBRACKET_L qualifier PIPE expression SBRACKET_R
+ '''
+ t[0] = Query(self.metadata, self.symbols, t[1], t[3], t[5])
+ if DEBUG: print 'reducing "collection SBRACKET_L qualifier PIPE expression SBRACKET_R" to "expression"', t[0]
+
+#TODO add a test
+ def p_expr_for_query(self, t):
+ r'''expression : collection SBRACKET_L qualifier FOR expression SBRACKET_R
+ '''
+ t[0] = Query(self.metadata, self.symbols, t[1], t[3], t[5])
+ if DEBUG: print 'reducing "collection SBRACKET_L qualifier FOR expression SBRACKET_R" to "expression"', t[0]
+
+ def p_expr_literal(self, t):
+ r'''expression : literal
+ '''
+ t[0] = t[1]
+ if DEBUG: print 'reducing "literal" to "expression"', t[0]
+
+ def p_expr_path(self, t):
+ r'''expression : path
+ '''
+ t[0] = t[1]
+ if DEBUG: print 'reducing "path" to "expression"', t[0]
+
+ def p_expr_call(self, t):
+ r'''expression : call
+ '''
+ t[0] = t[1]
+ if DEBUG: print 'reducing "path" to "expression"', t[0]
+
+ def p_expr_len(self, t):
+ r'''expression : LEN BRACKET_L expression BRACKET_R
+ '''
+ t[0] = Count(self.metadata, self.symbols, t[3])
+ if DEBUG: print 'reducing "LEN BRACKET_L expression BRACKET_R" to "expression"', t[0]
+
+ def p_collection_set(self, t):
+ r'''collection : SET
+ '''
+ t[0] = self.types['set']
+ if DEBUG: print 'reducing "set" to "collection"', t[0]
+
+ def p_collection_list(self, t):
+ r'''collection : LIST
+ '''
+ t[0] = self.types['list']
+ if DEBUG: print 'reducing "list" to "collection"', t[0]
+
+ def p_collection_bag(self, t):
+ r'''collection : BAG
+ '''
+ raise NotImplementedError('bag')
+ if DEBUG: print 'reducing "bag" to "collection"', t[0]
+
+ def p_qualifier_null(self, t):
+ r'''qualifier :
+ '''
+ t[0] = []
+ if DEBUG: print 'reducing "" to "qualifier"', t[0]
+
+ def p_qualifier_generator(self, t):
+ r'''qualifier : generator
+ '''
+ t[0] = [t[1]]
+ if DEBUG: print 'reducing "generator" to "qualifier"', t[0]
+
+ def p_qualifier_definition(self, t):
+ r'''qualifier : definition
+ '''
+ t[0] = [t[1]]
+ if DEBUG: print 'reducing "definition" to "qualifier"', t[0]
+
+ def p_qualifier_filter(self, t):
+ r'''qualifier : filter
+ '''
+ t[0] = [t[1]]
+ if DEBUG: print 'reducing "filter" to "qualifier"', t[0]
+
+ def p_qualifier_qualifier(self, t):
+ r'''qualifier : qualifier SEMI_COLON qualifier
+ '''
+ t[0] = t[0].extend(t[1])
+ t[0] = t[0].extend(t[3])
+ if DEBUG: print 'reducing "qualifier SEMI_COLON qualifier" to "qualifier"', t[0]
+
+# def p_qualifier_6(self, t):
+# r'''qualifier : expression
+# '''
+# t[0] = t[1]
+# if DEBUG: print 'reducing "expression" to "qualifier"'
+
+ def p_generator_in(self, t):
+ r'''generator : IDENTIFIER IN expression
+ '''
+ t[0] = In(self.metadata,
+ self.symbols,
+ Identifier(self.metadata,
+ self.symbols,
+ t[1]),
+ t[3])
+ if DEBUG: print 'reducing "IDENTIFIER IN expression" to "generator"', t[0]
+
+ def p_filter_and(self, t):
+ r'''filter : filter AND filter
+ '''
+ t[0] = And(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "filter AND filter" to "filter"', t[0]
+
+ def p_filter_or(self, t):
+ r'''filter : filter OR filter
+ '''
+ t[0] = Or(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "filter OR filter" to "filter"', t[0]
+
+ def p_filter_not(self, t):
+ r'''filter : NOT condition
+ '''
+ t[0] = Not(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "NOT condition" to "filter"', t[0]
+
+ def p_filter_condition(self, t):
+ r'''filter : condition
+ '''
+ t[0] = t[1]
+ if DEBUG: print 'reducing "condition" to "filter"', t[0]
+
+ def p_condition_filter(self, t):
+ r'''condition : BRACKET_L filter BRACKET_R
+ '''
+ t[0] = t[2]
+ if DEBUG: print 'reducing "BRACKET_L filter BRACKET_R" to "condition"', t[0]
+
+ def p_condition_assign(self, t):
+ r'''condition : quantified ASSIGN quantified
+ '''
+ raise NotImplementedError('assign')
+ if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
+
+ def p_condition_not_assign(self, t):
+ r'''condition : quantified NOT_ASSIGN quantified
+ '''
+ raise NotImplementedError('not assign')
+ if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
+
+ def p_condition_lt(self, t):
+ r'''condition : quantified LT quantified
+ '''
+ t[0] = Lt(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
+
+ def p_condition_lte(self, t):
+ r'''condition : quantified LTE quantified
+ '''
+ t[0] = Le(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
+
+ def p_condition_gt(self, t):
+ r'''condition : quantified GT quantified
+ '''
+ t[0] = Gt(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
+
+ def p_condition_gte(self, t):
+ r'''condition : quantified GTE quantified
+ '''
+ t[0] = Ge(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
+
+ def p_condition_equal(self, t):
+ r'''condition : quantified EQUAL quantified
+ '''
+ t[0] = Eq(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
+
+ def p_condition_not_equal(self, t):
+ r'''condition : quantified NOT_EQUAL quantified
+ '''
+ t[0] = Ne(self.metadata, self.symbols, t[1], t[3])
+ if DEBUG: print 'reducing "quantified operator quantified" to "condition"', t[0]
+
+ #need to extend this for collection of types
+ def p_condition_isinstance(self, t):
+ r'''condition : ISINSTANCE BRACKET_L expression COMMA IDENTIFIER BRACKET_R
+ '''
+ raise NotImplementedError('isinstance')
+ if DEBUG: print 'reducing "ISINSTANCE BRACKET_L expression COMMA IDENTIFIER BRACKET_R" to "condition"', t[0]
+
+ def p_quantified_expression(self, t):
+ r'''quantified : expression
+ '''
+ t[0] = t[1]
+ if DEBUG: print 'reducing "expression" to "quantified"', t[0]
+
+ def p_quantified_some(self, t):
+ r'''quantified : SOME expression
+ '''
+ t[0] = Some(self.metadata, self.symbols, t[2])
+ if DEBUG: print 'reducing "quantification expression" to "quantified"', t[0]
+
+ def p_quantified_just(self, t):
+ r'''quantified : JUST expression
+ '''
+ t[0] = Just(self.metadata, self.symbols, t[2])
+ if DEBUG: print 'reducing "quantification expression" to "quantified"', t[0]
+
+ def p_quantified_every(self, t):
+ r'''quantified : EVERY expression
+ '''
+ t[0] = Every(self.metadata, self.symbols, t[2])
+ if DEBUG: print 'reducing "quantification expression" to "quantified"', t[0]
+
+ def p_quantified_atleast(self, t):
+ r'''quantified : ATLEAST expression
+ '''
+ t[0] = Atleast(self.metadata, self.symbols, t[2])
+ if DEBUG: print 'reducing "quantification expression" to "quantified"', t[0]
+
+ def p_quantified_almost(self, t):
+ r'''quantified : ATMOST expression
+ '''
+ t[0] = Atmost(self.metadata, self.symbols, t[2])
+ if DEBUG: print 'reducing "quantification expression" to "quantified"', t[0]
+
+ def p_definition_as(self, t):
+ r'''definition : IDENTIFIER AS expression
+ '''
+ #t[0]=''
+ if DEBUG: print 'reducing "IDENTIFIER AS expression" to "definition"', t[0]
+
+ def p_literal_constant(self, t):
+ r'''literal : CONSTANT
+ '''
+ t[0] = Constant(self.metadata, self.symbols, t[1])
+ if DEBUG: print 'reducing "CONSTANT" to "literal"', t[0]
+
+ def p_literal_element(self, t):
+ r'''literal : collection CBRACKET_L element CBRACKET_R
+ '''
+ raise NotImplementedError('collection set')
+ if DEBUG: print 'reducing "collection CBRACKET_L element CBRACKET_R" to "literal"', t[0]
+
+ def p_element_null(self, t):
+ r'''element :
+ '''
+ t[0] = None
+ if DEBUG: print 'reducing "" to "element"', t[0]
+
+ def p_element_expression(self, t):
+ r'''element : expression
+ '''
+ t[0] = t[1]
+ if DEBUG: print 'reducing "expression" to "element"', t[0]
+
+# Why this raise a shift/reduce conflict
+# def p_element_comma(self, t):
+# r'''element : element COMMA element
+# '''
+# raise NotImplementedError('element list')
+# if DEBUG: print 'reducing "element COMMA element" to "element"', t[0]
+
+ def p_element_ellipsis(self, t):
+ r'''element : expression ELLIPSIS expression
+ '''
+ raise NotImplementedError('range')
+ if DEBUG: print 'reducing "expression ELLIPSIS expression" to "element"', t[0]
+
+ def p_path_identifier(self, t):
+ r'''path : IDENTIFIER
+ '''
+ t[0] = Identifier(self.metadata, self.symbols, t[1])
+ if DEBUG: print 'reducing "IDENTIFIER" to "path"', t[0]
+
+ def p_path_method(self, t):
+ r'''path : IDENTIFIER DOT method
+ '''
+ t[0] = Property(self.metadata, self.symbols, Identifier(self.metadata, self.symbols, t[1]), t[3])
+ if DEBUG: print 'reducing "IDENTIFIER DOT method" to "path"', t[0]
+
+ def p_method_identifier(self, t):
+ r'''method : IDENTIFIER
+ '''
+ t[0] = Identifier(self.metadata, self.symbols, t[1])
+ if DEBUG: print 'reducing "IDENTIFIER" to "method"', t[0]
+
+ def p_method_arguments(self, t):
+ r'''method : IDENTIFIER BRACKET_L argument_list BRACKET_R
+ '''
+ raise NotImplementedError('function call')
+ if DEBUG: print 'reducing "IDENTIFIER BRACKET_L argument_list BRACKET_R" to "method"', t[0]
+
+ def p_argument_list_null(self, t):
+ r'''argument_list :
+ '''
+ t[0] = None
+ if DEBUG: print 'reducing "" to "argument_list"', t[0]
+
+ def p_argument_list_expression(self, t):
+ r'''argument_list : expression
+ '''
+ t[0] = t[1]
+ if DEBUG: print 'reducing "expression" to "argument_list"', t[0]
+
+ def p_argument_list_set(self, t):
+ r'''argument_list : expression COMMA argument_list
+ '''
+ t[0]=''
+ if DEBUG: print 'reducing "expression COMMA argument_list" to "argument_list"', t[0]
+
+ def p_call(self, t):
+ r'''call : IDENTIFIER BRACKET_L argument_list BRACKET_R
+ '''
+ raise NotImplementedError('function call')
+ if DEBUG: print 'reducing "IDENTIFIER BRACKET_L argument_list BRACKET_R" to "call"', t[0]
+
+#these are here, to keep lexer and parser instantiation to a minimum possible
+#level because they are quite expensive operations
+#parsers must be thread safe on the other hand!
+LEXER = lex.lex(object=Lexer(), debug=0)
+#PARSERS = local()
+
+def parse(str, metadata):
+ lexer = LEXER.clone()
+
+ #global PARSERS
+ #try:
+ # parser = PARSERS.parser
+ #
+ # try:
+ # parser.restart()
+ # except AttributeError:
+ # pass
+ #
+ #except AttributeError:
+ # parser = yacc.yacc(module = Parser(metadata))
+ # PARSERS.parser = parser
+
+ try:
+ parser = yacc.yacc(module = Parser(metadata))
+
+ retval = parser.parse(str, lexer = lexer)
+ except Exception, e:
+ if DEBUG: print e
+ raise
+ return retval
+
+class QueryParser(object):
+ implements(IQueryParser)
+ adapts(basestring)
+
+ def __init__(self, context):
+ self.context = context
+ #self.db = db
+
+ def __call__(self, metadata):
+ strg = self.context
+ tree = parse(strg, metadata)
+ return Head(tree)
+ #return parse(strg, None)
\ No newline at end of file
Modified: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/rewriter/algebra.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -16,6 +16,7 @@
from ocql.interfaces import IAlgebraObjectHead
from ocql.rewriter.interfaces import *
from zope.location import Location, locate
+from zope.location.interfaces import ILocation
class Head(Location):
implements(IAlgebraObjectHead)
@@ -33,8 +34,16 @@
class BaseAlgebra(Location):
implements(IAlgebraObject)
- children = []
+ def __init__(self):
+ self.children = []
+
+ def setProp(self, name, value):
+ setattr(self, name, value)
+ if ILocation.providedBy(value):
+ locate(value, self, name)
+ self.children.append(value)
+
def walk(self):
yield self
for child in self.children:
@@ -45,7 +54,8 @@
implements(IEmpty)
def __init__(self, klass):
- self.klass = klass
+ BaseAlgebra.__init__(self)
+ self.setProp('klass', klass)
def __repr__(self):
return 'Empty(%s)'%(self.klass)
@@ -54,110 +64,95 @@
implements(ISingle)
def __init__(self, klass, expr):
- self.klass = klass
- self.expr = expr
- locate(expr, self, 'expr')
- self.children.extend([klass, expr])
+ BaseAlgebra.__init__(self)
+ self.setProp('klass', klass)
+ self.setProp('expr', expr)
def __repr__(self):
- return 'Single(%s,%s)'%(self.klass, self.expr)
+ return 'Single(%s, %s)'%(self.klass, self.expr)
class Union(BaseAlgebra):
implements(IUnion)
def __init__(self, klass, coll1, coll2):
- self.klass=klass
- self.coll1=coll1
- self.coll2=coll2
- locate(coll1, self, 'coll1')
- locate(coll2, self, 'coll2')
- self.children.extend([coll1, coll2])
+ BaseAlgebra.__init__(self)
+ self.setProp('klass', klass)
+ self.setProp('coll1', coll1)
+ self.setProp('coll2', coll2)
def __repr__(self):
- return 'Union(%s,%s,%s)'%(self.klass, self.coll1, self.coll2)
+ return 'Union(%s, %s, %s)' % (self.klass, self.coll1, self.coll2)
class Differ(BaseAlgebra):
implements(IDiffer)
def __init__(self, klass, coll1, coll2):
- self.klass = klass
- self.coll1 = coll1
- self.coll2 = coll2
- locate(coll1, self, 'coll1')
- locate(coll2, self, 'coll2')
- self.children.extend([coll1, coll2])
+ BaseAlgebra.__init__(self)
+ self.setProp('klass', klass)
+ self.setProp('coll1', coll1)
+ self.setProp('coll2', coll2)
def __repr__(self):
- return 'Differ(%s,%s,%s)'%(self.klass, self.coll1, self.coll2)
+ return 'Differ(%s, %s, %s)' % (self.klass, self.coll1, self.coll2)
class Iter(BaseAlgebra):
implements(IIter)
def __init__(self, klass, func, coll):
- self.klass = klass
- self.func = func
- self.coll = coll
- locate(func, self, 'func')
- locate(coll, self, 'coll')
- self.children.extend([func,coll])
+ BaseAlgebra.__init__(self)
+ self.setProp('klass', klass)
+ self.setProp('func', func)
+ self.setProp('coll', coll)
def __repr__(self):
- return "Iter(%s,%s,%s)"%(self.klass, self.func, self.coll)
+ return "Iter(%s, %s, %s)"%(self.klass, self.func, self.coll)
class Select(BaseAlgebra):
implements(ISelect)
def __init__(self, klass, func, coll):
- self.klass = klass
- self.func = func
- self.coll = coll
- locate(func, self, 'func')
- locate(coll, self, 'coll')
- self.children.extend([func,coll])
+ BaseAlgebra.__init__(self)
+ self.setProp('klass', klass)
+ self.setProp('func', func)
+ self.setProp('coll', coll)
def __repr__(self):
- return "Select(%s,%s,%s)"%(self.klass, self.func, self.coll)
+ return "Select(%s, %s, %s)"%(self.klass, self.func, self.coll)
class Reduce(BaseAlgebra):
implements(IReduce)
def __init__(self, klass, expr, func, aggreg, coll):
- self.klass = klass
- self.expr = expr
- self.func = func
- self.aggreg = aggreg
- self.coll = coll
- locate(expr, self, 'expr')
- locate(func, self, 'func')
- locate(aggreg, self, 'aggreg')
- locate(coll, self, 'coll')
- self.children.extend([expr, func, aggreg, coll])
+ BaseAlgebra.__init__(self)
+ self.setProp('klass', klass)
+ self.setProp('expr', expr)
+ self.setProp('func', func)
+ self.setProp('aggreg', aggreg)
+ self.setProp('coll', coll)
def __repr__(self):
- return "Reduce(%s,%s,%s,%s,%s)"%(self.klass, self.expr, self.func, self.aggreg, self.coll)
+ return "Reduce(%s, %s, %s, %s, %s)"%(self.klass, self.expr, self.func, self.aggreg, self.coll)
#class Equal:
# def __init__(self, klass, coll1, coll2):
-# self.klass = klass
-# self.coll1 = coll1
-# self.coll2 = coll2
+# self.setProp('klass', klass)
+# self.setProp('coll1', coll1)
+# self.setProp('coll2', coll2)
#
# def compile(self):
# if self.klass == set:
-# return 'set(filter(%s,%s))' % (self.coll1.compile(),self.coll1.compile())
+# return 'set(filter(%s, %s))' % (self.coll1.compile(),self.coll1.compile())
# if self.klass == list:
-# return 'filter(%s,%s)' % (self.coll1.compile(),self.coll2.compile())
+# return 'filter(%s, %s)' % (self.coll1.compile(),self.coll2.compile())
#
class Range(BaseAlgebra):
implements(IRange)
def __init__(self, klass, start, end):
- self.klass = klass
- self.start = start
- self.end = end
- locate(start, self, 'start')
- locate(end, self, 'end')
- self.children.extend([start, end])
+ BaseAlgebra.__init__(self)
+ self.setProp('klass', klass)
+ self.setProp('start', start)
+ self.setProp('end', end)
#class Index
@@ -165,18 +160,33 @@
implements(IMake)
def __init__(self, coll1, coll2, expr):
- self.expr = expr
- self.coll1 = coll1
- self.coll2 = coll2
- locate(expr, self, 'expr')
-# locate(coll1, self, 'coll1')
-# locate(coll2, self, 'coll2')
- self.children.append(expr)
+ BaseAlgebra.__init__(self)
+ self.setProp('expr', expr)
+ self.setProp('coll1', coll1)
+ self.setProp('coll2', coll2)
def __repr__(self):
- return "Make(%s,%s,%s)" %(self.coll1, self.coll2, self.expr)
+ return "Make(%s, %s, %s)" %(self.coll1, self.coll2, self.expr)
+class MakeFromIndex(BaseAlgebra):
+
+ implements(IMakeFromIndex)
+
+ def __init__(self, coll1, coll2, expr1, expr2, operator, value):
+ BaseAlgebra.__init__(self)
+ self.setProp('expr1', expr1)
+ self.setProp('expr2', expr2)
+ self.setProp('coll1', coll1)
+ self.setProp('coll2', coll2)
+ self.setProp('operator', operator)
+ self.setProp('value', value)
+
+ def __repr__(self):
+ return "MakeFromIndex(%s, %s, %s, %s, %s)" % (
+ self.coll1, self.coll2, self.expr1, self.expr2, self.value)
+
+
#class And:
#class Being:
@@ -184,16 +194,13 @@
implements(IIf)
def __init__(self, cond, expr1, expr2):
- self.cond = cond
- self.expr1 = expr1
- self.expr2 = expr2
- locate(cond, self, 'cond')
- locate(expr1, self, 'expr1')
- locate(expr2, self, 'expr2')
- self.children.extend([cond, expr1, expr2])
+ BaseAlgebra.__init__(self)
+ self.setProp('cond', cond)
+ self.setProp('expr1', expr1)
+ self.setProp('expr2', expr2)
def __repr__(self):
- return "If(%s,%s,%s)" % (self.cond, self.expr1, self.expr2)
+ return "If(%s, %s, %s)" % (self.cond, self.expr1, self.expr2)
#
#
@@ -202,10 +209,9 @@
implements(ILambda)
def __init__(self, var, expr):
- self.var = var
- self.expr = expr
- locate(expr, self, 'expr')
- self.children.append(expr)
+ BaseAlgebra.__init__(self)
+ self.setProp('var', var)
+ self.setProp('expr', expr)
def __repr__(self):
return "Lambda %s: %s" %(self.var, self.expr)
@@ -214,6 +220,7 @@
implements(IConstant)
def __init__(self, value):
+ BaseAlgebra.__init__(self)
self.value = value
def __repr__(self):
@@ -223,6 +230,7 @@
implements(IIdentifier)
def __init__(self, name):
+ BaseAlgebra.__init__(self)
self.name=name
def __repr__(self):
@@ -232,12 +240,10 @@
implements(IBinary)
def __init__(self, left, op, right):
- self.left = left
- self.op = op
- self.right = right
- locate(left, self, 'left')
- locate(right, self, 'right')
- self.children.extend([left, right])
+ BaseAlgebra.__init__(self)
+ self.setProp('left', left)
+ self.setProp('op', op)
+ self.setProp('right', right)
def __repr__(self):
return "%s%s%s" % (self.left, self.op.op, self.right)
@@ -246,6 +252,7 @@
implements(IOperator)
def __init__(self, op):
+ BaseAlgebra.__init__(self)
self.op = op
def __repr__(self):
Modified: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/interfaces.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/rewriter/interfaces.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/rewriter/interfaces.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -79,6 +79,17 @@
coll1 = Attribute('first collection')
coll2 = Attribute('second collection')
+class IMakeFromIndex(IAlgebraObject):
+ """Objects providing this interface represent the
+ MakeFromIndex Algebra object
+ """
+ expr1 = Attribute('expression1')
+ expr2 = Attribute('expression2')
+ coll1 = Attribute('first collection')
+ coll2 = Attribute('second collection')
+ operator = Attribute('operator')
+ value = Attribute('boundary value of the query')
+
class IIf(IAlgebraObject):
"""Objects providing this interface represent the
If Algebra object
Modified: Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.txt 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/rewriter/rewriter.txt 2008-08-08 09:13:02 UTC (rev 89534)
@@ -20,43 +20,43 @@
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
>>> print str(alg)
- Single(<type 'set'>,`1`)
+ Single(<type 'set'>, `1`)
>>> qo = QueryParser("list [ | 1 ]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
>>> print str(alg)
- Single(<type 'list'>,`1`)
+ Single(<type 'list'>, `1`)
>>> qo = QueryParser("set [ | 1 ] union set [|2]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
>>> print str(alg)
- Union(<type 'set'>,Single(<type 'set'>,`1`),Single(<type 'set'>,`2`))
+ Union(<type 'set'>, Single(<type 'set'>, `1`), Single(<type 'set'>, `2`))
>>> qo = QueryParser("list [ | 1 ] union list [|2]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
>>> print str(alg)
- Union(<type 'list'>,Single(<type 'list'>,`1`),Single(<type 'list'>,`2`))
+ Union(<type 'list'>, Single(<type 'list'>, `1`), Single(<type 'list'>, `2`))
>>> qo = QueryParser("set [ | 1 ] differ set [|2]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
>>> print str(alg)
- Differ(<type 'set'>,Single(<type 'set'>,`1`),Single(<type 'set'>,`2`))
+ Differ(<type 'set'>, Single(<type 'set'>, `1`), Single(<type 'set'>, `2`))
>>> qo = QueryParser("list [ | 1 ] differ list [|2]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
>>> print str(alg)
- Differ(<type 'list'>,Single(<type 'list'>,`1`),Single(<type 'list'>,`2`))
+ Differ(<type 'list'>, Single(<type 'list'>, `1`), Single(<type 'list'>, `2`))
>>> qo = QueryParser("set [ i in ICourse | i ]")(TestMetadata())
>>> opt = QueryOptimizer(qo)()
>>> alg = Rewriter(opt)()
>>> print str(alg)
- Iter(<type 'set'>,Lambda i: Single(<type 'set'>,i),Make(<type 'set'>,<type 'set'>,ICourse))
+ Iter(<type 'set'>, Lambda i: Single(<type 'set'>, i), Make(<type 'set'>, <type 'set'>, ICourse))
# >>> qo = QueryParser("list [ i in ICourse | i ]")(TestMetadata())
# >>> opt = QueryOptimizer(qo)()
@@ -64,9 +64,16 @@
# >>> print str(alg)
# Iter(<type 'list'>,Lambda i: Single(<type 'list'>,i),Make(<type 'list'>,<type 'list'>,ICourse))
+ #>>> qo = QueryParser("set [ c in ICourse; c.credits>3 | c.code ]")(TestMetadata())
+ #>>> opt = QueryOptimizer(qo)()
+ #>>> alg = Rewriter(opt)()
+ #>>> print str(alg)
+ #Iter(<type 'set'>, Lambda c: If(c.credits>`3`, Single(<type 'set'>, c.code), Empty(<type 'set'>)), Make(<type 'set'>, <type 'set'>, ICourse))
+
+
#bag not implemented
#>>> qo = QueryParser("size set [ i in ICourse | i ]")(TestMetadata())
#>>> opt = QueryOptimizer(qo)()
#>>> alg = Rewriter(opt)()
#>>> print str(alg)
- #Iter(<type 'set'>,Lambda i: Single(<type 'set'>,i),Make(<type 'set'>,<type 'set'>,ICourse))
\ No newline at end of file
+ #Iter(<type 'set'>, Lambda i: Single(<type 'set'>, i), Make(<type 'set'>, <type 'set'>, ICourse))
Modified: Sandbox/adamg/ocql/trunk/src/ocql/testing/database.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/testing/database.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/testing/database.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -130,9 +130,4 @@
return x
def get_class(self, name):
- return self.classes[name]
-
- #def get_collection_type(self, name):
- # klass = self.get_class(name)
- # rv = klass.get_collection_type()
- # return rv
\ No newline at end of file
+ return self.classes[name]
\ No newline at end of file
Modified: Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/interfaces.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/interfaces.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/interfaces.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -36,8 +36,8 @@
"""A Student object"""
name = TextLine(title=u"Student Name")
+ country = Attribute('student country')
-
class IMentor(Interface):
"""A Mentor object"""
@@ -54,13 +54,13 @@
containers(".IGsoc")
+#class IProjectRelation(Interface):
+# mentor = Attribute('assigned mentor for the project')
+# project = Attribute('mentoring project')
+#
+#
+
class IOrganizationContainer(IContainer):
"""Organization is also a container for projects, students and mentors"""
- contains(".IProject", ".IStudent", ".IMentor")
-
-#class IProjectRelation(Interface):
-# mentor = Attribute('assigned mentor for the project')
-# project = Attribute('mentoring project')
-#
-#
\ No newline at end of file
+ contains(".IProject", ".IStudent", ".IMentor")
\ No newline at end of file
Modified: Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/project.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/project.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/project.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -5,6 +5,13 @@
from ocql.testing.sample.interfaces import IProject
+#class ProjectRelation(object):
+# implements(IProjectRelation)
+#
+# def __init__(self, mentor, project):
+# self.mentor = mentor
+# self.project = project
+
class Project(persistent.Persistent):
"""A simple implementation of a Project .
@@ -31,12 +38,4 @@
name = u''
def __repr__(self):
- return "%s <%s>" % (self.__class__.__name__, self.name)
-
-
-#class ProjectRelation(object):
-# implements(IProjectRelation)
-#
-# def __init__(self, mentor, project):
-# self.mentor = mentor
-# self.project = project
+ return "%s <%s>" % (self.__class__.__name__, self.name)
\ No newline at end of file
Modified: Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/student.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/student.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/testing/sample/student.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -1,6 +1,6 @@
# -*- coding: UTF-8 -*-
from zope.interface import implements
-from zope.interface import Interface
+from zope.interface import Interface, Attribute
import persistent
from ocql.testing.sample.interfaces import IStudent
@@ -26,6 +26,7 @@
implements(IStudent)
name = u''
+ country = None
def __repr__(self):
return "%s <%s>" % (self.__class__.__name__, self.name)
Modified: Sandbox/adamg/ocql/trunk/src/ocql/testing/stubs.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/testing/stubs.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/testing/stubs.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -77,7 +77,7 @@
self.context = context
#self.db = db
- def __call__(self):
+ def __call__(self, metadata):
return AlgebraOptimized()
class AlgebraCompiler(object):
Modified: Sandbox/adamg/ocql/trunk/src/ocql/testing/utils.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/testing/utils.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/testing/utils.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -11,6 +11,7 @@
from zope.app.catalog.catalog import Catalog
from zope.app.catalog.interfaces import ICatalog
from zope.app.catalog.field import FieldIndex
+from zope.app.catalog.attribute import AttributeIndex
from ocql.database.index import AllIndex
from zope.app.intid import IntIds
@@ -27,10 +28,10 @@
from ocql.testing.sample.project import Project
from ocql.testing.sample.student import Student
from ocql.testing.sample.organization import Organization
-
-import zc.relation.catalog
-import zc.relation.interfaces
-import zc.relation.queryfactory
+
+#import zc.relation.catalog
+#import zc.relation.interfaces
+#import zc.relation.queryfactory
import BTrees
#_obj = {}
@@ -70,6 +71,7 @@
cat['proj_descr'] = FieldIndex('description', IProject)
cat['student_name'] = FieldIndex('name', IStudent)
+ cat['student_country'] = FieldIndex('country', IStudent)
cat['mentor_name'] = FieldIndex('name', IMentor)
@@ -91,16 +93,19 @@
s1 = Student()
s1.name = u"Charith"
+ s1.country = "Sri Lanka"
id = intids.register(s1)
cat.index_doc(id, s1)
s2 = Student()
s2.name = u"Jane"
+ s2.country = "USA"
id = intids.register(s2)
cat.index_doc(id, s2)
s3 = Student()
s3.name = u"Ann"
+ s3.country = "Hungary"
id = intids.register(s3)
cat.index_doc(id, s3)
@@ -108,7 +113,7 @@
o1.name = u"Zope.org"
id = intids.register(o1)
cat.index_doc(id, o1)
-
+
# cat2 = zc.relation.catalog.Catalog(dumpRelation, loadRelation)
# cat2.addValueIndex(IProjectRelation['project'], dumpObj, loadObj, btree=BTrees.family32.OO)
# cat2.addValueIndex(IProjectRelation['mentor'], dumpObj, loadObj, btree=BTrees.family32.OO)
@@ -135,12 +140,4 @@
for r in results:
obj = intids.getObject(r)
- print obj
-
-# rel_mentor = cat.apply({'all_mentors':(1,1)})
-#
-# for r in rel_mentor:
-# obj = intids.getObject(r)
-# for p in cat2.findValueTokens('project',query(mentor=obj)):
-# print p.name
-#
\ No newline at end of file
+ print obj
\ No newline at end of file
Copied: Sandbox/adamg/ocql/trunk/src/ocql/testing/utils_opt.py (from rev 89533, Sandbox/adamg/ocql/branches/optimize-with-index/src/ocql/testing/utils_opt.py)
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/testing/utils_opt.py (rev 0)
+++ Sandbox/adamg/ocql/trunk/src/ocql/testing/utils_opt.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -0,0 +1,123 @@
+# -*- coding: UTF-8 -*-
+
+"""Utilities for testing support
+
+$Id$
+"""
+
+from zope import interface, component
+from zope.component.interface import provideInterface
+
+from zope.schema import Text, TextLine, Int
+
+from zope.app.catalog.catalog import Catalog
+from zope.app.catalog.interfaces import ICatalog
+from zope.app.catalog.field import FieldIndex
+from ocql.database.index import AllIndex
+
+from zope.app.intid import IntIds
+from zope.app.intid.interfaces import IIntIds
+
+from zope.app.keyreference.testing import SimpleKeyReference
+
+from ocql.testing.sample.interfaces import IOrganization
+from ocql.testing.sample.interfaces import IProject
+from ocql.testing.sample.interfaces import IStudent
+from ocql.testing.sample.interfaces import IMentor
+
+from ocql.testing.sample.mentor import Mentor
+from ocql.testing.sample.project import Project
+from ocql.testing.sample.student import Student
+from ocql.testing.sample.organization import Organization
+
+#import zc.relation.catalog
+#import zc.relation.interfaces
+#import zc.relation.queryfactory
+import BTrees
+
+
+class IOptimizedClass(interface.Interface):
+ name = TextLine(title=u"Name")
+ value = Int(title=u"value")
+
+class IUnOptimizedClass(interface.Interface):
+ name = TextLine(title=u"Name")
+ value = Int(title=u"value")
+
+class IHalfOptimizedClass(interface.Interface):
+ name = TextLine(title=u"Name")
+ valueOpt = Int(title=u"value")
+ valueNoOpt = Int(title=u"value")
+
+class OptimizedClass(object):
+ interface.implements(IOptimizedClass)
+
+ name = u''
+ value = 0
+
+ def __repr__(self):
+ return "Opt: %s" % self.name
+
+class UnOptimizedClass(object):
+ interface.implements(IUnOptimizedClass)
+
+ name = u''
+ value = 0
+
+ def __repr__(self):
+ return "UnOpt: %s" % self.name
+
+class HalfOptimizedClass(object):
+ interface.implements(IHalfOptimizedClass)
+
+ name = u''
+ valueOpt = 0
+ valueNoOpt = 0
+
+ def __repr__(self):
+ return "HalfOpt: %s" % self.name
+
+def setupInterfaces(test):
+ provideInterface('', IOptimizedClass)
+ provideInterface('', IUnOptimizedClass)
+ provideInterface('', IHalfOptimizedClass)
+
+def setupCatalog(test, optCount=10, unoptCount=10, halfCount=10):
+ intids = IntIds()
+ component.provideUtility(intids, IIntIds)
+ component.provideAdapter(SimpleKeyReference)
+ cat = Catalog()
+
+ cat['opt_name'] = FieldIndex('name', IOptimizedClass)
+ cat['opt_value'] = FieldIndex('value', IOptimizedClass)
+
+ cat['half_name'] = FieldIndex('name', IHalfOptimizedClass)
+ cat['half_valueOpt'] = FieldIndex('value', IHalfOptimizedClass)
+
+ cat['all_opt'] = AllIndex(IOptimizedClass)
+ cat['all_unopt'] = AllIndex(IUnOptimizedClass)
+ cat['all_half'] = AllIndex(IHalfOptimizedClass)
+
+ for i in range(optCount):
+ o = OptimizedClass()
+ o.value = i
+ o.name = unicode(i)
+ id = intids.register(o)
+ cat.index_doc(id, o)
+
+ for i in range(unoptCount):
+ o = UnOptimizedClass()
+ o.value = i
+ o.name = unicode(i)
+ id = intids.register(o)
+ cat.index_doc(id, o)
+
+ for i in range(halfCount):
+ o = HalfOptimizedClass()
+ o.valueOpt = i
+ o.valueNoOpt = i
+ o.name = unicode(i)
+ id = intids.register(o)
+ cat.index_doc(id, o)
+
+ component.provideUtility(cat, ICatalog, name='foo-catalog')
Modified: Sandbox/adamg/ocql/trunk/src/ocql/tests/run.txt
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/tests/run.txt 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/tests/run.txt 2008-08-08 09:13:02 UTC (rev 89534)
@@ -46,8 +46,8 @@
RunnableQuery: set.union(set([1]), set([2]))
>>> result = run.execute()
- >>> result
- set([1, 2])
+ >>> sorted(list(result))
+ [1, 2]
>>> type(result)
<type 'set'>
@@ -57,11 +57,11 @@
>>> engine = OCQLEngine()
>>> run = engine.compile("set [ i in ICourse | i ]")
>>> run
- RunnableQuery: reduce(set.union, map(lambda i: set([i]),set(metadata.getAll("ICourse"))), set())
+ RunnableQuery: reduce(set.union, map(lambda i: set([i]), set(metadata.getAll("ICourse"))), set())
>>> result = run.execute()
- >>> result
- set([Course <C1>, Course <C2>, Course <C3>])
+ >>> sorted(list(result), key=lambda i: i.code)
+ [Course <C1>, Course <C2>, Course <C3>]
>>> type(result)
<type 'set'>
@@ -71,15 +71,19 @@
>>> engine = OCQLEngine()
>>> run = engine.compile("set [ c in ICourse | c.code ]")
>>> run
- RunnableQuery: reduce(set.union, map(lambda c: set([c.code]),set(metadata.getAll("ICourse"))), set())
+ RunnableQuery: reduce(set.union, map(lambda c: set([c.code]), set(metadata.getAll("ICourse"))), set())
>>> result = run.execute()
- >>> result
- set(['C3', 'C2', 'C1'])
+ >>> type(result)
+ <type 'set'>
+ >>> len(result)
+ 3
+ >>> sorted(list(result))
+ ['C1', 'C2', 'C3']
>>> type(result)
<type 'set'>
>>> run = run.reanalyze()
- >>> run.execute()
- set(['C3', 'C2', 'C1'])
\ No newline at end of file
+ >>> sorted(list(run.execute()))
+ ['C1', 'C2', 'C3']
\ No newline at end of file
Modified: Sandbox/adamg/ocql/trunk/src/ocql/tests/test_old.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/tests/test_old.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/tests/test_old.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -166,6 +166,9 @@
Constant(metadata, symbols,'3')),
] ,Identifier(metadata, symbols, 'c.code') ))
+ #from pub.dbgpclient import brk; brk('172.16.144.39')
+
+
self.doit(query, qo, set([]))
Modified: Sandbox/adamg/ocql/trunk/src/ocql/tests/test_zope.py
===================================================================
--- Sandbox/adamg/ocql/trunk/src/ocql/tests/test_zope.py 2008-08-08 09:04:59 UTC (rev 89533)
+++ Sandbox/adamg/ocql/trunk/src/ocql/tests/test_zope.py 2008-08-08 09:13:02 UTC (rev 89534)
@@ -147,6 +147,30 @@
self.doit(query, qo, set(["Save the world"]))
+ symbols = SymbolContainer()
+ #
+ # Filtering --one result using optimization
+ #
+ # set [ c in IStudent , c.country="USA" | c.name]
+ #
+ query = "[c in IStudent , c.country=USA | c.name]"
+ qo = Head(Query(
+ metadata, symbols,
+ set,
+ [
+ In(
+ metadata, symbols,
+ Identifier(metadata,symbols,'c'),
+ Identifier(metadata,symbols, 'IStudent')),
+ Eq(
+ metadata,symbols,
+ Identifier(metadata, symbols, 'c.country'),
+ Identifier(metadata, symbols, '"USA"'))
+ ], Identifier(metadata, symbols, 'c.name')))
+
+ self.doit(query, qo, set([metadata.getFromIndex('IStudent', 'country','==', 'USA')[0].name]))
+
+
def test_suite():
flags = doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
return unittest.TestSuite((
More information about the Checkins
mailing list