Skip to content

Commit 2c17713

Browse files
committed
Fix searching+sorting for Link properties
Note that this turns off recursive pre-populating the cache in filter_iter, we only pre-populate the top-level element. Otherwise this interacts with searching producing duplicates.
1 parent 324bb0b commit 2c17713

File tree

3 files changed

+30
-28
lines changed

3 files changed

+30
-28
lines changed

roundup/backends/rdbms_common.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,7 +2545,7 @@ def _filter_sql (self, search_matches, filterspec, srt=[], grp=[], retr=0,
25452545
a = self.db.arg
25462546

25472547
# figure the WHERE clause from the filterspec
2548-
mlfilt = 0 # are we joining with Multilink tables?
2548+
use_distinct = False # Do we need a distinct clause?
25492549
sortattr = self._sortattr (group = grp, sort = srt)
25502550
proptree = self._proptree(filterspec, exact_match_spec, sortattr, retr)
25512551
mlseen = 0
@@ -2581,7 +2581,8 @@ def _filter_sql (self, search_matches, filterspec, srt=[], grp=[], retr=0,
25812581
rc = oc = ac = '_%s._%s'%(pln, k)
25822582
if isinstance(propclass, Multilink):
25832583
if 'search' in p.need_for:
2584-
mlfilt = 1
2584+
# if we joining with Multilink tables we need distinct
2585+
use_distinct = True
25852586
tn = propclass.table_name
25862587
nid = propclass.nodeid_name
25872588
lid = propclass.linkid_name
@@ -2672,7 +2673,9 @@ def _filter_sql (self, search_matches, filterspec, srt=[], grp=[], retr=0,
26722673
if p.children:
26732674
if 'sort' not in p.need_for:
26742675
frum.append('_%s as _%s' % (cn, ln))
2675-
where.append('_%s._%s=_%s.id'%(pln, k, ln))
2676+
c = [x for x in p.children if 'search' in x.need_for]
2677+
if c:
2678+
where.append('_%s._%s=_%s.id'%(pln, k, ln))
26762679
if p.has_values:
26772680
if isinstance(v, type([])):
26782681
d = {}
@@ -2835,9 +2838,8 @@ def _filter_sql (self, search_matches, filterspec, srt=[], grp=[], retr=0,
28352838
where = ' where ' + (' and '.join(where))
28362839
else:
28372840
where = ''
2838-
if mlfilt:
2839-
# we're joining tables on the id, so we will get dupes if we
2840-
# don't distinct()
2841+
if use_distinct:
2842+
# Avoid dupes
28412843
cols[0] = 'distinct(_%s.id)'%icn
28422844

28432845
order = []

roundup/hyperdb.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,9 @@ def append(self, name, need_for='search', retr=False):
519519
if name in self.propdict:
520520
pt = self.propdict[name]
521521
pt.need_for[need_for] = True
522-
if retr and isinstance(pt.propclass, Link):
523-
pt.append_retr_props()
522+
# For now we do not recursively retrieve Link properties
523+
#if retr and isinstance(pt.propclass, Link):
524+
# pt.append_retr_props()
524525
return pt
525526
propclass = self.props[name]
526527
cls = None
@@ -538,8 +539,9 @@ def append(self, name, need_for='search', retr=False):
538539
child.need_child_retired = True
539540
self.children.append(child)
540541
self.propdict[name] = child
541-
if retr and isinstance(child.propclass, Link):
542-
child.append_retr_props()
542+
# For now we do not recursively retrieve Link properties
543+
#if retr and isinstance(child.propclass, Link):
544+
# child.append_retr_props()
543545
return child
544546

545547
def append_retr_props(self):
@@ -1566,8 +1568,7 @@ def _proptree(self, filterspec, exact_match_spec={}, sortattr=[],
15661568
"""Build a tree of all transitive properties in the given
15671569
exact_match_spec/filterspec.
15681570
If we retrieve (retr is True) linked items we don't follow
1569-
across multilinks. We also don't follow if the searched value
1570-
can contain NULL values.
1571+
across multilinks or links.
15711572
"""
15721573
proptree = Proptree(self.db, self, '', self.getprops(), retr=retr)
15731574
for exact, spec in enumerate((filterspec, exact_match_spec)):

test/db_test_base.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3658,14 +3658,14 @@ def testFilteringTransitiveLinkCache(self):
36583658
('+','username')]):
36593659
result.append(id)
36603660
nodeid = id
3661-
for x in range(4):
3662-
assert(('user', nodeid) in self.db.cache)
3663-
n = self.db.user.getnode(nodeid)
3664-
for k, v in user_result[nodeid].items():
3665-
ae((k, n[k]), (k, v))
3666-
for k in 'creation', 'activity':
3667-
assert(n[k])
3668-
nodeid = n.supervisor
3661+
# Note in the recent implementation we do not recursively
3662+
# cache results in filter_iter
3663+
assert(('user', nodeid) in self.db.cache)
3664+
n = self.db.user.getnode(nodeid)
3665+
for k, v in user_result[nodeid].items():
3666+
ae((k, n[k]), (k, v))
3667+
for k in 'creation', 'activity':
3668+
assert(n[k])
36693669
self.db.clearCache()
36703670
ae (result, ['8', '9', '10', '6', '7', '1', '3', '2', '4', '5'])
36713671

@@ -3683,14 +3683,13 @@ def testFilteringTransitiveLinkCache(self):
36833683
for k in 'creation', 'activity':
36843684
assert(n[k])
36853685
nodeid = n.assignedto
3686-
for x in range(4):
3687-
assert(('user', nodeid) in self.db.cache)
3688-
n = self.db.user.getnode(nodeid)
3689-
for k, v in user_result[nodeid].items():
3690-
ae((k, n[k]), (k, v))
3691-
for k in 'creation', 'activity':
3692-
assert(n[k])
3693-
nodeid = n.supervisor
3686+
# Note in the recent implementation we do not recursively
3687+
# cache results in filter_iter
3688+
n = self.db.user.getnode(nodeid)
3689+
for k, v in user_result[nodeid].items():
3690+
ae((k, n[k]), (k, v))
3691+
for k in 'creation', 'activity':
3692+
assert(n[k])
36943693
self.db.clearCache()
36953694
ae (result, ['4', '5', '6', '7', '8', '1', '2', '3'])
36963695

0 commit comments

Comments
 (0)