def eval_cond(cond, tables): ''' Evaluates a single condition then returns a dict of the filtered indexes of columns involved in the condition :param cond: a single conditional expression :param tables: a dict of tables {tname: tb} :return: a dict {col_name: [index that fulfills condition]} ''' if ' EN ' in cond: col_name, inner_query = cond.split(' EN ', 1) # On filter column by inner query result tname, tb = [(tname, tb) for tname, tb in tables.items() if man.has_col(tb, col_name)][0] col_entries = tb[col_name] return filter_by_query(tname, col_name, # inner query take away the brackets col_entries, inner_query[1:-1], tables) if 'EXISTE ' in cond: inner_query = cond.replace('EXISTE (', '', 1)[:-1] if not exist_condition(inner_query, tables): # if return False, terminate the current query, otherwise continue raise hpr.TerminateQueryError() else: return True clauses = split_clauses(cond) var1, oper, var2 = clauses if oper == 'ENTRE': # filter by range # Get table, assumes unique column name tname, tb = [(tname, tb) for tname, tb in tables.items() if man.has_col(tb, var1)][0] col_entries = tb[var1] start, end = var2.strip(' (').strip(') ').split(' Y ') return filter_by_range(tname, col_entries, int(start), int(end)) else: if man.is_col(tables, var1) and man.is_col(tables, var2): # filter by cols tname1, tb1 = [(tname, tb) for tname, tb in tables.items() if man.has_col(tb, var1)][0] tname2, tb2 = [(tname, tb) for tname, tb in tables.items() if man.has_col(tb, var2)][0] col_entries1 = tb1[var1] col_entries2 = tb2[var2] return filter_by_col(tname1, col_entries1, tname2, col_entries2) elif man.is_col(tables, var1): # filter by val # Get table, assumes unique column name tname, tb = [(tname, tb) for tname, tb in tables.items() if man.has_col(tb, var1)][0] col_entries = tb[var1] return filter_by_val(tname, col_entries, oper, hpr.parse_val(var2)) else: # Get table, assumes unique column name tname, tb = [(tname, tb) for tname, tb in tables.items() if man.has_col(tb, var2)][0] col_entries = tb[var2] return filter_by_val(tname, col_entries, oper, hpr.parse_val(var1))
def filter_grps(line, tb, grouping): ''' Filter out groups that do not meet filter condition before performing column functions on groups in do_col_func_two :param line: a TENIENDO condition without ' TENIENDO ' and '()' :param tb: a dict {col_name: [entries]} :param grouping: a list of [indexes], each sublist is an equivalence class :return: a list of [indexes], each equivalence class meets the condition ''' # split the line into var1, operator, var2 var1, oper, var2 = split_clauses(line) if '(' in var1: col_str = var1 val_str = var2 else: col_str = var2 val_str = var1 # Get the list of function names func_keys = list(eva.FUNC.keys()) col, func = [(strip_func(col_str), func) for func in func_keys if func + '(' in col_str][0] if tb.get(col) is None: raise hpr.InvalidQueryError('Table do not have column: {0}'.format(col)) # Get the list of entry values of each group after performing function values = [eva.FUNC[func](man.get_entries(tb[col], grp)) for grp in grouping] # Filter list of values by the var2 using operator, return a list of group # ids of groups that passed filter condition if col_str == var1: filtered_grps = [grp_id for grp_id, val in enumerate(values) if eva.OPER[oper](var1=val, var2=hpr.parse_val(val_str))] else: filtered_grps = [grp_id for grp_id, val in enumerate(values) if eva.OPER[oper](var1=hpr.parse_val(val_str), var2=val)] return [grouping[i] for i in filtered_grps]