server/test/unittest_rql2sql.py
changeset 5768 1e73a466aa69
parent 5590 a56eb02f9ce7
child 5811 e77cea9721e7
equal deleted inserted replaced
5766:c397819f2482 5768:1e73a466aa69
    20 import sys
    20 import sys
    21 
    21 
    22 from logilab.common.testlib import TestCase, unittest_main, mock_object
    22 from logilab.common.testlib import TestCase, unittest_main, mock_object
    23 
    23 
    24 from rql import BadRQLQuery
    24 from rql import BadRQLQuery
    25 
       
    26 #from cubicweb.server.sources.native import remove_unused_solutions
       
    27 from cubicweb.server.sources.rql2sql import SQLGenerator, remove_unused_solutions
       
    28 
       
    29 from rql.utils import register_function, FunctionDescr
    25 from rql.utils import register_function, FunctionDescr
       
    26 
       
    27 from cubicweb.devtools import TestServerConfiguration
       
    28 from cubicweb.devtools.repotest import RQLGeneratorTC
       
    29 from cubicweb.server.sources.rql2sql import remove_unused_solutions
       
    30 
       
    31 
    30 # add a dumb registered procedure
    32 # add a dumb registered procedure
    31 class stockproc(FunctionDescr):
    33 class stockproc(FunctionDescr):
    32     supported_backends = ('postgres', 'sqlite', 'mysql')
    34     supported_backends = ('postgres', 'sqlite', 'mysql')
    33 try:
    35 try:
    34     register_function(stockproc)
    36     register_function(stockproc)
    35 except AssertionError, ex:
    37 except AssertionError, ex:
    36     pass # already registered
    38     pass # already registered
    37 
    39 
    38 from cubicweb.devtools import TestServerConfiguration
       
    39 from cubicweb.devtools.repotest import RQLGeneratorTC
       
    40 
    40 
    41 config = TestServerConfiguration('data')
    41 config = TestServerConfiguration('data')
    42 config.bootstrap_cubes()
    42 config.bootstrap_cubes()
    43 schema = config.load_schema()
    43 schema = config.load_schema()
    44 schema['in_state'].inlined = True
    44 schema['in_state'].inlined = True
  1058      '''SELECT rel_is0.eid_from
  1058      '''SELECT rel_is0.eid_from
  1059 FROM is_relation AS rel_is0
  1059 FROM is_relation AS rel_is0
  1060 WHERE rel_is0.eid_to=2'''),
  1060 WHERE rel_is0.eid_to=2'''),
  1061 
  1061 
  1062     ]
  1062     ]
  1063 from logilab.database import get_db_helper
       
  1064 
       
  1065 class CWRQLTC(RQLGeneratorTC):
  1063 class CWRQLTC(RQLGeneratorTC):
  1066     schema = schema
  1064     schema = schema
  1067 
  1065     backend = 'sqlite'
  1068     def test_nonregr_sol(self):
  1066     def test_nonregr_sol(self):
  1069         delete = self.rqlhelper.parse(
  1067         delete = self.rqlhelper.parse(
  1070             'DELETE X read_permission READ_PERMISSIONSUBJECT,X add_permission ADD_PERMISSIONSUBJECT,'
  1068             'DELETE X read_permission READ_PERMISSIONSUBJECT,X add_permission ADD_PERMISSIONSUBJECT,'
  1071             'X in_basket IN_BASKETSUBJECT,X delete_permission DELETE_PERMISSIONSUBJECT,'
  1069             'X in_basket IN_BASKETSUBJECT,X delete_permission DELETE_PERMISSIONSUBJECT,'
  1072             'X update_permission UPDATE_PERMISSIONSUBJECT,'
  1070             'X update_permission UPDATE_PERMISSIONSUBJECT,'
  1088         self.assertEquals(var_sols('ISOBJECT'), delete.defined_vars['ISOBJECT'].stinfo['possibletypes'])
  1086         self.assertEquals(var_sols('ISOBJECT'), delete.defined_vars['ISOBJECT'].stinfo['possibletypes'])
  1089 
  1087 
  1090 
  1088 
  1091 class PostgresSQLGeneratorTC(RQLGeneratorTC):
  1089 class PostgresSQLGeneratorTC(RQLGeneratorTC):
  1092     schema = schema
  1090     schema = schema
  1093 
  1091     backend = 'postgres'
  1094     #capture = True
       
  1095     def setUp(self):
       
  1096         RQLGeneratorTC.setUp(self)
       
  1097         dbhelper = get_db_helper('postgres')
       
  1098         self.o = SQLGenerator(schema, dbhelper)
       
  1099 
  1092 
  1100     def _norm_sql(self, sql):
  1093     def _norm_sql(self, sql):
  1101         return sql.strip()
  1094         return sql.strip()
  1102 
  1095 
  1103     def _check(self, rql, sql, varmap=None, args=None):
  1096     def _check(self, rql, sql, varmap=None, args=None):
  1353 FROM appears AS appears0, cw_Basket AS _X
  1346 FROM appears AS appears0, cw_Basket AS _X
  1354 WHERE appears0.words @@ to_tsquery('default', 'toto&tata') AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu
  1347 WHERE appears0.words @@ to_tsquery('default', 'toto&tata') AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu
  1355 UNION ALL
  1348 UNION ALL
  1356 SELECT _X.cw_eid
  1349 SELECT _X.cw_eid
  1357 FROM appears AS appears0, cw_Folder AS _X
  1350 FROM appears AS appears0, cw_Folder AS _X
  1358 WHERE appears0.words @@ to_tsquery('default', 'toto&tata') AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu
  1351 WHERE appears0.words @@ to_tsquery('default', 'toto&tata') AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu"""),
  1359 """),
       
  1360 
  1352 
  1361             ('Personne X where X has_text %(text)s, X travaille S, S has_text %(text)s',
  1353             ('Personne X where X has_text %(text)s, X travaille S, S has_text %(text)s',
  1362              """SELECT _X.eid
  1354              """SELECT _X.eid
  1363 FROM appears AS appears0, appears AS appears2, entities AS _X, travaille_relation AS rel_travaille1
  1355 FROM appears AS appears0, appears AS appears2, entities AS _X, travaille_relation AS rel_travaille1
  1364 WHERE appears0.words @@ to_tsquery('default', 'hip&hop&momo') AND appears0.uid=_X.eid AND _X.type='Personne' AND _X.eid=rel_travaille1.eid_from AND appears2.uid=rel_travaille1.eid_to AND appears2.words @@ to_tsquery('default', 'hip&hop&momo')"""),
  1356 WHERE appears0.words @@ to_tsquery('default', 'hip&hop&momo') AND appears0.uid=_X.eid AND _X.type='Personne' AND _X.eid=rel_travaille1.eid_from AND appears2.uid=rel_travaille1.eid_to AND appears2.words @@ to_tsquery('default', 'hip&hop&momo')"""),
       
  1357 
       
  1358             ('Any X ORDERBY FTIRANK(X) DESC WHERE X has_text "toto tata"',
       
  1359              """SELECT appears0.uid
       
  1360 FROM appears AS appears0
       
  1361 WHERE appears0.words @@ to_tsquery('default', 'toto&tata')
       
  1362 ORDER BY ts_rank(appears0.words, to_tsquery('default', 'toto&tata'))*appears0.weight DESC"""),
       
  1363 
       
  1364             ('Personne X ORDERBY FTIRANK(X) WHERE X has_text "toto tata"',
       
  1365              """SELECT _X.eid
       
  1366 FROM appears AS appears0, entities AS _X
       
  1367 WHERE appears0.words @@ to_tsquery('default', 'toto&tata') AND appears0.uid=_X.eid AND _X.type='Personne'
       
  1368 ORDER BY ts_rank(appears0.words, to_tsquery('default', 'toto&tata'))*appears0.weight"""),
       
  1369 
       
  1370             ('Personne X ORDERBY FTIRANK(X) WHERE X has_text %(text)s',
       
  1371              """SELECT _X.eid
       
  1372 FROM appears AS appears0, entities AS _X
       
  1373 WHERE appears0.words @@ to_tsquery('default', 'hip&hop&momo') AND appears0.uid=_X.eid AND _X.type='Personne'
       
  1374 ORDER BY ts_rank(appears0.words, to_tsquery('default', 'hip&hop&momo'))*appears0.weight"""),
       
  1375 
       
  1376             ('Any X ORDERBY FTIRANK(X) WHERE X has_text "toto tata", X name "tutu", X is IN (Basket,Folder)',
       
  1377              """SELECT T1.C0 FROM (SELECT _X.cw_eid AS C0, ts_rank(appears0.words, to_tsquery('default', 'toto&tata'))*appears0.weight AS C1
       
  1378 FROM appears AS appears0, cw_Basket AS _X
       
  1379 WHERE appears0.words @@ to_tsquery('default', 'toto&tata') AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu
       
  1380 UNION ALL
       
  1381 SELECT _X.cw_eid AS C0, ts_rank(appears0.words, to_tsquery('default', 'toto&tata'))*appears0.weight AS C1
       
  1382 FROM appears AS appears0, cw_Folder AS _X
       
  1383 WHERE appears0.words @@ to_tsquery('default', 'toto&tata') AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu
       
  1384 ORDER BY 2) AS T1"""),
       
  1385 
       
  1386             ('Personne X ORDERBY FTIRANK(X),FTIRANK(S) WHERE X has_text %(text)s, X travaille S, S has_text %(text)s',
       
  1387              """SELECT _X.eid
       
  1388 FROM appears AS appears0, appears AS appears2, entities AS _X, travaille_relation AS rel_travaille1
       
  1389 WHERE appears0.words @@ to_tsquery('default', 'hip&hop&momo') AND appears0.uid=_X.eid AND _X.type='Personne' AND _X.eid=rel_travaille1.eid_from AND appears2.uid=rel_travaille1.eid_to AND appears2.words @@ to_tsquery('default', 'hip&hop&momo')
       
  1390 ORDER BY ts_rank(appears0.words, to_tsquery('default', 'hip&hop&momo'))*appears0.weight,ts_rank(appears2.words, to_tsquery('default', 'hip&hop&momo'))*appears2.weight"""),
       
  1391 
       
  1392 
       
  1393             ('Any X, FTIRANK(X) WHERE X has_text "toto tata"',
       
  1394              """SELECT appears0.uid, ts_rank(appears0.words, to_tsquery('default', 'toto&tata'))*appears0.weight
       
  1395 FROM appears AS appears0
       
  1396 WHERE appears0.words @@ to_tsquery('default', 'toto&tata')"""),
       
  1397 
  1365             )):
  1398             )):
  1366             yield t
  1399             yield t
  1367 
  1400 
  1368 
  1401 
  1369     def test_from_clause_needed(self):
  1402     def test_from_clause_needed(self):
  1409         finally:
  1442         finally:
  1410             self.o.attr_map.clear()
  1443             self.o.attr_map.clear()
  1411 
  1444 
  1412 
  1445 
  1413 class SqliteSQLGeneratorTC(PostgresSQLGeneratorTC):
  1446 class SqliteSQLGeneratorTC(PostgresSQLGeneratorTC):
  1414 
  1447     backend = 'sqlite'
  1415     def setUp(self):
       
  1416         RQLGeneratorTC.setUp(self)
       
  1417         dbhelper = get_db_helper('sqlite')
       
  1418         self.o = SQLGenerator(schema, dbhelper)
       
  1419 
  1448 
  1420     def _norm_sql(self, sql):
  1449     def _norm_sql(self, sql):
  1421         return sql.strip().replace(' ILIKE ', ' LIKE ')
  1450         return sql.strip().replace(' ILIKE ', ' LIKE ')
  1422 
  1451 
  1423     def test_date_extraction(self):
  1452     def test_date_extraction(self):
  1511 UNION
  1540 UNION
  1512 SELECT DISTINCT _X.cw_eid
  1541 SELECT DISTINCT _X.cw_eid
  1513 FROM appears AS appears0, cw_Folder AS _X
  1542 FROM appears AS appears0, cw_Folder AS _X
  1514 WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('toto', 'tata')) AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu
  1543 WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('toto', 'tata')) AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu
  1515 """),
  1544 """),
       
  1545 
       
  1546             ('Any X ORDERBY FTIRANK(X) WHERE X has_text "toto tata"',
       
  1547              """SELECT DISTINCT appears0.uid
       
  1548 FROM appears AS appears0
       
  1549 WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('toto', 'tata'))"""),
       
  1550 
       
  1551             ('Any X ORDERBY FTIRANK(X) WHERE X has_text "toto tata", X name "tutu", X is IN (Basket,Folder)',
       
  1552              """SELECT DISTINCT _X.cw_eid
       
  1553 FROM appears AS appears0, cw_Basket AS _X
       
  1554 WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('toto', 'tata')) AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu
       
  1555 UNION
       
  1556 SELECT DISTINCT _X.cw_eid
       
  1557 FROM appears AS appears0, cw_Folder AS _X
       
  1558 WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('toto', 'tata')) AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu
       
  1559 """),
       
  1560 
       
  1561             ('Any X, FTIRANK(X) WHERE X has_text "toto tata"',
       
  1562              """SELECT DISTINCT appears0.uid, 1.0
       
  1563 FROM appears AS appears0
       
  1564 WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('toto', 'tata'))"""),
  1516             )):
  1565             )):
  1517             yield t
  1566             yield t
  1518 
  1567 
  1519 
  1568 
  1520 
  1569 
  1521 class MySQLGenerator(PostgresSQLGeneratorTC):
  1570 class MySQLGenerator(PostgresSQLGeneratorTC):
  1522 
  1571     backend = 'mysql'
  1523     def setUp(self):
       
  1524         RQLGeneratorTC.setUp(self)
       
  1525         dbhelper = get_db_helper('mysql')
       
  1526         self.o = SQLGenerator(schema, dbhelper)
       
  1527 
  1572 
  1528     def _norm_sql(self, sql):
  1573     def _norm_sql(self, sql):
  1529         sql = sql.strip().replace(' ILIKE ', ' LIKE ').replace('TRUE', '1').replace('FALSE', '0')
  1574         sql = sql.strip().replace(' ILIKE ', ' LIKE ').replace('TRUE', '1').replace('FALSE', '0')
  1530         newsql = []
  1575         newsql = []
  1531         latest = None
  1576         latest = None