def _parse_select(self, sql): """ parsing the sql by the grammar Select ::= Agg | AggAgg | AggAggAgg | ... | Agg ::= agg column table :return: [Select(), states] """ lst_result = [] select = sql['sql']['select'] lst_result.append(grammar.Select(0)) lst_result.append(grammar.NumA(len(select) - 1)) for sel in select: if sel[1][0] == 0: lst_result.append(grammar.Agg(sel[0])) col_id, is_const_col = self._trans_col_id(sql['column_set'], sql['column_names'], sel[1][1][1]) self.col_set.add(col_id) lst_result.append(grammar.Column(col_id)) # now check for the situation with * if is_const_col: lst_result.append(self._parse_const_column(sql, select)) else: lst_result.append(grammar.Table(sql['column_table'][sel[1][1][1]])) else: #列计算 lst_result.append(grammar.Agg(sel[0] + 6)) if sel[1][0] == 1: # - lst_result.append(grammar.MathAgg(1)) elif sel[1][0] == 2: # + lst_result.append(grammar.MathAgg(0)) elif sel[1][0] == 3: # * lst_result.append(grammar.MathAgg(2)) elif sel[1][0] == 4: # / lst_result.append(grammar.MathAgg(3)) else: raise NotImplementedError("Not the right MathAgg") lst_result.append(grammar.Agg(sel[1][1][0])) col_id1, is_const_col = self._trans_col_id(sql['column_set'], sql['column_names'], sel[1][1][1]) lst_result.append(grammar.Column(col_id1)) # now check for the situation with * if is_const_col: lst_result.append(self._parse_const_column(sql, select)) else: lst_result.append(grammar.Table(sql['column_table'][sel[1][1][1]])) lst_result.append(grammar.Agg(sel[1][2][0])) col_id2, is_const_col = self._trans_col_id(sql['column_set'], sql['column_names'], sel[1][2][1]) lst_result.append(grammar.Column(col_id2)) # now check for the situation with * if is_const_col: lst_result.append(self._parse_const_column(sql, select)) else: lst_result.append(grammar.Table(sql['column_table'][sel[1][1][1]])) if not self.copy_selec: self.copy_selec = [copy.deepcopy(lst_result[-2]), copy.deepcopy(lst_result[-1])] return lst_result, None
def _parse_order(self, sql): """ parsing the sql by the grammar Order ::= asc Agg | desc Agg Agg ::= agg column table :return: [Order(), states] """ lst_result = [] if 'order' not in sql['query_toks_no_value'] or 'by' not in sql[ 'query_toks_no_value']: return lst_result, None elif 'limit' in sql['query_toks_no_value']: return lst_result, None if sql['sql']['orderBy'] == []: return lst_result, None if sql['sql']['orderBy'][0] == 'desc': lst_result.append(grammar.Order(0)) else: lst_result.append(grammar.Order(1)) agg_id, val_unit = sql['sql']['orderBy'][1][0] if val_unit[2] is not None: lst_result.append(grammar.Agg(agg_id + 6)) if val_unit[0] == 1: lst_result.append(grammar.MathAgg(1)) elif val_unit[0] == 2: lst_result.append(grammar.MathAgg(0)) elif val_unit[0] == 3: lst_result.append(grammar.MathAgg(2)) elif val_unit[0] == 4: lst_result.append(grammar.MathAgg(3)) lst_result.extend(self._gen_agg(val_unit[1][0], val_unit[1], sql)) lst_result.extend(self._gen_agg(val_unit[2][0], val_unit[2], sql)) else: lst_result.extend(self._gen_agg(agg_id, val_unit[1], sql)) return lst_result, None
def _parse_sup(self, sql): """ parsing the sql by the grammar Superlative ::= Most Agg | Least Agg Agg ::= agg column table :return: [Superlative(), states] """ lst_result = [] if sql['sql']['limit'] is None: return lst_result, None if sql['sql']['orderBy'][0] == 'desc': lst_result.append(grammar.Superlative(0)) else: lst_result.append(grammar.Superlative(1)) agg_id, val_unit = sql['sql']['orderBy'][1][0] if val_unit[2] is not None: lst_result.append(grammar.Agg(agg_id + 6)) if val_unit[0] == 1: lst_result.append(grammar.MathAgg(1)) elif val_unit[0] == 2: lst_result.append(grammar.MathAgg(0)) elif val_unit[0] == 3: lst_result.append(grammar.MathAgg(2)) elif val_unit[0] == 4: lst_result.append(grammar.MathAgg(3)) lst_result.extend(self._gen_agg(val_unit[1][0], val_unit[1], sql)) lst_result.extend(self._gen_agg(val_unit[2][0], val_unit[2], sql)) else: lst_result.extend(self._gen_agg(agg_id, val_unit[1], sql)) value_idx = self._find_value_index(sql['dct_values'], sql['sql']['limit']) lst_result.append(grammar.Value(value_idx)) return lst_result, None
def _parse_one_condition(self, cond_unit, names, sql): """ parse one condition unit Args: cond_unit: cond_unit names:names sql:sql """ lst_result = [] # check if V(root) nest_query = True if type(cond_unit[3]) != dict: nest_query = False # check for Filter (=, <, >, !=, between, >=, <=, ...) # 00: not_in # 01: between 05: >= 09: like # 02: = 06: <= 10: is # 03: > 07: != 11: exists # 04: < 08: in 12: not like # map from sql op id to grammar filter id single_map = {1: 8, 2: 2, 3: 5, 4: 4, 5: 7, 6: 6, 7: 3} nested_map = {1: 15, 2: 11, 3: 13, 4: 12, 5: 16, 6: 17, 7: 14} cond_op = cond_unit[1] if cond_op in [1, 2, 3, 4, 5, 6, 7]: if nest_query == False: fil = grammar.Filter(single_map[cond_op]) else: fil = grammar.Filter(nested_map[cond_op]) elif cond_op == 8: fil = grammar.Filter(18) elif cond_op == 9: fil = grammar.Filter(9) elif cond_op == 12: fil = grammar.Filter(10) elif cond_op == 0: fil = grammar.Filter(19) else: raise NotImplementedError("not implement for the others FIL") lst_result.append(fil) # MathAgg if cond_unit[2][2] is not None: lst_result.append(grammar.Agg(cond_unit[0] + 6)) if cond_unit[2][0] == 1: lst_result.append(grammar.MathAgg(1)) elif cond_unit[2][0] == 2: lst_result.append(grammar.MathAgg(0)) elif cond_unit[2][0] == 3: lst_result.append(grammar.MathAgg(2)) elif cond_unit[2][0] == 4: lst_result.append(grammar.MathAgg(3)) lst_result.extend( self._gen_agg(cond_unit[2][1][0], cond_unit[2][1], sql)) lst_result.extend( self._gen_agg(cond_unit[2][2][0], cond_unit[2][2], sql)) else: lst_result.extend(self._gen_agg(cond_unit[0], cond_unit[2][1], sql)) dct_values = sql['dct_values'] if not nest_query: lst_result.append( grammar.Value(self._find_value_index(dct_values, cond_unit[3]))) if not nest_query and cond_unit[4] is not None: lst_result.append( grammar.Value(self._find_value_index(dct_values, cond_unit[4]))) if nest_query: nest_query = {} nest_query['query_toks_no_value'] = "" nest_query['sql'] = cond_unit[3] nest_query['column_table'] = sql['column_table'] nest_query['column_names'] = sql['column_names'] nest_query['table_names'] = sql['table_names'] nest_query['question'] = sql['question'] nest_query['column_set'] = sql['column_set'] nest_query['values'] = sql['values'] nest_query['dct_values'] = sql['dct_values'] lst_result.extend(self._parse_single_sql(nest_query)) return lst_result