[rql] basic support for regexp-based pattern matching
authorAdrien Di Mascio <Adrien.DiMascio@logilab.fr>
Wed, 27 Apr 2011 12:23:43 +0200
changeset 7257 beea955b45e2
parent 7256 ccd44caeb936
child 7260 2b1dce628d33
[rql] basic support for regexp-based pattern matching
server/sources/rql2sql.py
server/test/unittest_querier.py
server/test/unittest_rql2sql.py
--- a/server/sources/rql2sql.py	Wed Apr 27 11:37:42 2011 +0200
+++ b/server/sources/rql2sql.py	Wed Apr 27 12:23:43 2011 +0200
@@ -1357,6 +1357,8 @@
                 operator = ' LIKE '
             else:
                 operator = ' %s ' % operator
+        elif operator == 'REGEXP':
+            return ' %s' % self.dbhelper.sql_regexp_match_expression(rhs.accept(self))
         elif (operator == '=' and isinstance(rhs, Constant)
               and rhs.eval(self._args) is None):
             if lhs is None:
--- a/server/test/unittest_querier.py	Wed Apr 27 11:37:42 2011 +0200
+++ b/server/test/unittest_querier.py	Wed Apr 27 12:23:43 2011 +0200
@@ -443,6 +443,15 @@
             self.assertEqual(rset.rows[0][0], result)
             self.assertEqual(rset.description, [('Int',)])
 
+    def test_regexp_based_pattern_matching(self):
+        peid1 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
+        peid2 = self.execute("INSERT Personne X: X nom 'cidule'")[0][0]
+        rset = self.execute('Any X WHERE X is Personne, X nom REGEXP "^b"')
+        self.assertEqual(len(rset.rows), 1, rset.rows)
+        self.assertEqual(rset.rows[0][0], peid1)
+        rset = self.execute('Any X WHERE X is Personne, X nom REGEXP "idu"')
+        self.assertEqual(len(rset.rows), 2, rset.rows)
+
     def test_select_aggregat_count(self):
         rset = self.execute('Any COUNT(X)')
         self.assertEqual(len(rset.rows), 1)
--- a/server/test/unittest_rql2sql.py	Wed Apr 27 11:37:42 2011 +0200
+++ b/server/test/unittest_rql2sql.py	Wed Apr 27 12:23:43 2011 +0200
@@ -1336,6 +1336,13 @@
                     '''SELECT CAST(_P.cw_eid AS text)
 FROM cw_Personne AS _P''')
 
+    def test_regexp(self):
+        self._check("Any X WHERE X login REGEXP '[0-9].*'",
+                    '''SELECT _X.cw_eid
+FROM cw_CWUser AS _X
+WHERE _X.cw_login ~ [0-9].*
+''')
+
     def test_parser_parse(self):
         for t in self._parse(PARSER):
             yield t
@@ -1635,6 +1642,9 @@
         for t in self._parse(HAS_TEXT_LG_INDEXER):
             yield t
 
+    def test_regexp(self):
+        self.skipTest('regexp-based pattern matching not implemented in sqlserver')
+
     def test_or_having_fake_terms(self):
         self._check('Any X WHERE X is CWUser, X creation_date D HAVING YEAR(D) = "2010" OR D = NULL',
                     '''SELECT _X.cw_eid
@@ -1748,6 +1758,14 @@
                     '''SELECT MONTH(_P.cw_creation_date)
 FROM cw_Personne AS _P''')
 
+    def test_regexp(self):
+        self._check("Any X WHERE X login REGEXP '[0-9].*'",
+                    '''SELECT _X.cw_eid
+FROM cw_CWUser AS _X
+WHERE _X.cw_login REGEXP [0-9].*
+''')
+
+
     def test_union(self):
         for t in self._parse((
             ('(Any N ORDERBY 1 WHERE X name N, X is State)'
@@ -1893,6 +1911,13 @@
                     '''SELECT CAST(_P.cw_eid AS mediumtext)
 FROM cw_Personne AS _P''')
 
+    def test_regexp(self):
+        self._check("Any X WHERE X login REGEXP '[0-9].*'",
+                    '''SELECT _X.cw_eid
+FROM cw_CWUser AS _X
+WHERE _X.cw_login REGEXP [0-9].*
+''')
+
     def test_from_clause_needed(self):
         queries = [("Any 1 WHERE EXISTS(T is CWGroup, T name 'managers')",
                     '''SELECT 1