def optimize_program(code: str, rels: Dict[str, Relation]) -> str: ''' Optimize an entire program, composed by multiple expressions and assignments. ''' lines = code.split('\n') context: Dict[str, Node] = {} last_res = None for line in lines: # skip comments or empty lines line = line.strip() if line.startswith(';') or not line: continue res, query = UserInterface.split_query(line) last_res = res parsed = tree(query) _replace_leaves(parsed, context) context[res] = parsed if last_res is None: return '' node = optimize_all(context[last_res], rels, tostr=False) return querysplit.split(node, rels)
def run_fail_test(testname): '''Runs a test, which executes a query that is supposed to fail''' print("Running fail test: " + colorize(testname, COLOR_MAGENTA)) query = readfile('%s%s.fail' % (tests_path, testname)).strip() test_succeed = True try: expr = parser.parse(query) expr(rels) test_succeed = False except: pass try: o_query = optimizer.optimize_all(query, rels) o_expr = parser.parse(o_query) o_expr(rels) test_succeed = False except: pass try: c_expr = parser.tree(query).toCode() eval(c_expr, rels) test_succeed = False except: pass if test_succeed: print(colorize('Test passed', COLOR_GREEN)) else: print(colorize('Test failed (by not raising any exception)', COLOR_RED)) return test_succeed
def run_fail_test(testname): '''Runs a test, which executes a query that is supposed to fail''' print ("Running fail test: " + colorize(testname, COLOR_MAGENTA)) query = readfile('%s%s.fail' % (tests_path, testname)).strip() test_succeed = True try: expr = parser.parse(query) expr(rels) test_succeed = False except: pass try: o_query = optimizer.optimize_all(query, rels) o_expr = parser.parse(o_query) o_expr(rels) test_succeed = False except: pass try: c_expr = parser.tree(query).toCode() eval(c_expr, rels) test_succeed = False except: pass if test_succeed: print (colorize('Test passed', COLOR_GREEN)) else: print (colorize('Test failed (by not raising any exception)', COLOR_RED)) return test_succeed
def run_test(testname): '''Runs a specific test executing the file testname.query and comparing the result with testname.result The query will be executed both unoptimized and optimized''' print("Running test: " + colorize(testname, COLOR_MAGENTA)) query = None expr = None o_query = None o_expr = None result_rel = None result = None o_result = None try: result_rel = relation.Relation.load('%s%s.result' % (tests_path, testname)) query = readfile('%s%s.query' % (tests_path, testname)).strip() o_query = optimizer.optimize_all(query, rels) expr = parser.parse(query) result = expr(rels) o_expr = parser.parse(o_query) o_result = o_expr(rels) c_expr = parser.tree(query).toCode() c_result = eval(c_expr, rels) if (o_result == result_rel) and (result == result_rel) and (c_result == result_rel): print(colorize('Test passed', COLOR_GREEN)) return True except Exception as inst: traceback.print_exc(file=sys.stdout) print(inst) pass print(colorize('ERROR', COLOR_RED)) print("Query: %s -> %s" % (query, expr)) print("Optimized query: %s -> %s" % (o_query, o_expr)) print(colorize('=====================================', COLOR_RED)) print(colorize("Expected result", COLOR_GREEN)) print(result_rel.pretty_string(tty=True)) print(colorize("Result", COLOR_RED)) print(result.pretty_string(tty=True)) print(colorize("Optimized result", COLOR_RED)) print(o_result.pretty_string(tty=True)) print( colorize("optimized result match %s" % str(result_rel == o_result), COLOR_MAGENTA)) print( colorize("result match %s" % str(result == result_rel), COLOR_MAGENTA)) print(colorize('=====================================', COLOR_RED)) return False
def run_test(testname): '''Runs a specific test executing the file testname.query and comparing the result with testname.result The query will be executed both unoptimized and optimized''' print "Running test: " + colorize(testname, COLOR_MAGENTA) query = None expr = None o_query = None o_expr = None result_rel = None result = None o_result = None try: result_rel = relation.relation('%s%s.result' % (tests_path, testname)) query = unicode( readfile('%s%s.query' % (tests_path, testname)).strip(), 'utf8') o_query = optimizer.optimize_all(query, rels) expr = parser.parse(query) # Converting expression to python string result = eval(expr, rels) # Evaluating the expression o_expr = parser.parse( o_query) # Converting expression to python string o_result = eval(o_expr, rels) # Evaluating the expression c_expr = parser.tree(query).toCode() # Converting to python code c_result = eval(c_expr, rels) if (o_result == result_rel) and (result == result_rel) and (c_result == result_rel): print colorize('Test passed', COLOR_GREEN) return True except Exception as inst: print inst pass print colorize('ERROR', COLOR_RED) print "Query: %s -> %s" % (query, expr) print "Optimized query: %s -> %s" % (o_query, o_expr) print colorize('=====================================', COLOR_RED) print colorize("Expected result", COLOR_GREEN) print result_rel print colorize("Result", COLOR_RED) print result print colorize("Optimized result", COLOR_RED) print o_result print colorize("optimized result match %s" % str(result_rel == o_result), COLOR_MAGENTA) print colorize("result match %s" % str(result == result_rel), COLOR_MAGENTA) print colorize('=====================================', COLOR_RED) return False
def run_test(testname): '''Runs a specific test executing the file testname.query and comparing the result with testname.result The query will be executed both unoptimized and optimized''' print ("Running test: " + colorize(testname, COLOR_MAGENTA)) query = None expr = None o_query = None o_expr = None result_rel = None result = None o_result = None try: result_rel = relation.relation('%s%s.result' % (tests_path, testname)) query = readfile('%s%s.query' % (tests_path, testname)).strip() o_query = optimizer.optimize_all(query, rels) expr = parser.parse(query) # Converting expression to python string result = eval(expr, rels) # Evaluating the expression o_expr = parser.parse( o_query) # Converting expression to python string o_result = eval(o_expr, rels) # Evaluating the expression c_expr = parser.tree(query).toCode() # Converting to python code c_result = eval(c_expr, rels) if (o_result == result_rel) and (result == result_rel) and (c_result == result_rel): print (colorize('Test passed', COLOR_GREEN)) return True except Exception as inst: print (inst) pass print (colorize('ERROR', COLOR_RED)) print ("Query: %s -> %s" % (query, expr)) print ("Optimized query: %s -> %s" % (o_query, o_expr)) print (colorize('=====================================', COLOR_RED)) print (colorize("Expected result", COLOR_GREEN)) print (result_rel) print (colorize("Result", COLOR_RED)) print (result) print (colorize("Optimized result", COLOR_RED)) print (o_result) print (colorize("optimized result match %s" % str(result_rel == o_result), COLOR_MAGENTA)) print (colorize("result match %s" % str(result == result_rel), COLOR_MAGENTA)) print (colorize('=====================================', COLOR_RED)) return False
def optimize_all(expression: Union[str, Node], rels: Dict[str, Relation], specific: bool = True, general: bool = True, debug: Optional[list] = None, tostr: bool = True) -> Union[str, Node]: '''This function performs all the available optimizations. expression : see documentation of this module rels: dic with relation name as key, and relation istance as value specific: True if it has to perform specific optimizations general: True if it has to perform general optimizations debug: if a list is provided here, after the end of the function, it will contain the query repeated many times to show the performed steps. Return value: this will return an optimized version of the expression''' if isinstance(expression, str): n = tree(expression) # Gets the tree elif isinstance(expression, Node): n = expression else: raise TypeError('expression must be a string or a node') total = 1 while total != 0: total = 0 if specific: for i in optimizations.specific_optimizations: n, c = _recursive_scan(i, n, rels) if c != 0 and isinstance(debug, list): debug.append(str(n)) total += c if general: for j in optimizations.general_optimizations: n, c = _recursive_scan(j, n, None) if c != 0 and isinstance(debug, list): debug.append(str(n)) total += c if tostr: return str(n) else: return n
def optimize_all(expression: Union[str, Node], rels: ContextDict, specific: bool = True, general: bool = True, debug: Optional[list] = None, tostr: bool = True) -> Union[str, Node]: '''This function performs all the available optimizations. expression : see documentation of this module rels: dic with relation name as key, and relation istance as value specific: True if it has to perform specific optimizations general: True if it has to perform general optimizations debug: if a list is provided here, after the end of the function, it will contain the query repeated many times to show the performed steps. Return value: this will return an optimized version of the expression''' if isinstance(expression, str): n = tree(expression) # Gets the tree elif isinstance(expression, Node): n = expression else: raise (TypeError("expression must be a string or a node")) if isinstance(debug, list): dbg = True else: dbg = False total = 1 while total != 0: total = 0 if specific: for i in optimizations.specific_optimizations: res = i(n, rels) # Performs the optimization if res != 0 and dbg: debug.append(str(n)) total += res if general: for i in optimizations.general_optimizations: res = i(n) # Performs the optimization if res != 0 and dbg: debug.append(str(n)) total += res if tostr: return str(n) else: return n
def optimize_program(code, rels: ContextDict): ''' Optimize an entire program, composed by multiple expressions and assignments. ''' lines = code.split('\n') context = {} # type: ContextDict for line in lines: line = line.strip() if line.startswith(';') or not line: continue res, query = UserInterface.split_query(line) last_res = res parsed = tree(query) optimizations.replace_leaves(parsed, context) context[res] = parsed node = optimize_all(context[last_res], rels, tostr=False) return querysplit.split(node, rels)