def resolve_condition(cond): """ When conditions have been parsed by the api.event_search module we can end up with conditions that are not valid on the current dataset due to how ap.event_search checks for valid field names without being aware of the dataset. We have the dataset context here, so we need to re-scope conditions to the current dataset. """ index = get_function_index(cond) if index is not None: # IN conditions are detected as a function but aren't really. if cond[index] == "IN": cond[0] = resolve_column(cond[0]) return cond func_args = cond[index + 1] for (i, arg) in enumerate(func_args): # Nested function if isinstance(arg, (list, tuple)): func_args[i] = resolve_condition(arg) else: func_args[i] = resolve_column(arg) cond[index + 1] = func_args return cond # No function name found if isinstance(cond, (list, tuple)) and len(cond): # Condition is [col, operator, value] if isinstance(cond[0], six.string_types) and len(cond) == 3: cond[0] = resolve_column(cond[0]) return cond if isinstance(cond[0], (list, tuple)): if get_function_index(cond[0]) is not None: cond[0] = resolve_condition(cond[0]) return cond else: # Nested conditions return [resolve_condition(item) for item in cond] raise ValueError("Unexpected condition format %s" % cond)
def parse_columns_in_functions(col, context=None, index=None): """ Checks expressions for arguments that should be considered a column while ignoring strings that represent clickhouse function names if col is a list, means the expression has functions and we need to parse for arguments that should be considered column names. Assumptions here: * strings that represent clickhouse function names are always followed by a list or tuple * strings that are quoted with single quotes are used as string literals for CH * otherwise we should attempt to get the snuba column name (or custom tag) """ function_name_index = get_function_index(col) if function_name_index is not None: # if this is non zero, that means there are strings before this index # that should be converted to snuba column names # e.g. ['func1', ['column', 'func2', ['arg1']]] if function_name_index > 0: for i in range(0, function_name_index): if context is not None: context[i] = get_snuba_column_name(col[i]) args = col[function_name_index + 1] # check for nested functions in args if get_function_index(args): # look for columns return parse_columns_in_functions(args, args) # check each argument for column names else: for (i, arg) in enumerate(args): parse_columns_in_functions(arg, args, i) else: # probably a column name if context is not None and index is not None: context[index] = get_snuba_column_name(col)