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  })