diff --git a/ChangeLog b/ChangeLog index e0f450b12992dd54156e90bb825e0dce5023f488_Q2hhbmdlTG9n..64531b6511838533f4246987d1ce352c14fc851d_Q2hhbmdlTG9n 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,9 @@ ================= -- -* suport != operator for non equality +* support != operator for non equality +* support for CAST function + 2011-01-12 -- 0.28.0 * enhance rewrite_shared_optional so one can specify where the new identity diff --git a/__pkginfo__.py b/__pkginfo__.py index e0f450b12992dd54156e90bb825e0dce5023f488_X19wa2dpbmZvX18ucHk=..64531b6511838533f4246987d1ce352c14fc851d_X19wa2dpbmZvX18ucHk= 100644 --- a/__pkginfo__.py +++ b/__pkginfo__.py @@ -81,7 +81,7 @@ install_requires = [ 'logilab-common >= 0.47.0', - 'logilab-database', + 'logilab-database >= 1.6.0', 'yapps == 2.1.1', # XXX to ensure we don't use the broken pypi version 'constraint', # fallback if the gecode compiled module is missing ] diff --git a/debian/control b/debian/control index e0f450b12992dd54156e90bb825e0dce5023f488_ZGViaWFuL2NvbnRyb2w=..64531b6511838533f4246987d1ce352c14fc851d_ZGViaWFuL2NvbnRyb2w= 100644 --- a/debian/control +++ b/debian/control @@ -11,7 +11,7 @@ Package: python-rql Architecture: any XB-Python-Version: ${python:Versions} -Depends: ${python:Depends}, ${misc:Depends}, ${shlibs:Depends}, python-logilab-common (>= 0.35.3-1), yapps2-runtime, python-logilab-database +Depends: ${python:Depends}, ${misc:Depends}, ${shlibs:Depends}, python-logilab-common (>= 0.35.3-1), yapps2-runtime, python-logilab-database (>= 1.6.0) Conflicts: cubicweb-common (<= 3.8.3) Provides: ${python:Provides} Description: relationship query language (RQL) utilities diff --git a/nodes.py b/nodes.py index e0f450b12992dd54156e90bb825e0dce5023f488_bm9kZXMucHk=..64531b6511838533f4246987d1ce352c14fc851d_bm9kZXMucHk= 100644 --- a/nodes.py +++ b/nodes.py @@ -28,6 +28,8 @@ from datetime import datetime, date, time, timedelta from time import localtime +from logilab.database import DYNAMIC_RTYPE + from rql import CoercionError from rql.base import BaseNode, Node, BinaryNode, LeafNode from rql.utils import (function_description, quote, uquote, build_visitor_stub, @@ -440,12 +442,7 @@ return False rhs = self.children[1] if isinstance(rhs, Comparison): - try: - rhs = rhs.children[0] - except: - print 'opppp', rhs - print rhs.root - raise + rhs = rhs.children[0] # else: relation used in SET OR DELETE selection return ((isinstance(rhs, Constant) and rhs.type == 'etype') or (isinstance(rhs, Function) and rhs.name == 'IN')) @@ -625,7 +622,8 @@ solution is an optional variable/etype mapping """ - rtype = self.descr().rtype + func_descr = self.descr() + rtype = func_descr.rql_return_type(self) if rtype is None: # XXX support one variable ref child try: diff --git a/stcheck.py b/stcheck.py index e0f450b12992dd54156e90bb825e0dce5023f488_c3RjaGVjay5weQ==..64531b6511838533f4246987d1ce352c14fc851d_c3RjaGVjay5weQ== 100644 --- a/stcheck.py +++ b/stcheck.py @@ -455,8 +455,5 @@ def visit_constant(self, constant, state): #assert len(constant.children)==0 if constant.type == 'etype': - if constant.relation().r_type not in ('is', 'is_instance_of'): - msg ='using an entity type in only allowed with "is" relation' - state.error(msg) - if not constant.value in self.schema: + if constant.value not in self.schema: state.error('unknown entity type %s' % constant.value) @@ -462,4 +459,12 @@ state.error('unknown entity type %s' % constant.value) + rel = constant.relation() + if rel is not None: + if rel.r_type not in ('is', 'is_instance_of'): + msg ='using an entity type in only allowed with "is" relation' + state.error(msg) + elif not (isinstance(constant.parent, Function) and + constant.parent.name == 'CAST'): + state.error('Entity types can only be used inside a CAST()') def leave_constant(self, node, state): pass diff --git a/test/unittest_nodes.py b/test/unittest_nodes.py index e0f450b12992dd54156e90bb825e0dce5023f488_dGVzdC91bml0dGVzdF9ub2Rlcy5weQ==..64531b6511838533f4246987d1ce352c14fc851d_dGVzdC91bml0dGVzdF9ub2Rlcy5weQ== 100644 --- a/test/unittest_nodes.py +++ b/test/unittest_nodes.py @@ -564,6 +564,12 @@ tree = sparse('Any X,R,D,Y WHERE X work_for R, R creation_date D, Y connait X') self.assertEqual(tree.get_description(0), [['Person, Student', 'work_for', 'creation_date', 'connait']]) + def test_get_description_cast(self): + tree = sparse('Any CAST(String, Y) WHERE X creation_date Y') + select = tree.children[0] + self.assertEqual(select.selection[0].get_type(), 'String') + self.assertEqual(tree.get_description(0), [['String']]) + class GetNodesFunctionTest(TestCase): def test_known_values_1(self): diff --git a/utils.py b/utils.py index e0f450b12992dd54156e90bb825e0dce5023f488_dXRpbHMucHk=..64531b6511838533f4246987d1ce352c14fc851d_dXRpbHMucHk= 100644 --- a/utils.py +++ b/utils.py @@ -68,7 +68,7 @@ from logilab.common.decorators import monkeypatch -from logilab.database import SQL_FUNCTIONS_REGISTRY, FunctionDescr +from logilab.database import SQL_FUNCTIONS_REGISTRY, FunctionDescr, CAST RQL_FUNCTIONS_REGISTRY = SQL_FUNCTIONS_REGISTRY.copy() @@ -85,6 +85,19 @@ raise BadRQLQuery("backend %s doesn't support function %s" % (backend, self.name)) +@monkeypatch(FunctionDescr) +def rql_return_type(self, funcnode): + return self.rtype + +@monkeypatch(CAST) +def st_description(self, funcnode, mainindex, tr): + return self.rql_return_type(funcnode) + +@monkeypatch(CAST) +def rql_return_type(self, funcnode): + return funcnode.children[0].value + + def iter_funcnode_variables(funcnode): for term in funcnode.children: try: