in common/utils/utils.go [434:508]
func CompareSchema(sessionFileConv, actualSpannerConv *internal.Conv) error {
if sessionFileConv.SpDialect != actualSpannerConv.SpDialect {
return fmt.Errorf("spanner dialect don't match: session dialect %v, spanner dialect %v", sessionFileConv.SpDialect, actualSpannerConv.SpDialect)
}
for _, sessionTable := range sessionFileConv.SpSchema {
spannerTableId, err := internal.GetTableIdFromSpName(actualSpannerConv.SpSchema, sessionTable.Name)
if err != nil {
return fmt.Errorf("table %v not found in the spanner database schema but found in the session file. If this table does not need to be migrated, please exclude it during the schema conversion and migration process", sessionTable.Name)
}
spannerTable := actualSpannerConv.SpSchema[spannerTableId]
sessionTableParentName := sessionFileConv.SpSchema[sessionTable.ParentTable.Id].Name
spannerTableParentName := actualSpannerConv.SpSchema[spannerTable.ParentTable.Id].Name
//table names should match
if sessionTable.Name != spannerTable.Name {
return fmt.Errorf("table name don't match: session table %v, spanner table %v", sessionTable.Name, spannerTable.Name)
}
//parent table names should match
if sessionTableParentName != spannerTableParentName {
return fmt.Errorf("parent table name don't match: session table %v, parent session table name: %v, spanner table %v, parent spanner table name: %v", sessionTable.Name, sessionTableParentName, spannerTable.Name, spannerTableParentName)
}
//parent table on delete actions should match
if sessionTable.ParentTable.OnDelete != spannerTable.ParentTable.OnDelete {
return fmt.Errorf("parent table on delete actions don't match: session table %v, parent session table name: %v, spanner table %v, parent spanner table name: %v", sessionTable.Name, sessionTable.ParentTable.OnDelete, spannerTable.Name, spannerTable.ParentTable.OnDelete)
}
//number of columns should match
if len(sessionTable.ColDefs) != len(spannerTable.ColDefs) {
return fmt.Errorf("number of columns don't match: session table %v, spanner table %v", sessionTable.Name, spannerTable.Name)
}
//primary keys should be of the same length
if len(sessionTable.PrimaryKeys) != len(spannerTable.PrimaryKeys) {
return fmt.Errorf("primary keys don't match: session table primary key length %v: %v, spanner table primary key length %v: %v", sessionTable.Name, len(sessionTable.PrimaryKeys), spannerTable.Name, len(spannerTable.PrimaryKeys))
}
// Sorts both primary key slices based on primary key order
sortKeysByOrder(sessionTable.PrimaryKeys)
sortKeysByOrder(spannerTable.PrimaryKeys)
//primary keys should be of the same order
for idx, sessionPk := range sessionTable.PrimaryKeys {
sessionTablePkCol := sessionTable.ColDefs[sessionPk.ColId]
correspondingSpColId, _ := internal.GetColIdFromSpName(spannerTable.ColDefs, sessionTablePkCol.Name)
spannerTablePkCol := spannerTable.ColDefs[correspondingSpColId]
if sessionTablePkCol.Name != spannerTablePkCol.Name || sessionTable.PrimaryKeys[idx].Desc != spannerTable.PrimaryKeys[idx].Desc {
return fmt.Errorf("primary keys for table %v are not identical: session table primary key %v, spanner table primary key %v", sessionTable.Name, sessionTable.PrimaryKeys, spannerTable.PrimaryKeys)
}
}
//columns should be identical in terms of data type, name, length, nullability
for _, sessionColDef := range sessionTable.ColDefs {
correspondingSpColId, _ := internal.GetColIdFromSpName(spannerTable.ColDefs, sessionColDef.Name)
spannerColDef := spannerTable.ColDefs[correspondingSpColId]
// In case of PostgreSQL dialect, Spanner by default adds is_nullable = false to all the columns that are a part of primary key.
// Therefore, we cannot compare NotNull attributes for these columns.
if sessionFileConv.SpDialect == constants.DIALECT_POSTGRESQL && FindInPrimaryKey(sessionColDef.Id, sessionTable.PrimaryKeys) {
if sessionColDef.Name != spannerColDef.Name ||
sessionColDef.T.IsArray != spannerColDef.T.IsArray || sessionColDef.T.Len != spannerColDef.T.Len || sessionColDef.T.Name != spannerColDef.T.Name {
return fmt.Errorf("column detail for table %v don't match: session column name: %v, spanner column: %v", sessionTable.Name, sessionColDef, spannerColDef)
}
} else {
if sessionColDef.Name != spannerColDef.Name ||
sessionColDef.T.IsArray != spannerColDef.T.IsArray || sessionColDef.T.Len != spannerColDef.T.Len || sessionColDef.T.Name != spannerColDef.T.Name || sessionColDef.NotNull != spannerColDef.NotNull {
return fmt.Errorf("column detail for table %v don't match: session column: %v, spanner column: %v", sessionTable.Name, sessionColDef, spannerColDef)
}
}
}
}
return nil
}