Beispiel #1
0
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)
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
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
Beispiel #9
0
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)