diff --git a/.hgtags b/.hgtags
index 583427b3646cf7c07756769f5b098b1fa4169d58_LmhndGFncw==..446e99609442ee5baa2933c3e466891e98498da4_LmhndGFncw== 100644
--- a/.hgtags
+++ b/.hgtags
@@ -43,3 +43,6 @@
 7dd29e42751ebebae4b50126dfb2071d9b2e8de1 rql-debian-version-0.23.0-1
 5cb31b7a463ea8fcc56da4e768648a2f818ec0ee rql-version-0.24.0
 4f8562728585d53053e914171180e623e73ac235 rql-debian-version-0.24.0-1
+4025f1f02d1da65d26eada37708409984942c432 oldstable
+3d59f6b1cbb90278f3b4374dce36b6e31c7e9884 rql-version-0.25.0
+360a6c3a48393f8d5353198d45fbcf25f9ef5369 rql-debian-version-0.25.0-1
diff --git a/ChangeLog b/ChangeLog
index 583427b3646cf7c07756769f5b098b1fa4169d58_Q2hhbmdlTG9n..446e99609442ee5baa2933c3e466891e98498da4_Q2hhbmdlTG9n 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,13 @@
 ChangeLog for RQL
 =================
 
+2010-03-16  --  0.25.0
+    * depends on logilab-database
+
+    * raise BadRQLQuery when using optional on attribute relation
+
+
+
 2010-02-10  --  0.24.0
     * update to yams 0.27 api
 
diff --git a/DEPENDS b/DEPENDS
deleted file mode 100644
index 583427b3646cf7c07756769f5b098b1fa4169d58_REVQRU5EUw==..0000000000000000000000000000000000000000
--- a/DEPENDS
+++ /dev/null
@@ -1,2 +0,0 @@
-python-logilab-common
-python-constraint (>= 0.2.7)
diff --git a/__pkginfo__.py b/__pkginfo__.py
index 583427b3646cf7c07756769f5b098b1fa4169d58_X19wa2dpbmZvX18ucHk=..446e99609442ee5baa2933c3e466891e98498da4_X19wa2dpbmZvX18ucHk= 100644
--- a/__pkginfo__.py
+++ b/__pkginfo__.py
@@ -8,7 +8,7 @@
 __docformat__ = "restructuredtext en"
 
 modname = "rql"
-numversion = (0, 24, 0)
+numversion = (0, 25, 0)
 version = '.'.join(str(num) for num in numversion)
 
 license = 'LGPL'
diff --git a/analyze.py b/analyze.py
index 583427b3646cf7c07756769f5b098b1fa4169d58_YW5hbHl6ZS5weQ==..446e99609442ee5baa2933c3e466891e98498da4_YW5hbHl6ZS5weQ== 100644
--- a/analyze.py
+++ b/analyze.py
@@ -7,8 +7,6 @@
 __docformat__ = "restructuredtext en"
 
 from cStringIO import StringIO
-import warnings
-warnings.filterwarnings(action='ignore', module='logilab.constraint.propagation')
 
 from rql import TypeResolverException, nodes
 from pprint import pprint
@@ -20,6 +18,8 @@
     import rql_solve
 except ImportError:
     rql_solve = None
+    import warnings
+    warnings.filterwarnings(action='ignore', module='logilab.constraint.propagation')
     from logilab.constraint import Repository, Solver, fd
 
     # Gecode solver not available
diff --git a/debian/changelog b/debian/changelog
index 583427b3646cf7c07756769f5b098b1fa4169d58_ZGViaWFuL2NoYW5nZWxvZw==..446e99609442ee5baa2933c3e466891e98498da4_ZGViaWFuL2NoYW5nZWxvZw== 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+rql (0.25.0-1) unstable; urgency=low
+
+  * new upstream release
+
+ -- Sylvain Thénault <sylvain.thenault@logilab.fr>  Tue, 16 Mar 2010 13:41:03 +0100
+
 rql (0.24.0-1) unstable; urgency=low
 
   * new upstream release
diff --git a/debian/control b/debian/control
index 583427b3646cf7c07756769f5b098b1fa4169d58_ZGViaWFuL2NvbnRyb2w=..446e99609442ee5baa2933c3e466891e98498da4_ZGViaWFuL2NvbnRyb2w= 100644
--- a/debian/control
+++ b/debian/control
@@ -12,7 +12,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
+Depends: ${python:Depends}, ${misc:Depends}, ${shlibs:Depends}, python-logilab-common (>= 0.35.3-1), yapps2-runtime, python-logilab-database
 Provides: ${python:Provides}
 Description: relationship query language (RQL) utilities
  A library providing the base utilities to handle RQL queries,
