All of the INTERSECTs can just be WHERE clauses.

This commit is contained in:
voussoir 2018-04-04 22:08:08 -07:00
parent c0df14db62
commit 028a8cb2ef
2 changed files with 18 additions and 26 deletions

View file

@ -530,7 +530,7 @@ class PDBPhotoMixin:
} }
yield parameters yield parameters
photo_tag_rel_intersections = searchhelpers.photo_tag_rel_intersections( photo_tag_rel_exist_clauses = searchhelpers.photo_tag_rel_exist_clauses(
tag_musts, tag_musts,
tag_mays, tag_mays,
tag_forbids, tag_forbids,
@ -594,17 +594,10 @@ class PDBPhotoMixin:
for (column, value) in maximums.items(): for (column, value) in maximums.items():
wheres.append(column + ' <= ' + str(value)) wheres.append(column + ' <= ' + str(value))
# In order to use ORDER BY RANDOM(), we must place all of the intersect if photo_tag_rel_exist_clauses:
# tag searches into a subquery. If we simply try to do wheres.extend(photo_tag_rel_exist_clauses)
# SELECT * ... INTERSECT SELECT * ... ORDER BY RANDOM()
# we get an error that random is not a column. But placing all of the query = ['SELECT * FROM photos']
# selects into a named subquery fixes that.
query = ['SELECT * FROM']
if photo_tag_rel_intersections:
intersections = '(%s) photos' % '\nINTERSECT\n'.join(photo_tag_rel_intersections)
query.append(intersections)
else:
query.append('photos')
if wheres: if wheres:
wheres = 'WHERE ' + ' AND '.join(wheres) wheres = 'WHERE ' + ' AND '.join(wheres)

View file

@ -358,37 +358,36 @@ def normalize_tag_expression(expression):
return expression return expression
INTERSECT_FORMAT = ''' EXIST_FORMAT = '''
SELECT * FROM photos WHERE {operator} ( {operator} (
SELECT 1 FROM photo_tag_rel WHERE photos.id == photo_tag_rel.photoid SELECT 1 FROM photo_tag_rel WHERE photos.id == photo_tag_rel.photoid
AND tagid IN {tagset} AND tagid IN {tagset}
) )
'''.strip() '''.strip()
def photo_tag_rel_intersections(tag_musts, tag_mays, tag_forbids): def photo_tag_rel_exist_clauses(tag_musts, tag_mays, tag_forbids):
(tag_musts, tag_mays, tag_forbids) = expand_mmf( (tag_musts, tag_mays, tag_forbids) = expand_mmf(
tag_musts, tag_musts,
tag_mays, tag_mays,
tag_forbids, tag_forbids,
) )
intersections = [] clauses = []
for tag_must_group in tag_musts: for tag_must_group in tag_musts:
intersections.append( ('EXISTS', tag_must_group) ) clauses.append( ('EXISTS', tag_must_group) )
if tag_mays: if tag_mays:
intersections.append( ('EXISTS', tag_mays) ) clauses.append( ('EXISTS', tag_mays) )
if tag_forbids: if tag_forbids:
intersections.append( ('NOT EXISTS', tag_forbids) ) clauses.append( ('NOT EXISTS', tag_forbids) )
intersections = [ clauses = [
#(operator, helpers.sql_listify([tag.id for tag in tagset] + [""]))
(operator, helpers.sql_listify(tag.id for tag in tagset)) (operator, helpers.sql_listify(tag.id for tag in tagset))
for (operator, tagset) in intersections for (operator, tagset) in clauses
] ]
intersections = [ clauses = [
INTERSECT_FORMAT.format(operator=operator, tagset=tagset) EXIST_FORMAT.format(operator=operator, tagset=tagset)
for (operator, tagset) in intersections for (operator, tagset) in clauses
] ]
return intersections return clauses
def normalize_tagset(photodb, tags, warning_bag=None): def normalize_tagset(photodb, tags, warning_bag=None):
if not tags: if not tags: