@@ -752,32 +752,52 @@ def _build_file_query(self, **kwargs):
752752 for name , val in filters .items ():
753753 tag_alias = aliased (Tag )
754754
755- if isinstance (val , (list , tuple )) and len (val ) == 1 :
756- val = val [0 ]
755+ val_list = list (listify (val )) if val is not None else [None ]
756+ if not val_list :
757+ continue
758+
759+ if Query .OPTIONAL in val_list :
760+ continue
757761
762+ none = required = False
763+ if None in val_list :
764+ none = True
765+ val_list .remove (None )
766+ if Query .NONE in val_list :
767+ none = True
768+ val_list .remove (Query .NONE )
769+ if Query .REQUIRED in val_list :
770+ required = True
771+ val_list .remove (Query .REQUIRED )
772+
773+ if none and required :
774+ # Always true, apply no filter
775+ continue
776+
777+ # Baseline, use join, start accumulating clauses
758778 join_method = query .join
779+ val_clauses = []
759780
760- if val is None or val == Query .NONE :
781+ # NONE and REQUIRED get special treatment
782+ if none :
761783 join_method = query .outerjoin
762- val_clause = tag_alias ._value .is_ (None )
763- elif val == Query .OPTIONAL :
764- continue
765- elif val == Query .ANY :
766- val_clause = tag_alias ._value .isnot (None )
767- elif regex :
768- if isinstance (val , (list , tuple )):
769- val_clause = sa .or_ (* [
770- tag_alias ._value .op ('REGEXP' )(str (v ))
771- for v in val
772- ])
773- else :
774- val_clause = tag_alias ._value .op ('REGEXP' )(str (val ))
775- else :
776- vals = listify (val )
777- if isinstance (vals [0 ], int ):
778- val_clause = cast (tag_alias ._value , sa .Integer ).in_ (vals )
779- else :
780- val_clause = tag_alias ._value .in_ (vals )
784+ val_clauses .append (tag_alias ._value .is_ (None ))
785+ if required :
786+ val_clauses .append (tag_alias ._value .isnot (None ))
787+
788+ # Any remaining values
789+ if regex :
790+ val_clauses .extend ([tag_alias ._value .op ('REGEXP' )(str (v ))
791+ for v in val_list ])
792+ elif val_list :
793+ _value = tag_alias ._value
794+ if isinstance (val_list [0 ], int ):
795+ _value = cast (tag_alias ._value , sa .Integer )
796+
797+ val_clauses .append (_value .in_ (val_list ))
798+
799+ # Looking for intersection with list of vals, so use OR
800+ val_clause = sa .or_ (* val_clauses ) if len (val_clauses ) > 1 else val_clauses [0 ]
781801
782802 query = join_method (
783803 tag_alias ,
0 commit comments