def visitAlter_table_add_foreign_key( self, ctx: SQLParser.Alter_table_add_foreign_keyContext): table_name = to_str(ctx.Identifier(0)) foreign_name = to_str(ctx.Identifier(1)) for_table_name = to_str(ctx.Identifier(2)) tb_list = ctx.identifiers(0).accept(self) for_list = ctx.identifiers(1).accept(self) for (tb_col, for_col) in zip(tb_list, for_list): self.manager.add_foreign(table_name, tb_col, (for_table_name, for_col), foreign_name)
def visitWhere_like_string(self, ctx: SQLParser.Where_like_stringContext): pattern = to_str(ctx.String())[1:-1] table_name, column_name = ctx.column().accept(self) return Condition(ConditionType.Like, table_name, column_name, value=pattern)
def visitField_list(self, ctx: SQLParser.Field_listContext): name_to_column = {} foreign_keys = {} primary_key = None # Modified by Dong: remove reversed for field in ctx.field(): if isinstance(field, SQLParser.Normal_fieldContext): name = to_str(field.Identifier()) type_, size = field.type_().accept(self) # not_null = field.getChild(2) == 'NOT' # default = to_str(field.value()) if field.value() else None name_to_column[name] = ColumnInfo(type_, name, size) elif isinstance(field, SQLParser.Foreign_key_fieldContext): field_name, table_name, refer_name = field.accept(self) if field_name in foreign_keys: raise DataBaseError( f'Foreign key named {field_name} is duplicated') foreign_keys[field_name] = table_name, refer_name else: assert isinstance(field, SQLParser.Primary_key_fieldContext) names = field.accept(self) for name in names: if name not in name_to_column: raise DataBaseError(f'Unknown field {name} field list') if primary_key: raise DataBaseError('Only one primary key supported') primary_key = names return list(name_to_column.values()), foreign_keys, primary_key
def visitCreate_table(self, ctx: SQLParser.Create_tableContext): columns, foreign_keys, primary = ctx.field_list().accept(self) table_name = to_str(ctx.Identifier()) res = self.manager.create_table(TableInfo(table_name, columns)) for col in foreign_keys: self.manager.add_foreign(table_name, col, foreign_keys[col]) self.manager.set_primary(table_name, primary) return res
def visitSelector(self, ctx: SQLParser.SelectorContext): if ctx.Count(): return Selector(SelectorType.Counter, '*', '*') table_name, column_name = ctx.column().accept(self) if ctx.aggregator(): return Selector(SelectorType.Aggregation, table_name, column_name, to_str(ctx.aggregator())) return Selector(SelectorType.Field, table_name, column_name)
def visitValue(self, ctx: SQLParser.ValueContext): if ctx.Integer(): return to_int(ctx) if ctx.Float(): return to_float(ctx) if ctx.String(): # 1:-1 to remove "'" at begin and end return to_str(ctx)[1:-1] if ctx.Null(): return None
def visitWhere_operator_select( self, ctx: SQLParser.Where_operator_selectContext): table_name, column_name = ctx.column().accept(self) operator = to_str(ctx.operator()) result: QueryResult = ctx.select_table().accept(self) value = self.manager.result_to_value(result, False) return Condition(ConditionType.Compare, table_name, column_name, operator, value=value)
def visitWhere_operator_expression( self, ctx: SQLParser.Where_operator_expressionContext): table_name, column_name = ctx.column().accept(self) operator = to_str(ctx.operator()) value = ctx.expression().accept(self) if isinstance(value, tuple): return Condition(ConditionType.Compare, table_name, column_name, operator, target_table=value[0], target_column=value[1]) else: return Condition(ConditionType.Compare, table_name, column_name, operator, value=value)
def visitAlter_table_rename(self, ctx: SQLParser.Alter_table_renameContext): old_name = to_str(ctx.Identifier(0)) new_name = to_str(ctx.Identifier(1)) self.manager.rename_table(old_name, new_name)
def visitAlter_table_drop(self, ctx: SQLParser.Alter_table_dropContext): table_name = to_str(ctx.Identifier(0)) col_name = to_str(ctx.Identifier(1)) self.manager.drop_column(table_name, col_name)
def visitAlter_table_add(self, ctx: SQLParser.Alter_table_addContext): column_info: ColumnInfo = ctx.field().accept(self) table_name = to_str(ctx.Identifier()) self.manager.add_column(table_name, column_info)
def visitUpdate_table(self, ctx: SQLParser.Update_tableContext): table_name = to_str(ctx.Identifier()) conditions = ctx.where_and_clause().accept(self) set_value_map = ctx.set_clause().accept(self) return self.manager.update_records(table_name, conditions, set_value_map)
def visitUse_db(self, ctx: SQLParser.Use_dbContext): return self.manager.use_db(to_str(ctx.Identifier()))
def visitCreate_db(self, ctx: SQLParser.Create_dbContext): return self.manager.create_db(to_str(ctx.Identifier()))
def visitAlter_table_add_pk(self, ctx: SQLParser.Alter_table_add_pkContext): table_name = to_str(ctx.Identifier(0)) primary = ctx.identifiers().accept(self) self.manager.set_primary(table_name, primary)
def visitColumn(self, ctx: SQLParser.ColumnContext): if len(ctx.Identifier()) == 1: return None, to_str(ctx.Identifier(0)) else: return to_str(ctx.Identifier(0)), to_str(ctx.Identifier(1))
def visitInsert_into_table(self, ctx: SQLParser.Insert_into_tableContext): table_name = to_str(ctx.getChild(2)) value_lists = ctx.value_lists().accept(self) for value_list in value_lists: self.manager.insert_record(table_name, value_list) return QueryResult('inserted_items', (len(value_lists), ))
def visitSelectors(self, ctx: SQLParser.SelectorsContext) -> tuple: if to_str(ctx.getChild(0)) == '*': return Selector(SelectorType.All, '*', '*'), return tuple(item.accept(self) for item in ctx.selector())
def visitAlter_table_drop_pk(self, ctx: SQLParser.Alter_table_drop_pkContext): table_name = to_str(ctx.Identifier(0)) self.manager.drop_primary(table_name)
def visitSet_clause(self, ctx: SQLParser.Set_clauseContext): set_value_map = {} for identifier, value in zip(ctx.Identifier(), ctx.value()): set_value_map[to_str(identifier)] = value.accept(self) return set_value_map
def visitAlter_table_drop_foreign_key( self, ctx: SQLParser.Alter_table_drop_foreign_keyContext): # table_name = to_str(ctx.Identifier(0)) foreign_name = to_str(ctx.Identifier(1)) self.manager.remove_foreign(None, None, foreign_name)
def visitDrop_table(self, ctx: SQLParser.Drop_tableContext): table_name = to_str(ctx.Identifier()) return self.manager.drop_table(table_name)
def visitType_(self, ctx: SQLParser.Type_Context): type_ = to_str(ctx.getChild(0)) size = to_int(ctx.Integer()) if ctx.Integer() else 0 return type_, size
def visitIdentifiers(self, ctx: SQLParser.IdentifiersContext): return tuple(to_str(each) for each in ctx.Identifier())
def visitDrop_db(self, ctx: SQLParser.Drop_dbContext): return self.manager.drop_db(to_str(ctx.Identifier()))
def visitAlter_drop_index(self, ctx: SQLParser.Alter_drop_indexContext): index_name = to_str(ctx.Identifier(1)) return self.manager.drop_index(index_name)
def visitCreate_index(self, ctx: SQLParser.Create_indexContext): index_name = to_str(ctx.getChild(2)) table_name = to_str(ctx.getChild(4)) column_names = ctx.identifiers().accept(self) for column_name in column_names: self.manager.create_index(index_name, table_name, column_name)
def visitDelete_from_table(self, ctx: SQLParser.Delete_from_tableContext): table_name = to_str(ctx.Identifier()) conditions = ctx.where_and_clause().accept(self) return self.manager.delete_records(table_name, conditions)
def visitAlter_add_index(self, ctx: SQLParser.Alter_add_indexContext): table_name = to_str(ctx.Identifier(0)) index_name = to_str(ctx.Identifier(1)) column_names = ctx.identifiers().accept(self) for column_name in column_names: self.manager.create_index(index_name, table_name, column_name)
def visitForeign_key_field(self, ctx: SQLParser.Foreign_key_fieldContext): return tuple(to_str(each) for each in ctx.Identifier())