@@ -587,6 +587,7 @@ def insert_job_batch_and_get_results(cls, query_set):
587587 # Support for specifying a set of continuous numeric attributes to be presumed for BETWEEN clauses
588588 #
589589 # TODO: add support for DATETIME eg 6/10/2010
590+ @staticmethod
590591 def build_bq_filter_and_params (filters , comb_with = 'AND' , param_suffix = None , with_count_toggle = False ,
591592 field_prefix = None , type_schema = None , case_insens = True , continuous_numerics = None ):
592593 if field_prefix and field_prefix [- 1 ] != "." :
@@ -675,8 +676,13 @@ def build_bq_filter_and_params(filters, comb_with='AND', param_suffix=None, with
675676 is_btw = re .search ('_e?btwe?' , attr .lower ()) is not None
676677 attr_name = attr [:attr .rfind ('_' )] if re .search ('_[gl]te?|_e?btwe?|_eq' , attr ) else attr
677678 if attr_name not in attr_filters :
679+ operator = 'OR'
680+ if 'values' in values :
681+ # This is a fully qualified attribute which needs to have its definition broken out
682+ operator = values ['op' ]
683+ values = values ['values' ]
678684 attr_filters [attr_name ] = {
679- 'OP' : 'OR' ,
685+ 'OP' : operator ,
680686 'filters' : []
681687 }
682688 attr_filter_set = attr_filters [attr_name ]['filters' ]
@@ -820,17 +826,23 @@ def build_bq_filter_and_params(filters, comb_with='AND', param_suffix=None, with
820826 filter_string += " OR " .join (btw_filter_strings )
821827 query_param = query_params
822828 else :
823- # Simple array param
824- query_param ['parameterType' ]['type' ] = "ARRAY"
825- query_param ['parameterType' ]['arrayType' ] = {
826- 'type' : parameter_type
827- }
828- query_param ['parameterValue' ] = {
829- 'arrayValues' : [{'value' : x .lower () if parameter_type == 'STRING' else x } for x in values ]}
830-
831- clause_base = "%s IN UNNEST(@{})" % ("LOWER({}{})" if parameter_type == "STRING" else "{}{}" )
832- filter_string += clause_base .format ('' if not field_prefix else field_prefix , attr ,
833- param_name )
829+ if operator == 'AND' and len (values ) > 1 :
830+ # If an operator is to be AND'd with more than one value we must make an intersection statement
831+ # on the higher-level entity (i.e. select for studies which have series containing both values)
832+ # That cannot be performed here, as this is only a clause builder
833+ logger .warning ("[WARNING] Multiple-value AND clauses require an intersection statement!" )
834+ else :
835+ # Simple array param
836+ query_param ['parameterType' ]['type' ] = "ARRAY"
837+ query_param ['parameterType' ]['arrayType' ] = {
838+ 'type' : parameter_type
839+ }
840+ query_param ['parameterValue' ] = {
841+ 'arrayValues' : [{'value' : x .lower () if parameter_type == 'STRING' else x } for x in values ]}
842+
843+ clause_base = "%s IN UNNEST(@{})" % ("LOWER({}{})" if parameter_type == "STRING" else "{}{}" )
844+ filter_string += clause_base .format ('' if not field_prefix else field_prefix , attr ,
845+ param_name )
834846
835847 if with_count_toggle :
836848 filter_string = "({}) OR @{}_filtering = 'not_filtering'" .format (filter_string , param_name )
0 commit comments