def execute(self, table: SymbolTable, tree): super().execute(table, tree) by_pass = False if isinstance(self.insert_list, Select): self.insert_list = self.insert_list.execute(table, tree)[1] by_pass = True # Table symbol so we can run checks and validations table_symbol = table.get(self.table_name, SymbolType.TABLE) all_fields_declared = table.get_fields_from_table(self.table_name) # Sorting list, so we know order to insert is correct all_fields_declared.sort(key=lambda x: x.field_index) # Mapping values to insert, to actual structure on data structure to_insert = [] if not by_pass: if self.column_list is not None: for field_symbol in all_fields_declared: # looking in column list if declared field appears or None match = next((col for col in self.column_list if col.val == field_symbol.name), None) # Run validations only if result is not None value_related_to_match = self.column_list.index(match) if match is not None: #to ENUM StmENUM = None try: StmENUM = table.get(field_symbol.field_type.upper(), SymbolType.TYPE) except: pass if StmENUM and self.insert_list[value_related_to_match].val not in StmENUM.value_list : raise Error(0, 0, ErrorType.SEMANTIC, f'Field {field_symbol.name} must be a take any of the follow: {str(StmENUM.value_list)}') # TODO ADD HERE TYPE VALIDATIONS PER FIELD, JUST ONE ADDED BY NOW TO GIVE EXAMPLE if field_symbol.field_type.upper() == 'INTEGER' and type(self.insert_list[value_related_to_match].val) != int: raise Error(0, 0, ErrorType.SEMANTIC, f'Field {field_symbol.name} must be an integer type') to_insert.append(self.insert_list[value_related_to_match].val) # TODO ADD HERE CHECK VALIDATION else: to_insert = list(map(lambda x: x.val, self.insert_list)) result = insert(table.get_current_db().name, self.table_name, to_insert) if result == 1: raise Error(0, 0, ErrorType.RUNTIME, '5800: system_error') elif result == 2: raise Error(0, 0, ErrorType.RUNTIME, '42P04: database_does_not_exists') elif result == 3: raise Error(0, 0, ErrorType.RUNTIME, '42P07: table_does_not_exists') elif result == 4: raise Error(0, 0, ErrorType.RUNTIME, '42P10: duplicated_primary_key') else: for insert_reg in self.insert_list: result = insert(table.get_current_db().name, self.table_name, insert_reg) if result == 1: raise Error(0, 0, ErrorType.RUNTIME, '5800: system_error') elif result == 2: raise Error(0, 0, ErrorType.RUNTIME, '42P04: database_does_not_exists') elif result == 3: raise Error(0, 0, ErrorType.RUNTIME, '42P07: table_does_not_exists') elif result == 4: raise Error(0, 0, ErrorType.RUNTIME, '42P10: duplicated_primary_key') return True
def ejecutar(self): global resultadotxt global cont global tabla global NombreDB try: columnasdetabla = [] tablas = tabla.BuscarNombre(self.iden) for simbolo in tabla.simbolos: if tabla.simbolos[simbolo].ambito == tablas.id and not tabla.simbolos[ simbolo].tipo == TS.TIPO.DATABASE and not tabla.simbolos[ simbolo].tipo == TS.TIPO.TABLE and not tabla.simbolos[ simbolo].tipo == TS.TIPO.TUPLA: columnasdetabla.append(tabla.simbolos[simbolo]) colcorrecta = [] iter = 0 for columna in columnasdetabla: if VerificarTipo(columna.tipocol, self.valores[iter]): colcorrecta.append(self.valores[iter]) iter += 1 resultado = func.insert(NombreDB, self.iden, colcorrecta) if resultado == 2: resultadotxt += "No existe la base de datos " + NombreDB + "\n" elif resultado == 3: resultadotxt += "No existe la base tabla " + NombreDB + "\n" elif resultado == 5: resultadotxt += "La cantidad de valores no coincide con la cantidad de columnas\n" else: nombre = "" for element in colcorrecta: nombre += str(element) + " " NuevoRegistro = TS.Simbolo(cont, nombre, TS.TIPO.TUPLA, tablas.id) tabla.agregar(NuevoRegistro) resultadotxt += "El registro " + self.valores[ 0] + " fue agregado a la tabla " + self.iden + "\n" except: """ERRORES SEMANTICOS"""
def execute(self, ts_global): self.base = ts_global.get_dbActual( ).id # se obtiene la base que se usa actualmente if isinstance(self.base, E.Errores): # si no hay base de datos en uso es error nuevo_error = E.Errores( 'Semántico.', 'No se ha seleccionado una base de datos.') #ls_error.append(nuevo_Error) # se agrega el error a la lista return # y termina la ejecución tabla = ts_global.get_table(self.base, self.tabla) # busca si existe la tabla if isinstance(tabla, E.Errores): # si no existe, es error #ls_error.append(tabla) # se agrega el error a la lista return # y termina la ejecución c_campos = -1 # variable para llevar conteo de campos if self.campos is not None: # si la instrucción si trae campos columna = None # variable para obtener columnas errores = False # bandera para saber si hubieron errores c_campos = 0 # se cambia el valor del contador para saber que venían campos for campo in self.campos: # se recorre la lista de campos y se buscan en la tabla de símbolos columna = ts_global.get_column(self.base, self.tabla, campo) if isinstance( columna, E.Errores): # si la columna queda en None, hubo error #ls_error.append(columna) # se agrega el error a la lista errores = True # se actualiza que hubo errores c_campos = c_campos + 1 # se aumenta el contador de campos if errores: # si hay errores return # se retorna y termina la ejecución c_valores = len(self.valores) # variable para llevar conteo de valores if c_campos == 0: # si el contador de campos está en 0, hay errores al reconocerlos return # entonces, se sale de la ejecución elif c_campos == -1: # si el contador de campos está en -1, se inserta en todos los campos l = -1 # variable para tener la posición de la lista de columnas valo = None # variable para manejar el valor k = 0 # variable para tener la posición de la lista de valores c_columnas = len( tabla.valor ) # variable para saber la cantidad de columnas totales if c_columnas == c_valores: # si coincide con la cantidad de valores que viene, se insertan tipo_c = False #comprobar tipos for col in tabla.valor: k = k + 1 valo = self.valores[k] tipo_c = self.verifyType(col.tipo, valo) if not tipo_c: # se verifica el valor del campo, si no coincide es error new_error = E.Errores( 'Semántico.', 'No se puede insertar \'' + valor + '\' en la columna \'' + columna.id + '\'.') #ls_error.append(nuevo_Error) # se agrega el error a la lista return # sale de la ejecución errores = False if columna.tipo == TS.tipo_simbolo.VARCHR: # se quitan las comillas de las cadenas self.valores[i] = ((self.valores[i]).split('\''))[1] for constraint in columna.valor: # se recorre la lista de constraints si tuviera if constraint.tipo == TS.t_constraint.PRIMARY: tipo_c = self.isNull(columna.tipo, self.valores[i]) if tipo_c: # si es nuleable, es error new_error = E.Errores( 'Semántico.', 'No puede venir null un campo con el constraint \'NOT NULL\'.' ) #ls_error.append(nuevo_Error) # se agrega el error a la lista errores = True tipo_c = self.isUnique( columna.tipo, self.valores[i], ts_global.get_pos_column(tabla, columna)) if not tipo_c: # si no es único, es error new_error = E.Errores( 'Semántico.', 'No pueden venir valores repetidos en un campo con el constraint \'UNIQUE\'.' ) #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.tipo == TS.t_constraint.NOT_NULL: tipo_c = self.isNull(columna.tipo, self.valores[i]) if tipo_c: # si es nuleable, es error new_error = E.Errores( 'Semántico.', 'No puede venir null un campo con el constraint \'NOT NULL\'.' ) #ls_error.append(nuevo_Error) # se agrega el error a la lista errores = True elif constraint.tipo == TS.t_constraint.UNIQUE: tipo_c = self.isUnique( columna.tipo, self.valores[i], ts_global.get_pos_column(tabla, columna)) if not tipo_c: # si no es único, es error new_error = E.Errores( 'Semántico.', 'No pueden venir valores repetidos en un campo con el constraint \'UNIQUE\'.' ) #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.tipo == TS.t_constraint.DEFOULT: print('') elif constraint.tipo == TS.t_constraint.CHECK: valor = self.valores[i] if constraint.condicion == '<': if valor >= constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.condicion == '>': if valor <= constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.condicion == '>=': if valor < constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.condicion == '<=': if valor > constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.condicion == '=' or constraint.condicion == '==': if valor != constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.condicion == '<>' or constraint.condicion == '<>': if valor == constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True else: print(constraint.condicion) elif constraint.tipo == TS.t_constraint.FOREIGN: print('') if errores: # si hay cualquier tipo de error, return # se retorna, si no, se inserta j.insert(self.base, self.tabla, self.valores) else: # si no coincide, es error new_error = E.Errores( 'Semántico.', 'No coincide la cantidad de campos a insertar.') elif c_campos != c_valores: # si la cantidad de campos es diferente a la cantidad de valores, es error new_error = E.Errores( 'Semántico.', 'La cantidad de campos a ingresar no coincide con la cantidad de valores.' ) #ls_error.append(nuevo_Error) # se agrega el error a la lista return # y se sale de la ejecución else: # si son iguales los contadores, se incerta en los campos campo = None # variable para seleccionar un campo de la lista de campos valor = None # variable para seleccionar un valor de la lista de valores columna = None # variable para obtener la columna de la tabla de símbolos tipo_c = False # variable para verificar los tipos de datos errores = False # variable para verificar si hay errores i = 0 # índice para separar los campos/valores inserciones = [] # arreglo para llevar las insercinoes while i < c_campos: # se recorre la lista de campos y se buscan en la tabla de símbolos campo = self.campos[ i] # se obtiene un campo en el que se va a insertar valor = self.valores[i] # se obtiene su valor a insertar inserciones.append(valor) # se agrega el valor a insertar columna = ts_global.get_column(self.base, self.tabla, campo) if isinstance( columna, E.Errores): # si no se encuentra la columna, es error nuevo_error = E.Errores( 'Semántico.', 'No se ha encontrado el campo en la tabla indicada.') #ls_error.append(nuevo_error) # se agrega el error a la lista i = i + 1 # se aumenta el índice i = 0 # se reinicia la variable para hacer comprobaciones while i < c_campos: # se recorre la lista de inserciones columna = ts_global.get_column(self.base, self.tabla, self.campos[i]) tipo_c = self.verifyType(columna.tipo, inserciones[i]) if not tipo_c: # se verifica el valor del campo, si no coincide es error new_error = E.Errores( 'Semántico.', 'No se puede insertar \'' + valor + '\' en la columna \'' + columna.id + '\'.') #ls_error.append(nuevo_Error) # se agrega el error a la lista return # sale de la ejecución if columna.tipo == TS.tipo_simbolo.VARCHR: # se quitan las comillas de las cadenas inserciones[i] = ((inserciones[i]).split('\''))[1] for constraint in columna.valor: # se recorre la lista de constraints si tuviera if constraint.tipo == TS.t_constraint.PRIMARY: tipo_c = self.isNull(columna.tipo, inserciones[i]) if tipo_c: # si es nuleable, es error new_error = E.Errores( 'Semántico.', 'No puede venir null un campo con el constraint \'NOT NULL\'.' ) #ls_error.append(nuevo_Error) # se agrega el error a la lista errores = True tipo_c = self.isUnique( columna.tipo, inserciones[i], ts_global.get_pos_column(tabla, columna)) if not tipo_c: # si no es único, es error new_error = E.Errores( 'Semántico.', 'No pueden venir valores repetidos en un campo con el constraint \'UNIQUE\'.' ) #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.tipo == TS.t_constraint.NOT_NULL: tipo_c = self.isNull(columna.tipo, inserciones[i]) if tipo_c: # si es nuleable, es error new_error = E.Errores( 'Semántico.', 'No puede venir null un campo con el constraint \'NOT NULL\'.' ) #ls_error.append(nuevo_Error) # se agrega el error a la lista errores = True elif constraint.tipo == TS.t_constraint.UNIQUE: tipo_c = self.isUnique( columna.tipo, inserciones[i], ts_global.get_pos_column(tabla, columna)) if not tipo_c: # si no es único, es error new_error = E.Errores( 'Semántico.', 'No pueden venir valores repetidos en un campo con el constraint \'UNIQUE\'.' ) #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.tipo == TS.t_constraint.DEFOULT: print('') elif constraint.tipo == TS.t_constraint.CHECK: valor = inserciones[i] print(valor) if constraint.condicion == '<': if valor >= constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.condicion == '>': if valor <= constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.condicion == '>=': if valor < constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.condicion == '<=': if valor > constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.condicion == '=' or constraint.condicion == '==': if valor != constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif constraint.condicion == '<>' or constraint.condicion == '<>': if valor == constraint.valor: new_error = E.Errores( 'Semántico.', 'Violación del constraint check.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True else: print(constraint.condicion) elif constraint.tipo == TS.t_constraint.FOREIGN: print('') if errores: # si hay errores en los valores o en los constraints, return # se sale de la ejecución i = i + 1 # se aumenta el índice val = [] # variable para tener todos los valores a insertar for x in tabla.valor: # se establece un tamaño definido para el arreglo igual val.append(None) # al tamaño de la cantidad de columnas l = -1 # variable para tener la posición de la lista de columnas k = 0 # variable para tener la posición de la lista de valores c_columnas = len( tabla.valor ) # variable para saber la cantidad de columnas totales if c_columnas == c_valores: # si coincide con la cantidad de valores que viene, se insertan j.insert(self.base, self.tabla, inserciones) else: # si no coincide, se recorre la lista de columnas de la tabla para for columna in tabla.valor: # verificar constraints, si la columna tiene constraints, se verifica l = l + 1 # que la columna venga en los campos. Si sí viene (cuando el try se if len( columna.valor ) > 0: # ejecuta con éxito), se verifica que las posiciones coincidan para try: # si la columna no se encuentra en la lista de campos, se recorre la k = self.campos.index(columna.id) val[l] = inserciones[k] except: # lista de constraints, verificando que no venga PRIMARY KEY o NOT NULL for con in columna.valor: if con.id == TS.t_constraint.NOT_NULL: new_error = E.Errores( 'Semántico.', 'Se está violando el constraint \'NOT NULL\' de la columna \'' + columna.id + '\'.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True elif con.id == TS.t_constraint.PRIMARY: new_error = E.Errores( 'Semántico.', 'La llave primaria no puede ser nula.') #ls_error.append(nuevo_Error)# se agrega el error a la lista errores = True val[l] = None else: try: k = self.campos.index(columna.id) val[l] = inserciones[k] except: val[l] = None if errores: # si existiera uno de esos constraints, es error y no se puede insertar return # por lo que se sale de la ejecución j.insert(self.base, self.tabla, val) # si no hay error, se insertan los valores