def down_select(syntax_tree, sql, relation2): if syntax_tree.op == 'SELECT': condition = syntax_tree.cond sql = condition.split('&') relation = [] # 找出关系名 for i in range(len(sql)): if lookfor(sql[i]) is not None: relation.append(lookfor(sql[i])) relation2.append(lookfor2(sql[i])) syntax_tree = down_select(syntax_tree.lfchild, sql, relation2) elif syntax_tree.op == 'PROJECTION': # 跳过投影 syntax_tree.lfchild = down_select(syntax_tree.lfchild, sql, relation2) elif syntax_tree.op == 'JOIN': # 有JOIN,将SELECT与关系名下推 first_tree = SyntaxTree() first_tree.op = 'SELECT' first_tree.cond = sql[0] first_tree.lfchild = syntax_tree.lfchild syntax_tree.lfchild = first_tree if len(sql) == 1: return syntax_tree second_tree = SyntaxTree() second_tree.op = 'SELECT' second_tree.cond = sql[1] second_tree.rchild = syntax_tree.rchild syntax_tree.rchild = second_tree return syntax_tree
def parsesql(sql_statement): sql = sql_statement.split() tree = SyntaxTree() index = 0 while True: if index >= len(sql): break elif sql[index] == 'SELECT' or sql[index] == 'PROJECTION': tree.op = sql[index] index += 2 condition = '' # 把[]里的内容全部记录下来 while sql[index] != ']': condition += sql[index] condition += ' ' index += 1 index += 1 tree.cond = condition elif sql[index] == 'JOIN': # 连接操作创建子树 tree.op = sql[index] tree.lfchild = SyntaxTree() tree.lfchild.attr = sql[index - 1] tree.rchild = SyntaxTree() tree.rchild.attr = sql[index + 1] index += 1 elif sql[index] == '(': # 遇到(再创建一个子树 index += 1 statement = '' while index < len(sql) and sql[index] != ')': statement += sql[index] statement += ' ' index += 1 index += 1 tree.lfchild = parsesql(statement) # 递归构造子树 else: index += 1 return tree
def down_proj(syntax_tree, sql, relation2, same): if syntax_tree.op == 'SELECT': syntax_tree.lfchild = down_proj(syntax_tree.lfchild, sql, relation2, same) elif syntax_tree.op == 'PROJECTION': # 将投影下推 sql = syntax_tree.cond.split(",") for i in range(len(sql)): if lookfor(sql[i]) is not None: if lookfor2(sql[i]) in relation2: pass else: relation2.append(lookfor2(sql[i])) # 找相交的元素 same += findthesame(relation2[0], relation2[1]) syntax_tree.lfchild = down_proj(syntax_tree.lfchild, sql, relation2, same) elif syntax_tree.op == 'JOIN': # 有JOIN,将条件和投影下推 if len(sql) > 0 and '=' not in sql[0]: first_tree = SyntaxTree() first_tree.op = 'PROJECTION' first_tree.cond = sql[0] + ', ' + same first_tree.lfchild = syntax_tree.lfchild syntax_tree.lfchild = first_tree if len(sql) > 1: second_tree = SyntaxTree() second_tree.op = 'PROJECTION' second_tree.cond = sql[1] + ', ' + same second_tree.rchild = syntax_tree.rchild syntax_tree.rchild = second_tree elif same != '': second_tree = SyntaxTree() second_tree.op = 'PROJECTION' second_tree.cond = same second_tree.rchild = syntax_tree.rchild syntax_tree.rchild = second_tree return syntax_tree