diff --git a/stcheck.py b/stcheck.py
index 583427b3646cf7c07756769f5b098b1fa4169d58_c3RjaGVjay5weQ==..446e99609442ee5baa2933c3e466891e98498da4_c3RjaGVjay5weQ== 100644
--- a/stcheck.py
+++ b/stcheck.py
@@ -265,8 +265,8 @@
 
     def visit_relation(self, relation, errors):
         if relation.optional and relation.neged():
-                errors.append("can use optional relation under NOT (%s)"
-                              % relation.as_string())
+            errors.append("can use optional relation under NOT (%s)"
+                          % relation.as_string())
         # special case "X identity Y"
         if relation.r_type == 'identity':
             lhs, rhs = relation.children
@@ -280,8 +280,15 @@
                 #assert isinstance(rhs.children[0], Constant)
                 #assert rhs.operator == 'IS', rhs.operator
                 #assert rhs.children[0].type == None
-        elif not relation.r_type in self.schema:
-            errors.append('unknown relation `%s`' % relation.r_type)
+        else:
+            try:
+                rschema = self.schema.rschema(relation.r_type)
+            except KeyError:
+                errors.append('unknown relation `%s`' % relation.r_type)
+            else:
+                if relation.optional and rschema.final:
+                    errors.append("shouldn't use optional on final relation `%s`"
+                                  % relation.r_type)
         try:
             vargraph = relation.stmt.vargraph
             rhsvarname = relation.children[1].children[0].variable.name
diff --git a/utils.py b/utils.py
index 583427b3646cf7c07756769f5b098b1fa4169d58_dXRpbHMucHk=..446e99609442ee5baa2933c3e466891e98498da4_dXRpbHMucHk= 100644
--- a/utils.py
+++ b/utils.py
@@ -52,6 +52,8 @@
                 'LIMIT', 'OFFSET'))
 
 
-from logilab.common.adbh import _GenericAdvFuncHelper, FunctionDescr, \
-    auto_register_function
+from logilab.common.decorators import monkeypatch
+from logilab.database import SQL_FUNCTIONS_REGISTRY, FunctionDescr
+
+RQL_FUNCTIONS_REGISTRY = SQL_FUNCTIONS_REGISTRY.copy()
 
@@ -57,3 +59,4 @@
 
-def st_description(cls, funcnode, mainindex, tr):
+@monkeypatch(FunctionDescr)
+def st_description(self, funcnode, mainindex, tr):
     return '%s(%s)' % (
@@ -59,5 +62,5 @@
     return '%s(%s)' % (
-        tr(cls.name),
+        tr(self.name),
         ', '.join(sorted(child.get_description(mainindex, tr)
                          for child in iter_funcnode_variables(funcnode))))
 
@@ -61,8 +64,6 @@
         ', '.join(sorted(child.get_description(mainindex, tr)
                          for child in iter_funcnode_variables(funcnode))))
 
-FunctionDescr.st_description = classmethod(st_description)
-
 def iter_funcnode_variables(funcnode):
     for term in funcnode.children:
         try:
@@ -93,6 +94,4 @@
         node2 = node2.parent
     raise Exception('DUH!')
 
-FUNCTIONS = _GenericAdvFuncHelper.FUNCTIONS.copy()
-
 def register_function(funcdef):
@@ -98,10 +97,6 @@
 def register_function(funcdef):
-    if isinstance(funcdef, basestring) :
-        funcdef = FunctionDescr(funcdef.upper())
-    assert not funcdef.name in FUNCTIONS, \
-           '%s is already registered' % funcdef.name
-    FUNCTIONS[funcdef.name] = funcdef
-    auto_register_function(funcdef)
+    RQL_FUNCTIONS_REGISTRY.register_function(funcdef)
+    SQL_FUNCTIONS_REGISTRY.register_function(funcdef)
 
 def function_description(funcname):
     """Return the description (`FunctionDescription`) for a RQL function."""
@@ -105,7 +100,7 @@
 
 def function_description(funcname):
     """Return the description (`FunctionDescription`) for a RQL function."""
-    return FUNCTIONS[funcname.upper()]
+    return RQL_FUNCTIONS_REGISTRY.get_function(funcname)
 
 def quote(value):
     """Quote a string value."""