github.com/cloudberrydb/gpbackup@v1.0.3-0.20240118031043-5410fd45eed6/integration/predata_shared_create_test.go (about) 1 package integration 2 3 import ( 4 "database/sql" 5 6 "github.com/cloudberrydb/gp-common-go-libs/structmatcher" 7 "github.com/cloudberrydb/gp-common-go-libs/testhelper" 8 "github.com/cloudberrydb/gpbackup/backup" 9 "github.com/cloudberrydb/gpbackup/testutils" 10 11 . "github.com/onsi/ginkgo/v2" 12 . "github.com/onsi/gomega" 13 ) 14 15 var _ = Describe("backup integration create statement tests", func() { 16 BeforeEach(func() { 17 tocfile, backupfile = testutils.InitializeTestTOC(buffer, "predata") 18 }) 19 Describe("PrintCreateSchemaStatements", func() { 20 var partitionAlteredSchemas map[string]bool 21 BeforeEach(func() { 22 partitionAlteredSchemas = make(map[string]bool) 23 }) 24 It("creates a non public schema", func() { 25 schemas := []backup.Schema{{Oid: 0, Name: "test_schema"}} 26 schemaMetadata := testutils.DefaultMetadataMap("SCHEMA", true, true, true, includeSecurityLabels) 27 28 backup.PrintCreateSchemaStatements(backupfile, tocfile, schemas, schemaMetadata) 29 30 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 31 defer testhelper.AssertQueryRuns(connectionPool, "DROP SCHEMA test_schema") 32 33 resultSchemas := backup.GetAllUserSchemas(connectionPool, partitionAlteredSchemas) 34 35 Expect(resultSchemas).To(HaveLen(2)) 36 Expect(resultSchemas[0].Name).To(Equal("public")) 37 38 structmatcher.ExpectStructsToMatchExcluding(&schemas[0], &resultSchemas[1], "Oid") 39 }) 40 41 It("modifies the public schema", func() { 42 schemas := []backup.Schema{{Oid: 2200, Name: "public"}} 43 schemaMetadata := testutils.DefaultMetadataMap("SCHEMA", true, true, true, includeSecurityLabels) 44 45 backup.PrintCreateSchemaStatements(backupfile, tocfile, schemas, schemaMetadata) 46 47 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 48 defer testhelper.AssertQueryRuns(connectionPool, "ALTER SCHEMA public OWNER TO anothertestrole") 49 defer testhelper.AssertQueryRuns(connectionPool, "COMMENT ON SCHEMA public IS 'standard public schema'") 50 51 resultSchemas := backup.GetAllUserSchemas(connectionPool, partitionAlteredSchemas) 52 53 Expect(resultSchemas).To(HaveLen(1)) 54 structmatcher.ExpectStructsToMatchExcluding(&schemas[0], &resultSchemas[0]) 55 }) 56 }) 57 Describe("PrintConstraintStatement", func() { 58 var ( 59 uniqueConstraint backup.Constraint 60 pkConstraint backup.Constraint 61 fkConstraint backup.Constraint 62 checkConstraint backup.Constraint 63 partitionCheckConstraint backup.Constraint 64 partitionChildConstraint backup.Constraint 65 partitionIntmdConstraint backup.Constraint 66 partitionParentConstraint backup.Constraint 67 objectMetadata backup.ObjectMetadata 68 ) 69 BeforeEach(func() { 70 uniqueConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "uniq2", ConType: "u", Def: sql.NullString{String: "UNIQUE (a, b)", Valid: true}, OwningObject: "public.testtable", IsDomainConstraint: false, IsPartitionParent: false} 71 pkConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "constraints_other_table_pkey", ConType: "p", Def: sql.NullString{String: "PRIMARY KEY (b)", Valid: true}, OwningObject: "public.constraints_other_table", IsDomainConstraint: false, IsPartitionParent: false} 72 fkConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "fk1", ConType: "f", Def: sql.NullString{String: "FOREIGN KEY (b) REFERENCES public.constraints_other_table(b)", Valid: true}, OwningObject: "public.testtable", IsDomainConstraint: false, IsPartitionParent: false} 73 checkConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "check1", ConType: "c", Def: sql.NullString{String: "CHECK (a <> 42)", Valid: true}, OwningObject: "public.testtable", IsDomainConstraint: false, IsPartitionParent: false} 74 partitionCheckConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "check1", ConType: "c", Def: sql.NullString{String: "CHECK (id <> 0)", Valid: true}, OwningObject: "public.part", IsDomainConstraint: false, IsPartitionParent: true} 75 partitionIntmdConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "id_unique", ConType: "u", Def: sql.NullString{String: "UNIQUE (id)", Valid: true}, OwningObject: "public.part_one", IsDomainConstraint: false, IsPartitionParent: true} 76 partitionChildConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "id_unique", ConType: "u", Def: sql.NullString{String: "UNIQUE (id)", Valid: true}, OwningObject: "public.part_one", IsDomainConstraint: false, IsPartitionParent: false} 77 partitionParentConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "check_year", ConType: "c", Def: sql.NullString{String: "CHECK (year < 3000)", Valid: true}, OwningObject: "public.part", IsDomainConstraint: false, IsPartitionParent: true} 78 testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.testtable(a int, b text) DISTRIBUTED BY (b)") 79 objectMetadata = testutils.DefaultMetadata("CONSTRAINT", false, false, false, false) 80 81 if true { 82 uniqueConstraint.ConIsLocal = true 83 pkConstraint.ConIsLocal = true 84 fkConstraint.ConIsLocal = true 85 checkConstraint.ConIsLocal = true 86 partitionCheckConstraint.ConIsLocal = true 87 partitionIntmdConstraint.ConIsLocal = true 88 partitionChildConstraint.ConIsLocal = true 89 partitionParentConstraint.ConIsLocal = true 90 } 91 }) 92 AfterEach(func() { 93 testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.testtable CASCADE") 94 }) 95 It("creates a unique constraint", func() { 96 backup.PrintConstraintStatement(backupfile, tocfile, uniqueConstraint, objectMetadata) 97 98 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 99 100 resultConstraints := backup.GetConstraints(connectionPool) 101 102 Expect(resultConstraints).To(HaveLen(1)) 103 structmatcher.ExpectStructsToMatchExcluding(&uniqueConstraint, &resultConstraints[0], "Oid") 104 }) 105 It("creates a primary key constraint", func() { 106 backup.PrintConstraintStatement(backupfile, tocfile, pkConstraint, objectMetadata) 107 108 testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_other_table(b text)") 109 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_other_table CASCADE") 110 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 111 112 resultConstraints := backup.GetConstraints(connectionPool) 113 114 Expect(resultConstraints).To(HaveLen(1)) 115 structmatcher.ExpectStructsToMatchExcluding(&pkConstraint, &resultConstraints[0], "Oid") 116 }) 117 It("creates a foreign key constraint", func() { 118 backup.PrintConstraintStatement(backupfile, tocfile, fkConstraint, objectMetadata) 119 120 testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_other_table(b text PRIMARY KEY)") 121 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_other_table CASCADE") 122 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 123 124 resultConstraints := backup.GetConstraints(connectionPool) 125 126 Expect(resultConstraints).To(HaveLen(2)) 127 structmatcher.ExpectStructsToMatchExcluding(&pkConstraint, &resultConstraints[0], "Oid") 128 structmatcher.ExpectStructsToMatchExcluding(&fkConstraint, &resultConstraints[1], "Oid") 129 }) 130 It("creates a check constraint", func() { 131 backup.PrintConstraintStatement(backupfile, tocfile, checkConstraint, objectMetadata) 132 133 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 134 135 resultConstraints := backup.GetConstraints(connectionPool) 136 137 Expect(resultConstraints).To(HaveLen(1)) 138 structmatcher.ExpectStructsToMatchExcluding(&checkConstraint, &resultConstraints[0], "Oid") 139 }) 140 It("creates multiple constraints on one table", func() { 141 backup.PrintConstraintStatement(backupfile, tocfile, checkConstraint, objectMetadata) 142 backup.PrintConstraintStatement(backupfile, tocfile, uniqueConstraint, objectMetadata) 143 backup.PrintConstraintStatement(backupfile, tocfile, fkConstraint, objectMetadata) 144 145 testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_other_table(b text PRIMARY KEY)") 146 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_other_table CASCADE") 147 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 148 149 resultConstraints := backup.GetConstraints(connectionPool) 150 151 Expect(resultConstraints).To(HaveLen(4)) 152 structmatcher.ExpectStructsToMatchExcluding(&checkConstraint, &resultConstraints[0], "Oid") 153 structmatcher.ExpectStructsToMatchExcluding(&pkConstraint, &resultConstraints[1], "Oid") 154 structmatcher.ExpectStructsToMatchExcluding(&fkConstraint, &resultConstraints[2], "Oid") 155 structmatcher.ExpectStructsToMatchExcluding(&uniqueConstraint, &resultConstraints[3], "Oid") 156 }) 157 It("creates a check constraint on a parent partition table", func() { 158 backup.PrintConstraintStatement(backupfile, tocfile, partitionCheckConstraint, objectMetadata) 159 160 testhelper.AssertQueryRuns(connectionPool, `CREATE TABLE public.part (id int, year int) 161 DISTRIBUTED BY (id) 162 PARTITION BY RANGE (year) 163 ( START (2007) END (2008) EVERY (1), 164 DEFAULT PARTITION extra ); `) 165 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.part CASCADE") 166 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 167 168 resultConstraints := backup.GetConstraints(connectionPool) 169 170 Expect(resultConstraints).To(HaveLen(1)) 171 structmatcher.ExpectStructsToMatchExcluding(&partitionCheckConstraint, &resultConstraints[0], "Oid") 172 }) 173 It("creates a unique constraint on an intermediate partition table", func() { 174 // TODO -- this seems like it should work on 6. See about flexing the syntax below to 6-supported 175 testutils.SkipIfBefore7(connectionPool) 176 testhelper.AssertQueryRuns(connectionPool, `CREATE TABLE public.part (id int, year int) 177 DISTRIBUTED BY (id) 178 PARTITION BY RANGE (year);`) 179 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.part CASCADE") 180 181 testhelper.AssertQueryRuns(connectionPool, `CREATE TABLE public.part_one PARTITION OF public.part 182 FOR VALUES FROM (2007) TO (2010) PARTITION BY RANGE (id);`) 183 testhelper.AssertQueryRuns(connectionPool, `ALTER TABLE public.part_one ADD CONSTRAINT id_unique UNIQUE (id);`) 184 185 testhelper.AssertQueryRuns(connectionPool, `CREATE TABLE public.part_two PARTITION OF public.part_one 186 FOR VALUES FROM (0) TO (100);`) 187 188 resultConstraints := backup.GetConstraints(connectionPool) 189 Expect(resultConstraints).To(HaveLen(1)) 190 structmatcher.ExpectStructsToMatchExcluding(&partitionIntmdConstraint, &resultConstraints[0], "Oid") 191 }) 192 It("creates a unique constraint on a child partition table", func() { 193 // TODO -- this seems like it should work on 6. See about flexing the syntax below to 6-supported 194 testutils.SkipIfBefore7(connectionPool) 195 testhelper.AssertQueryRuns(connectionPool, `CREATE TABLE public.part (id int, year int) 196 DISTRIBUTED BY (id) 197 PARTITION BY RANGE (year);`) 198 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.part CASCADE") 199 200 testhelper.AssertQueryRuns(connectionPool, `CREATE TABLE public.part_one PARTITION OF public.part 201 FOR VALUES FROM (2007) TO (2010);`) 202 testhelper.AssertQueryRuns(connectionPool, `ALTER TABLE public.part_one ADD CONSTRAINT id_unique UNIQUE (id);`) 203 204 resultConstraints := backup.GetConstraints(connectionPool) 205 Expect(resultConstraints).To(HaveLen(1)) 206 structmatcher.ExpectStructsToMatchExcluding(&partitionChildConstraint, &resultConstraints[0], "Oid") 207 }) 208 It("creates two unique constraints, one each on parent and child partition tables", func() { 209 // TODO -- this seems like it should work on 6. See about flexing the syntax below to 6-supported 210 testutils.SkipIfBefore7(connectionPool) 211 testhelper.AssertQueryRuns(connectionPool, `CREATE TABLE public.part (id int, year int) 212 DISTRIBUTED BY (id) 213 PARTITION BY RANGE (year);`) 214 defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.part CASCADE") 215 testhelper.AssertQueryRuns(connectionPool, `ALTER TABLE public.part ADD CONSTRAINT check_year CHECK (year < 3000);`) 216 217 testhelper.AssertQueryRuns(connectionPool, `CREATE TABLE public.part_one PARTITION OF public.part 218 FOR VALUES FROM (2007) TO (2010);`) 219 testhelper.AssertQueryRuns(connectionPool, `ALTER TABLE public.part_one ADD CONSTRAINT id_unique UNIQUE (id);`) 220 221 resultConstraints := backup.GetConstraints(connectionPool) 222 Expect(resultConstraints).To(HaveLen(2)) 223 if resultConstraints[0].Name == "check_year" { 224 structmatcher.ExpectStructsToMatchExcluding(&partitionParentConstraint, &resultConstraints[0], "Oid") 225 structmatcher.ExpectStructsToMatchExcluding(&partitionChildConstraint, &resultConstraints[1], "Oid") 226 } else { 227 structmatcher.ExpectStructsToMatchExcluding(&partitionParentConstraint, &resultConstraints[1], "Oid") 228 structmatcher.ExpectStructsToMatchExcluding(&partitionChildConstraint, &resultConstraints[0], "Oid") 229 } 230 231 }) 232 }) 233 Describe("PrintAccessMethodStatement", func() { 234 It("creates user defined access method for tables and indexes", func() { 235 testutils.SkipIfBefore7(connectionPool) 236 237 accessMethodTable := backup.AccessMethod{Oid: 1, Name: "test_tableam_table", Handler: "heap_tableam_handler", Type: "t"} 238 accessMethodIndex := backup.AccessMethod{Oid: 2, Name: "test_tableam_index", Handler: "gisthandler", Type: "i"} 239 accessMethods := []backup.AccessMethod{accessMethodTable, accessMethodIndex} 240 backup.PrintAccessMethodStatements(backupfile, tocfile, accessMethods, backup.MetadataMap{}) 241 242 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 243 defer testhelper.AssertQueryRuns(connectionPool, "DROP ACCESS METHOD test_tableam_table;") 244 defer testhelper.AssertQueryRuns(connectionPool, "DROP ACCESS METHOD test_tableam_index;") 245 246 resultAccessMethods := backup.GetAccessMethods(connectionPool) 247 Expect(resultAccessMethods).To(HaveLen(2)) 248 structmatcher.ExpectStructsToMatchExcluding(&resultAccessMethods[0], &accessMethodTable, "Oid") 249 structmatcher.ExpectStructsToMatchExcluding(&resultAccessMethods[1], &accessMethodIndex, "Oid") 250 }) 251 }) 252 Describe("GUC-printing functions", func() { 253 gucs := backup.SessionGUCs{ClientEncoding: "UTF8"} 254 Describe("PrintSessionGUCs", func() { 255 It("prints the default session GUCs", func() { 256 backup.PrintSessionGUCs(backupfile, tocfile, gucs) 257 258 //We just want to check that these queries run successfully, no setup required 259 testhelper.AssertQueryRuns(connectionPool, buffer.String()) 260 }) 261 262 }) 263 }) 264 })