| package backup_test |
| |
| import ( |
| "database/sql" |
| "database/sql/driver" |
| |
| "github.com/DATA-DOG/go-sqlmock" |
| "github.com/apache/cloudberry-backup/backup" |
| "github.com/apache/cloudberry-go-libs/structmatcher" |
| |
| . "github.com/onsi/ginkgo/v2" |
| . "github.com/onsi/gomega" |
| ) |
| |
| var _ = Describe("backup/queries_postdata tests", func() { |
| Describe("GetIndexes", func() { |
| It("GetIndexes properly handles NULL index definitions", func() { |
| if connectionPool.Version.IsGPDB() && connectionPool.Version.Before("6") { |
| implicitIndexNamesHeader := []string{"string"} |
| implicitIndexNamesFakeRows := sqlmock.NewRows(implicitIndexNamesHeader) |
| mock.ExpectQuery(`SELECT (.*)`).WillReturnRows(implicitIndexNamesFakeRows) |
| } |
| |
| header := []string{"oid", "name", "owningschema", "owningtable", "tablespace", "def", "isclustered", "supportsconstraint", "isreplicaidentity"} |
| rowOne := []driver.Value{"1", "mock_index", "mock_schema", "mock_table", "mock_tablespace", "mock_def", false, false, false} |
| rowTwo := []driver.Value{"1", "mock_index2", "mock_schema2", "mock_table2", "mock_tablespace2", nil, false, false, false} |
| fakeRows := sqlmock.NewRows(header).AddRow(rowOne...).AddRow(rowTwo...) |
| mock.ExpectQuery(`SELECT (.*)`).WillReturnRows(fakeRows) |
| result := backup.GetIndexes(connectionPool) |
| |
| // Expect the GetIndexes function to return only the 1st row since the 2nd row has a NULL index definition |
| expectedResult := []backup.IndexDefinition{{Oid: 1, Name: "mock_index", OwningSchema: "mock_schema", OwningTable: "mock_table", |
| Tablespace: "mock_tablespace", Def: sql.NullString{String: "mock_def", Valid: true}, IsClustered: false, |
| SupportsConstraint: false, IsReplicaIdentity: false}} |
| Expect(result).To(HaveLen(1)) |
| structmatcher.ExpectStructsToMatch(&expectedResult[0], &result[0]) |
| }) |
| }) |
| Describe("RenameExchangedPartitionIndexes", func() { |
| It("RenameExchangedPartitionIndexes properly renames exchanged indexes to match their owning tables", func() { |
| if !(connectionPool.Version.IsGPDB() && connectionPool.Version.Is("6")) { |
| Skip("Test only applies to GPDB version 6") |
| } |
| indexes := []backup.IndexDefinition{ |
| {Oid: 1, Name: "mock_index", OwningSchema: "mock_schema", OwningTable: "mock_table", |
| Tablespace: "mock_tablespace", Def: sql.NullString{String: "CREATE INDEX mock_index ON mock_schema.mock_table", Valid: true}, IsClustered: false, |
| SupportsConstraint: false, IsReplicaIdentity: false}, |
| {Oid: 2, Name: "realTableName_c_idx", OwningSchema: "mock_schema", OwningTable: "pt_heap_tab_1_prt_pqr", |
| Tablespace: "mock_tablespace", Def: sql.NullString{String: "CREATE INDEX realTableName_c_idx ON mock_schema.pt_heap_tab_1_prt_pqr", Valid: true}, IsClustered: false, |
| SupportsConstraint: false, IsReplicaIdentity: false}, |
| {Oid: 3, Name: "pt_heap_tab_1_prt_pqr_a_idx", OwningSchema: "mock_schema", OwningTable: "realTableName", |
| Tablespace: "mock_tablespace", Def: sql.NullString{String: "CREATE INDEX pt_heap_tab_1_prt_pqr_a_idx ON mock_schema.realTableName", Valid: true}, IsClustered: false, |
| SupportsConstraint: false, IsReplicaIdentity: false}} |
| header := []string{"indexname", "tablename", "relispartition"} |
| rowOne := []driver.Value{"mock_index", "mock_table", "false"} |
| rowTwo := []driver.Value{"pt_heap_tab_1_prt_pqr_a_idx", "realTableName", "false"} |
| rowThree := []driver.Value{"realTableName_c_idx", "pt_heap_tab", "true"} |
| fakeRows := sqlmock.NewRows(header).AddRow(rowOne...).AddRow(rowTwo...).AddRow(rowThree...) |
| mock.ExpectQuery(`SELECT (.*)`).WillReturnRows(fakeRows) |
| backup.RenameExchangedPartitionIndexes(connectionPool, &indexes) |
| |
| Expect(indexes).To(HaveLen(3)) |
| for _, idx := range indexes { |
| switch idx.Oid { |
| case 1: |
| Expect(idx.Name).To(Equal("mock_index")) |
| Expect(idx.Def.String).To(Equal("CREATE INDEX mock_index ON mock_schema.mock_table")) |
| case 2: |
| // We do not rename the partition leaf index here, as it will be |
| // system-generated correctly when we apply the index to the partition root table. |
| Expect(idx.Name).To(Equal("realTableName_c_idx")) |
| Expect(idx.Def.String).To(Equal("CREATE INDEX realTableName_c_idx ON mock_schema.pt_heap_tab_1_prt_pqr")) |
| case 3: |
| Expect(idx.Name).To(Equal("realTableName_c_idx")) |
| Expect(idx.Def.String).To(Equal("CREATE INDEX realTableName_c_idx ON mock_schema.realTableName")) |
| default: |
| Fail("Unexpected index OID found") |
| } |
| } |
| }) |
| }) |
| Describe("GetRules", func() { |
| It("GetRules properly handles NULL rule definitions", func() { |
| header := []string{"oid", "name", "owningschema", "owningtable", "def"} |
| rowOne := []driver.Value{"1", "mock_rule", "mock_schema", "mock_table", "mock_def"} |
| rowTwo := []driver.Value{"2", "mock_rule2", "mock_schema2", "mock_table2", nil} |
| fakeRows := sqlmock.NewRows(header).AddRow(rowOne...).AddRow(rowTwo...) |
| mock.ExpectQuery(`SELECT (.*)`).WillReturnRows(fakeRows) |
| result := backup.GetRules(connectionPool) |
| |
| // Expect the GetRules function to return only the 1st row since the 2nd row has a NULL rule definition |
| expectedResult := []backup.RuleDefinition{{Oid: 1, Name: "mock_rule", OwningSchema: "mock_schema", OwningTable: "mock_table", Def: sql.NullString{String: "mock_def", Valid: true}}} |
| Expect(result).To(HaveLen(1)) |
| structmatcher.ExpectStructsToMatch(&expectedResult[0], &result[0]) |
| }) |
| }) |
| Describe("GetTriggers", func() { |
| It("GetTriggers properly handles NULL trigger definitions", func() { |
| header := []string{"oid", "name", "owningschema", "owningtable", "def"} |
| rowOne := []driver.Value{"1", "mock_trigger", "mock_schema", "mock_table", "mock_def"} |
| rowTwo := []driver.Value{"2", "mock_trigger2", "mock_schema2", "mock_table2", nil} |
| fakeRows := sqlmock.NewRows(header).AddRow(rowOne...).AddRow(rowTwo...) |
| mock.ExpectQuery(`SELECT (.*)`).WillReturnRows(fakeRows) |
| result := backup.GetTriggers(connectionPool) |
| |
| // Expect the GetTriggers function to return only the 1st row since the 2nd row has a NULL trigger definition |
| expectedResult := []backup.TriggerDefinition{{Oid: 1, Name: "mock_trigger", OwningSchema: "mock_schema", OwningTable: "mock_table", Def: sql.NullString{String: "mock_def", Valid: true}}} |
| Expect(result).To(HaveLen(1)) |
| structmatcher.ExpectStructsToMatch(&expectedResult[0], &result[0]) |
| }) |
| }) |
| }) |