Search based on tags condition with or condition combiner

In case of more than one tags values in request query with other
condition it was not using separate alias name for artifact_tag table
to join with glare_artifacts table. To rectify this we have created
aliases beforehand and using it updating the tag search condition.

Change-Id: Ic7afe47fcf8f23a694f2c3d99dbdbd7797d506dd
closes-bug: #1765338
This commit is contained in:
Kushal Agrawal 2018-04-29 20:33:52 +05:30
parent 92bc2ad89f
commit 40d57e0893
3 changed files with 31 additions and 4 deletions

View File

@ -265,8 +265,14 @@ def _apply_user_filters(query, basic_conds, tag_conds, prop_conds):
for tag_condition in tag_conds['and']:
query = query.join(models.ArtifactTag, aliased=True).filter(
and_(*tag_condition))
tag_or_queries = []
for tag_condition in tag_conds['or']:
or_queries.append(*tag_condition)
artifact_tag_alias = aliased(models.ArtifactTag)
query = query.join(artifact_tag_alias)
for tag_cond in tag_condition:
tag_cond.left = artifact_tag_alias.value
tag_or_queries.append(and_(*tag_condition))
or_queries.append(and_(*tag_or_queries))
if prop_conds:
for prop_condition in prop_conds['and']:

View File

@ -715,6 +715,21 @@ class TestList(base.TestArtifact):
result = self.get(url=url)['artifacts']
self.assertEqual([], result)
url = '/sample_artifact?name=or:eq:name2&tags-any=or:tag1,tag4' \
'&sort=name:asc'
result = self.get(url=url)['artifacts']
self.assertEqual(4, len(result))
for i in (1, 2, 4):
self.assertIn(art_list[i], result)
self.assertEqual(public_art, result[3])
url = '/sample_artifact?name=or:eq:name2&&tags=or:tag4,tag5' \
'&sort=name:asc'
result = self.get(url=url)['artifacts']
self.assertEqual(2, len(result))
self.assertEqual(art_list[2], result[0])
self.assertEqual(public_art, result[1])
class TestBlobs(base.TestArtifact):
def test_blob_dicts(self):

View File

@ -539,10 +539,16 @@ class TestArtifactList(base.BaseTestArtifactAPI):
for i in (3, 0):
self.assertIn(arts[i], res['artifacts'])
filters = [('name', 'or:in:name4,name1'), ('tags-any', 'or:tag4')]
filters = [('name', 'or:in:name2,name1'), ('tags-any', 'or:tag2,tag5')]
res = self.controller.list(self.req, 'sample_artifact', filters)
self.assertEqual(6, len(res['artifacts']))
for i in (5, 4, 3, 0):
self.assertEqual(4, len(res['artifacts']))
for i in (5, 3, 1, 0):
self.assertIn(arts[i], res['artifacts'])
filters = [('name', 'or:in:name4,name1'), ('tags', 'or:tag1,tag3')]
res = self.controller.list(self.req, 'sample_artifact', filters)
self.assertEqual(3, len(res['artifacts']))
for i in (3, 1, 0):
self.assertIn(arts[i], res['artifacts'])
# Filtering by tags with operators leads to BadRequest