Commit 4b37cb22 authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

Use alias in group_by_expression and order_by_expression.

It is useful when use select_expression in inner query and use
group_by_expression or order_by_expression in outer query.
parent 05efe1ba
...@@ -80,10 +80,10 @@ class TestI18NSearch(ERP5TypeTestCase): ...@@ -80,10 +80,10 @@ class TestI18NSearch(ERP5TypeTestCase):
self.assertEqual(result[0].getPath(), self.person1.getPath()) self.assertEqual(result[0].getPath(), self.person1.getPath())
# check sort on fulltext column # check sort on fulltext column
self.assertFalse('ORDER BY\n MATCH' in self.portal.portal_catalog(SearchableText='Faure', sort_on=(('SearchableText', 'ascending'),), src__=1)) self.assertTrue('ORDER BY\n `full_text`.`SearchableText` ASC' in self.portal.portal_catalog(SearchableText='Faure', sort_on=(('SearchableText', 'ascending'),), src__=1))
# check sort on fulltext search score # check sort on fulltext search score
self.assertTrue('ORDER BY\n MATCH' in self.portal.portal_catalog(SearchableText='Faure', sort_on=(('SearchableText__score__', 'ascending'),), src__=1)) self.assertTrue('ORDER BY\n SearchableText__score__ ASC' in self.portal.portal_catalog(SearchableText='Faure', sort_on=(('SearchableText__score__', 'ascending'),), src__=1))
def test_catalog_full_text_title(self): def test_catalog_full_text_title(self):
# check if 'é' == 'e' collation works # check if 'é' == 'e' collation works
...@@ -108,18 +108,23 @@ class TestI18NSearch(ERP5TypeTestCase): ...@@ -108,18 +108,23 @@ class TestI18NSearch(ERP5TypeTestCase):
self.assertEqual(result[0].getPath(), self.person3.getPath()) self.assertEqual(result[0].getPath(), self.person3.getPath())
# check sort on fulltext column # check sort on fulltext column
self.assertFalse('ORDER BY\n MATCH' in self.portal.portal_catalog(**{ self.assertFalse('ORDER BY\n title__score__ ASC' in self.portal.portal_catalog(**{
'catalog_full_text.title':'Faure', 'catalog_full_text.title':'Faure',
'sort_on':(('catalog_full_text.title', 'ascending'),), 'sort_on':(('catalog_full_text.title', 'ascending'),),
'src__':1 'src__':1
})) }))
# check sort on fulltext search score # check sort on fulltext search score
self.assertFalse('ORDER BY\n MATCH' in self.portal.portal_catalog(**{ self.assertFalse('ORDER BY\n title__score__' in self.portal.portal_catalog(**{
'catalog_full_text.title':'Faure', 'catalog_full_text.title':'Faure',
'sort_on':(('catalog_full_text.title__score__', 'ascending'),), 'sort_on':(('catalog_full_text.title__score__', 'ascending'),),
'src__':1 'src__':1
})) }))
self.assertTrue('ORDER BY\n title__score__' in self.portal.portal_catalog(**{
'catalog_full_text.title':'Faure',
'sort_on':(('title__score__', 'ascending'),),
'src__':1
}))
@expectedFailure @expectedFailure
def test_full_text_title(self): def test_full_text_title(self):
...@@ -148,10 +153,10 @@ class TestI18NSearch(ERP5TypeTestCase): ...@@ -148,10 +153,10 @@ class TestI18NSearch(ERP5TypeTestCase):
self.assertTrue('MATCH' in self.portal.portal_catalog(destination_title='Faure', src__=1)) self.assertTrue('MATCH' in self.portal.portal_catalog(destination_title='Faure', src__=1))
# check sort on fulltext column # check sort on fulltext column
self.assertFalse('ORDER BY\n MATCH' in self.portal.portal_catalog(title='Faure', sort_on=(('title', 'ascending'),), src__=1)) self.assertTrue('ORDER BY\n `catalog`.`title` ASC' in self.portal.portal_catalog(title='Faure', sort_on=(('title', 'ascending'),), src__=1))
# check sort on fulltext search score # check sort on fulltext search score
self.assertTrue('ORDER BY\n MATCH' in self.portal.portal_catalog(title='Faure', sort_on=(('title__score__', 'ascending'),), src__=1)) self.assertTrue('ORDER BY\n title__score__' in self.portal.portal_catalog(title='Faure', sort_on=(('title__score__', 'ascending'),), src__=1))
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
......
...@@ -133,6 +133,8 @@ class SQLExpression(object): ...@@ -133,6 +133,8 @@ class SQLExpression(object):
warnings.warn("Providing a 'from_expression' is deprecated.", warnings.warn("Providing a 'from_expression' is deprecated.",
DeprecationWarning) DeprecationWarning)
self.from_expression = from_expression self.from_expression = from_expression
self._select_dict = self._getSelectDict()[0]
self._reversed_select_dict = {y: x for x, y in self._select_dict.iteritems()}
def getTableAliasDict(self): def getTableAliasDict(self):
""" """
...@@ -239,6 +241,7 @@ class SQLExpression(object): ...@@ -239,6 +241,7 @@ class SQLExpression(object):
if column.endswith('__score__') and column not in order_by_dict: if column.endswith('__score__') and column not in order_by_dict:
continue continue
expression = conflictSafeGet(order_by_dict, column, str(column)) expression = conflictSafeGet(order_by_dict, column, str(column))
expression = self._reversed_select_dict.get(expression, expression)
if cast not in (None, ''): if cast not in (None, ''):
expression = 'CAST(%s AS %s)' % (expression, cast) expression = 'CAST(%s AS %s)' % (expression, cast)
if direction is not None: if direction is not None:
...@@ -304,7 +307,7 @@ class SQLExpression(object): ...@@ -304,7 +307,7 @@ class SQLExpression(object):
If there are nested SQLExpression, it merges (union of sets) them with If there are nested SQLExpression, it merges (union of sets) them with
local value. local value.
""" """
result = set(self.group_by_list) result = {self._reversed_select_dict.get(x, x) for x in self.group_by_list}
for sql_expression in self.sql_expression_list: for sql_expression in self.sql_expression_list:
result.update(sql_expression.getGroupByset()) result.update(sql_expression.getGroupByset())
return result return result
...@@ -363,7 +366,7 @@ class SQLExpression(object): ...@@ -363,7 +366,7 @@ class SQLExpression(object):
checks that they don't alias different columns with the same name. If checks that they don't alias different columns with the same name. If
they do, it raises a ValueError. they do, it raises a ValueError.
""" """
return self._getSelectDict()[0] return self._select_dict
def getSelectExpression(self): def getSelectExpression(self):
""" """
......
...@@ -728,27 +728,27 @@ class TestSQLCatalog(ERP5TypeTestCase): ...@@ -728,27 +728,27 @@ class TestSQLCatalog(ERP5TypeTestCase):
order_by_expression = sql_expression.getOrderByExpression() order_by_expression = sql_expression.getOrderByExpression()
self.assertNotEqual(order_by_expression, '') self.assertNotEqual(order_by_expression, '')
# ... and not sort by relevance # ... and not sort by relevance
self.assertFalse('MATCH' in order_by_expression, order_by_expression) self.assertEqual('`foo`.`fulltext`', order_by_expression)
# order_by_list on fulltext column + '__score__, resulting "ORDER BY" must be non-empty. # order_by_list on fulltext column + '__score__, resulting "ORDER BY" must be non-empty.
sql_expression = self.asSQLExpression({'fulltext': 'foo', sql_expression = self.asSQLExpression({'fulltext': 'foo',
'order_by_list': [('fulltext__score__', ), ]}) 'order_by_list': [('fulltext__score__', ), ]})
order_by_expression = sql_expression.getOrderByExpression() order_by_expression = sql_expression.getOrderByExpression()
self.assertNotEqual(order_by_expression, '') self.assertNotEqual(order_by_expression, '')
# ... and must sort by relevance # ... and must sort by relevance
self.assertTrue('MATCH' in order_by_expression, order_by_expression) self.assertEqual('fulltext__score__', order_by_expression)
# ordering on fulltext column with sort order specified must preserve # ordering on fulltext column with sort order specified must preserve
# sorting by relevance. # sorting by relevance.
for direction in ('ASC', 'DESC'): for direction in ('ASC', 'DESC'):
sql_expression = self.asSQLExpression({'fulltext': 'foo', sql_expression = self.asSQLExpression({'fulltext': 'foo',
'order_by_list': [('fulltext__score__', direction), ]}) 'order_by_list': [('fulltext__score__', direction), ]})
order_by_expression = sql_expression.getOrderByExpression() order_by_expression = sql_expression.getOrderByExpression()
self.assertTrue('MATCH' in order_by_expression, (order_by_expression, direction)) self.assertEqual('fulltext__score__ %s' % direction, order_by_expression)
# Providing a None cast should work too # Providing a None cast should work too
for direction in ('ASC', 'DESC'): for direction in ('ASC', 'DESC'):
sql_expression = self.asSQLExpression({'fulltext': 'foo', sql_expression = self.asSQLExpression({'fulltext': 'foo',
'order_by_list': [('fulltext__score__', direction, None), ]}) 'order_by_list': [('fulltext__score__', direction, None), ]})
order_by_expression = sql_expression.getOrderByExpression() order_by_expression = sql_expression.getOrderByExpression()
self.assertTrue('MATCH' in order_by_expression, (order_by_expression, direction)) self.assertEqual('fulltext__score__ %s' % direction, order_by_expression)
def test_logicalOperators(self): def test_logicalOperators(self):
self.catalog(ReferenceQuery(ReferenceQuery(operator='=', default='AN ORB'), self.catalog(ReferenceQuery(ReferenceQuery(operator='=', default='AN ORB'),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment