diff --git a/internal/reports/report_helpers.go b/internal/reports/report_helpers.go index 431da8136..5678b8fc6 100644 --- a/internal/reports/report_helpers.go +++ b/internal/reports/report_helpers.go @@ -448,6 +448,12 @@ func buildTableReportBody(conv *internal.Conv, tableId string, issues map[string Description: fmt.Sprintf("Table '%s': Column not found which is mention in check constraint condition. Verify the conditions with constraint logic", conv.SpSchema[tableId].Name), } l = append(l, toAppend) + case internal.TypeMismatch: + toAppend := Issue{ + Category: IssueDB[i].Category, + Description: fmt.Sprintf("Table '%s': Type mismatch in '%s'column affecting check constraints. Verify data type compatibility with constraint logic", conv.SpSchema[tableId].Name, conv.SpSchema[tableId].ColDefs[colId].Name), + } + l = append(l, toAppend) default: toAppend := Issue{ diff --git a/webv2/api/schema.go b/webv2/api/schema.go index 9840c55ae..23dfd27bb 100644 --- a/webv2/api/schema.go +++ b/webv2/api/schema.go @@ -682,6 +682,91 @@ func ValidateCheckConstraint(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(flag) } +// UpdateCheckConstraint processes the request to update spanner table check constraints, ensuring session and schema validity, and responds with the updated conversion metadata. +func UpdateCheckConstraint(w http.ResponseWriter, r *http.Request) { + tableId := r.FormValue("table") + reqBody, err := ioutil.ReadAll(r.Body) + if err != nil { + http.Error(w, fmt.Sprintf("Body Read Error : %v", err), http.StatusInternalServerError) + } + sessionState := session.GetSessionState() + if sessionState.Conv == nil || sessionState.Driver == "" { + http.Error(w, fmt.Sprintf("Schema is not converted or Driver is not configured properly. Please retry converting the database to Spanner."), http.StatusNotFound) + return + } + sessionState.Conv.ConvLock.Lock() + defer sessionState.Conv.ConvLock.Unlock() + + newCKs := []ddl.CheckConstraint{} + if err = json.Unmarshal(reqBody, &newCKs); err != nil { + http.Error(w, fmt.Sprintf("Request Body parse error : %v", err), http.StatusBadRequest) + return + } + + sp := sessionState.Conv.SpSchema[tableId] + sp.CheckConstraints = newCKs + sessionState.Conv.SpSchema[tableId] = sp + session.UpdateSessionFile() + + convm := session.ConvWithMetadata{ + SessionMetadata: sessionState.SessionMetadata, + Conv: *sessionState.Conv, + } + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(convm) +} + +func doesNameExist(spcks []ddl.CheckConstraint, targetName string) bool { + for _, spck := range spcks { + if strings.Contains(spck.Expr, targetName) { + return true + } + } + return false +} + +// ValidateCheckConstraint verifies if the type of a database column has been altered and add an error if a change is detected. +func ValidateCheckConstraint(w http.ResponseWriter, r *http.Request) { + sessionState := session.GetSessionState() + if sessionState.Conv == nil || sessionState.Driver == "" { + http.Error(w, fmt.Sprintf("Schema is not converted or Driver is not configured properly. Please retry converting the database to Spanner."), http.StatusNotFound) + return + } + sessionState.Conv.ConvLock.Lock() + defer sessionState.Conv.ConvLock.Unlock() + + sp := sessionState.Conv.SpSchema + srcschema := sessionState.Conv.SrcSchema + flag := true + var schemaIssue []internal.SchemaIssue + + for _, src := range srcschema { + for _, col := range sp[src.Id].ColDefs { + if len(sp[src.Id].CheckConstraints) > 0 { + spType := col.T.Name + srcType := srcschema[src.Id].ColDefs[col.Id].Type + actualType := mysqlDefaultTypeMap[srcType.Name] + if actualType.Name != spType { + columnName := sp[src.Id].ColDefs[col.Id].Name + spcks := sp[src.Id].CheckConstraints + if doesNameExist(spcks, columnName) { + flag = false + schemaIssue = sessionState.Conv.SchemaIssues[src.Id].ColumnLevelIssues[col.Id] + if !utilities.IsSchemaIssuePresent(schemaIssue, internal.TypeMismatch) { + schemaIssue = append(schemaIssue, internal.TypeMismatch) + } + sessionState.Conv.SchemaIssues[src.Id].ColumnLevelIssues[col.Id] = schemaIssue + break + } + } + } + } + } + + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(flag) +} + // renameForeignKeys checks the new names for spanner name validity, ensures the new names are already not used by existing tables // secondary indexes or foreign key constraints. If above checks passed then foreignKey renaming reflected in the schema else appropriate // error thrown.