github.com/tuhaihe/gpbackup@v1.0.3/integration/predata_shared_queries_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"database/sql"
     5  
     6  	"github.com/tuhaihe/gp-common-go-libs/structmatcher"
     7  	"github.com/tuhaihe/gp-common-go-libs/testhelper"
     8  	"github.com/tuhaihe/gpbackup/backup"
     9  	"github.com/tuhaihe/gpbackup/options"
    10  	"github.com/tuhaihe/gpbackup/testutils"
    11  
    12  	. "github.com/onsi/ginkgo/v2"
    13  	. "github.com/onsi/gomega"
    14  )
    15  
    16  var _ = Describe("backup integration tests", func() {
    17  	Describe("GetAllUserSchemas", func() {
    18  		var partitionAlteredSchemas map[string]bool
    19  		BeforeEach(func() {
    20  			partitionAlteredSchemas = make(map[string]bool)
    21  		})
    22  		It("returns user schema information", func() {
    23  			testhelper.AssertQueryRuns(connectionPool, "CREATE SCHEMA bar")
    24  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SCHEMA bar")
    25  			schemas := backup.GetAllUserSchemas(connectionPool, partitionAlteredSchemas)
    26  
    27  			schemaBar := backup.Schema{Oid: 0, Name: "bar"}
    28  			schemaPublic := backup.Schema{Oid: 2200, Name: "public"}
    29  
    30  			Expect(schemas).To(HaveLen(2))
    31  			structmatcher.ExpectStructsToMatchExcluding(&schemaBar, &schemas[0], "Oid")
    32  			structmatcher.ExpectStructsToMatchExcluding(&schemaPublic, &schemas[1], "Owner")
    33  		})
    34  
    35  		It("returns schema information for single specific schema", func() {
    36  			testhelper.AssertQueryRuns(connectionPool, "CREATE SCHEMA bar")
    37  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SCHEMA bar")
    38  			_ = backupCmdFlags.Set(options.INCLUDE_SCHEMA, "bar")
    39  
    40  			schemas := backup.GetAllUserSchemas(connectionPool, partitionAlteredSchemas)
    41  
    42  			schemaBar := backup.Schema{Oid: 0, Name: "bar"}
    43  
    44  			Expect(schemas).To(HaveLen(1))
    45  			structmatcher.ExpectStructsToMatchExcluding(&schemaBar, &schemas[0], "Oid")
    46  
    47  		})
    48  
    49  		It("returns schema information for multiple specific schemas", func() {
    50  			testhelper.AssertQueryRuns(connectionPool, "CREATE SCHEMA bar")
    51  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SCHEMA bar")
    52  			_ = backupCmdFlags.Set(options.INCLUDE_SCHEMA, "bar")
    53  			_ = backupCmdFlags.Set(options.INCLUDE_SCHEMA, "public")
    54  			schemas := backup.GetAllUserSchemas(connectionPool, partitionAlteredSchemas)
    55  
    56  			schemaBar := backup.Schema{Oid: 0, Name: "bar"}
    57  			schemaPublic := backup.Schema{Oid: 2200, Name: "public"}
    58  
    59  			Expect(schemas).To(HaveLen(2))
    60  			structmatcher.ExpectStructsToMatchExcluding(&schemaBar, &schemas[0], "Oid")
    61  			structmatcher.ExpectStructsToMatchExcluding(&schemaPublic, &schemas[1], "Owner")
    62  
    63  		})
    64  
    65  		It("returns schema information for filtered schemas with altered partition schema exceptions", func() {
    66  			testhelper.AssertQueryRuns(connectionPool, "CREATE SCHEMA bar")
    67  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SCHEMA bar")
    68  			_ = backupCmdFlags.Set(options.INCLUDE_SCHEMA, "public")
    69  			partitionAlteredSchemas["bar"] = true
    70  			schemas := backup.GetAllUserSchemas(connectionPool, partitionAlteredSchemas)
    71  
    72  			schemaBar := backup.Schema{Oid: 0, Name: "bar"}
    73  			schemaPublic := backup.Schema{Oid: 2200, Name: "public"}
    74  
    75  			Expect(schemas).To(HaveLen(2))
    76  			structmatcher.ExpectStructsToMatchExcluding(&schemaBar, &schemas[0], "Oid")
    77  			structmatcher.ExpectStructsToMatchExcluding(&schemaPublic, &schemas[1], "Owner")
    78  
    79  		})
    80  	})
    81  	Describe("GetConstraints", func() {
    82  		var (
    83  			uniqueConstraint         backup.Constraint
    84  			fkConstraint             backup.Constraint
    85  			pkConstraint             backup.Constraint
    86  			checkConstraint          backup.Constraint
    87  			partitionCheckConstraint backup.Constraint
    88  			domainConstraint         backup.Constraint
    89  			constraintInSchema       backup.Constraint
    90  		)
    91  
    92  		BeforeEach(func() {
    93  			uniqueConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "uniq2", ConType: "u", Def: sql.NullString{String: "UNIQUE (a, b)", Valid: true}, OwningObject: "public.constraints_table", IsDomainConstraint: false, IsPartitionParent: false}
    94  			fkConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "fk1", ConType: "f", Def: sql.NullString{String: "FOREIGN KEY (b) REFERENCES public.constraints_table(b)", Valid: true}, OwningObject: "public.constraints_other_table", IsDomainConstraint: false, IsPartitionParent: false}
    95  			pkConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "pk1", ConType: "p", Def: sql.NullString{String: "PRIMARY KEY (b)", Valid: true}, OwningObject: "public.constraints_table", IsDomainConstraint: false, IsPartitionParent: false}
    96  			checkConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "check1", ConType: "c", Def: sql.NullString{String: "CHECK (a <> 42)", Valid: true}, OwningObject: "public.constraints_table", IsDomainConstraint: false, IsPartitionParent: false}
    97  			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}
    98  			domainConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "check1", ConType: "c", Def: sql.NullString{String: "CHECK (VALUE <> 42)", Valid: true}, OwningObject: "public.constraint_domain", IsDomainConstraint: true, IsPartitionParent: false}
    99  			constraintInSchema = backup.Constraint{Oid: 0, Schema: "testschema", Name: "uniq2", ConType: "u", Def: sql.NullString{String: "UNIQUE (a, b)", Valid: true}, OwningObject: "testschema.constraints_table", IsDomainConstraint: false, IsPartitionParent: false}
   100  
   101  			if true {
   102  				uniqueConstraint.ConIsLocal = true
   103  				fkConstraint.ConIsLocal = true
   104  				pkConstraint.ConIsLocal = true
   105  				checkConstraint.ConIsLocal = true
   106  				partitionCheckConstraint.ConIsLocal = true
   107  				domainConstraint.ConIsLocal = true
   108  				constraintInSchema.ConIsLocal = true
   109  			}
   110  		})
   111  		Context("No constraints", func() {
   112  			It("returns an empty constraint array for a table with no constraints", func() {
   113  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.no_constraints_table(a int, b text)")
   114  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.no_constraints_table")
   115  
   116  				constraints := backup.GetConstraints(connectionPool)
   117  
   118  				Expect(constraints).To(BeEmpty())
   119  			})
   120  		})
   121  		Context("One constraint", func() {
   122  			It("returns a constraint array for a table with one UNIQUE constraint and a comment", func() {
   123  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float)")
   124  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table")
   125  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT uniq2 UNIQUE (a, b)")
   126  				testhelper.AssertQueryRuns(connectionPool, "COMMENT ON CONSTRAINT uniq2 ON public.constraints_table IS 'this is a constraint comment'")
   127  
   128  				constraints := backup.GetConstraints(connectionPool)
   129  
   130  				Expect(constraints).To(HaveLen(1))
   131  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &uniqueConstraint, "Oid")
   132  			})
   133  			It("returns a constraint array for a table with one PRIMARY KEY constraint and a comment", func() {
   134  				// In GPDB 6+, we no longer allow the distributed key to implicitly change when creating a unique index.
   135  				if false {
   136  					testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float)")
   137  				} else {
   138  					testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float) DISTRIBUTED BY (b)")
   139  				}
   140  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table")
   141  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT pk1 PRIMARY KEY (b)")
   142  				testhelper.AssertQueryRuns(connectionPool, "COMMENT ON CONSTRAINT pk1 ON public.constraints_table IS 'this is a constraint comment'")
   143  
   144  				constraints := backup.GetConstraints(connectionPool)
   145  
   146  				Expect(constraints).To(HaveLen(1))
   147  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &pkConstraint, "Oid")
   148  			})
   149  			It("returns a constraint array for a table with one FOREIGN KEY constraint", func() {
   150  				// In GPDB 6+, we no longer allow the distributed key to implicitly change when creating a unique index.
   151  				if false {
   152  					testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float)")
   153  				} else {
   154  					testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float) DISTRIBUTED BY (b)")
   155  				}
   156  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table CASCADE")
   157  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_other_table(b text)")
   158  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_other_table CASCADE")
   159  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT pk1 PRIMARY KEY (b)")
   160  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_other_table ADD CONSTRAINT fk1 FOREIGN KEY (b) REFERENCES public.constraints_table(b)")
   161  
   162  				constraints := backup.GetConstraints(connectionPool)
   163  
   164  				Expect(constraints).To(HaveLen(2))
   165  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &fkConstraint, "Oid")
   166  				structmatcher.ExpectStructsToMatchExcluding(&constraints[1], &pkConstraint, "Oid")
   167  			})
   168  			It("returns a constraint array for a table with one CHECK constraint", func() {
   169  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float)")
   170  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table")
   171  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT check1 CHECK (a <> 42)")
   172  
   173  				constraints := backup.GetConstraints(connectionPool)
   174  
   175  				Expect(constraints).To(HaveLen(1))
   176  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &checkConstraint, "Oid")
   177  			})
   178  			It("returns a constraint array for a parent partition table with one CHECK constraint", func() {
   179  				testhelper.AssertQueryRuns(connectionPool, `CREATE TABLE public.part (id int, date date, amt decimal(10,2) default 0.0) DISTRIBUTED BY (id)
   180  PARTITION BY RANGE (date)
   181        (PARTITION Jan08 START (date '2008-01-01') INCLUSIVE ,
   182        PARTITION Feb08 START (date '2008-02-01') INCLUSIVE ,
   183        PARTITION Mar08 START (date '2008-03-01') INCLUSIVE
   184        END (date '2008-04-01') EXCLUSIVE);`)
   185  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.part")
   186  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE public.part ADD CONSTRAINT check1 CHECK (id <> 0)")
   187  
   188  				constraints := backup.GetConstraints(connectionPool)
   189  
   190  				Expect(constraints).To(HaveLen(1))
   191  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &partitionCheckConstraint, "Oid")
   192  			})
   193  			It("returns a constraint array for a domain", func() {
   194  				testhelper.AssertQueryRuns(connectionPool, "CREATE DOMAIN public.constraint_domain AS int")
   195  				defer testhelper.AssertQueryRuns(connectionPool, "DROP DOMAIN public.constraint_domain")
   196  				testhelper.AssertQueryRuns(connectionPool, "ALTER DOMAIN public.constraint_domain ADD CONSTRAINT check1 CHECK (VALUE <> 42)")
   197  
   198  				constraints := backup.GetConstraints(connectionPool)
   199  
   200  				Expect(constraints).To(HaveLen(1))
   201  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &domainConstraint, "Oid")
   202  			})
   203  			It("does not return a constraint array for a table that inherits a constraint from another table", func() {
   204  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float)")
   205  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table")
   206  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT check1 CHECK (a <> 42)")
   207  
   208  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_child_table(a int, b text, c float) INHERITS (public.constraints_table)")
   209  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_child_table")
   210  
   211  				constraints := backup.GetConstraints(connectionPool)
   212  
   213  				Expect(constraints).To(HaveLen(1))
   214  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &checkConstraint, "Oid")
   215  			})
   216  			It("returns a constraint array for a table that inherits from another table and has an additional constraint", func() {
   217  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.parent_table(a int, b text, c float)")
   218  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.parent_table")
   219  
   220  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float) INHERITS (public.parent_table)")
   221  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table")
   222  
   223  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT check1 CHECK (a <> 42)")
   224  
   225  				constraints := backup.GetConstraints(connectionPool)
   226  
   227  				Expect(constraints).To(HaveLen(1))
   228  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &checkConstraint, "Oid")
   229  			})
   230  			It("returns a constraint array for a table in a specific schema", func() {
   231  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float)")
   232  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table")
   233  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT uniq2 UNIQUE (a, b)")
   234  				testhelper.AssertQueryRuns(connectionPool, "CREATE SCHEMA testschema")
   235  				defer testhelper.AssertQueryRuns(connectionPool, "DROP SCHEMA testschema")
   236  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE testschema.constraints_table(a int, b text, c float)")
   237  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE testschema.constraints_table")
   238  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY testschema.constraints_table ADD CONSTRAINT uniq2 UNIQUE (a, b)")
   239  				_ = backupCmdFlags.Set(options.INCLUDE_SCHEMA, "testschema")
   240  
   241  				constraints := backup.GetConstraints(connectionPool)
   242  
   243  				Expect(constraints).To(HaveLen(1))
   244  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &constraintInSchema, "Oid")
   245  			})
   246  			It("returns a constraint array for only the tables included in the backup set", func() {
   247  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float)")
   248  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table")
   249  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT uniq2 UNIQUE (a, b)")
   250  				testhelper.AssertQueryRuns(connectionPool, "COMMENT ON CONSTRAINT uniq2 ON public.constraints_table IS 'this is a constraint comment'")
   251  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.other_table(d bool, e float)")
   252  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.other_table")
   253  
   254  				constraintsOid := testutils.OidFromObjectName(connectionPool, "public", "constraints_table", backup.TYPE_RELATION)
   255  				otherOid := testutils.OidFromObjectName(connectionPool, "public", "other_table", backup.TYPE_RELATION)
   256  				tables := []backup.Relation{{Oid: constraintsOid, Schema: "public", Name: "constraints_table"}}
   257  				constraints := backup.GetConstraints(connectionPool, tables...)
   258  				Expect(constraints).To(HaveLen(1))
   259  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &uniqueConstraint, "Oid")
   260  
   261  				tables = []backup.Relation{{Oid: otherOid, Schema: "public", Name: "other_table"}}
   262  				constraints = backup.GetConstraints(connectionPool, tables...)
   263  				Expect(constraints).To(BeEmpty())
   264  			})
   265  			It("returns a constraint array without contraints on tables in the exclude set", func() {
   266  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float)")
   267  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table")
   268  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT uniq2 UNIQUE (a, b)")
   269  				testhelper.AssertQueryRuns(connectionPool, "COMMENT ON CONSTRAINT uniq2 ON public.constraints_table IS 'this is a constraint comment'")
   270  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.other_table(d bool, e float)")
   271  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.other_table")
   272  
   273  				_ = backupCmdFlags.Set(options.EXCLUDE_RELATION, "public.other_table")
   274  				defer backupCmdFlags.Set(options.EXCLUDE_RELATION, "")
   275  				constraints := backup.GetConstraints(connectionPool)
   276  				Expect(constraints).To(HaveLen(1))
   277  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &uniqueConstraint, "Oid")
   278  
   279  				_ = backupCmdFlags.Set(options.EXCLUDE_RELATION, "public.constraints_table")
   280  				backup.SetFilterRelationClause("")
   281  				constraints = backup.GetConstraints(connectionPool)
   282  				Expect(constraints).To(BeEmpty())
   283  			})
   284  		})
   285  		Context("Multiple constraints 4", func() {
   286  			It("returns a constraint array for a table with multiple constraints", func() {
   287  				testutils.SkipIfNot4(connectionPool)
   288  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float) DISTRIBUTED BY (b)")
   289  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table CASCADE")
   290  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_other_table(b text)")
   291  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_other_table CASCADE")
   292  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT uniq2 UNIQUE (a, b)")
   293  				testhelper.AssertQueryRuns(connectionPool, "COMMENT ON CONSTRAINT uniq2 ON public.constraints_table IS 'this is a constraint comment'")
   294  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT pk1 PRIMARY KEY (b)")
   295  				testhelper.AssertQueryRuns(connectionPool, "COMMENT ON CONSTRAINT pk1 ON public.constraints_table IS 'this is a constraint comment'")
   296  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_other_table ADD CONSTRAINT fk1 FOREIGN KEY (b) REFERENCES public.constraints_table(b)")
   297  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT check1 CHECK (a <> 42)")
   298  
   299  				constraints := backup.GetConstraints(connectionPool)
   300  
   301  				Expect(constraints).To(HaveLen(4))
   302  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &checkConstraint, "Oid")
   303  				structmatcher.ExpectStructsToMatchExcluding(&constraints[1], &fkConstraint, "Oid")
   304  				structmatcher.ExpectStructsToMatchExcluding(&constraints[2], &pkConstraint, "Oid")
   305  				structmatcher.ExpectStructsToMatchExcluding(&constraints[3], &uniqueConstraint, "Oid")
   306  			})
   307  		})
   308  		Context("Multiple constraints 5+", func() {
   309  			It("returns a constraint array for a table with multiple constraints", func() {
   310  				testutils.SkipIfBefore5(connectionPool)
   311  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_table(a int, b text, c float) DISTRIBUTED BY (b)")
   312  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_table CASCADE")
   313  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.constraints_other_table(a int, b text)")
   314  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.constraints_other_table CASCADE")
   315  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT uniq2 UNIQUE (a, b)")
   316  				testhelper.AssertQueryRuns(connectionPool, "COMMENT ON CONSTRAINT uniq2 ON public.constraints_table IS 'this is a constraint comment'")
   317  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT pk1 PRIMARY KEY (a,b)")
   318  				testhelper.AssertQueryRuns(connectionPool, "COMMENT ON CONSTRAINT pk1 ON public.constraints_table IS 'this is a constraint comment'")
   319  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_other_table ADD CONSTRAINT fk1 FOREIGN KEY (a,b) REFERENCES public.constraints_table(a,b)")
   320  				testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.constraints_table ADD CONSTRAINT check1 CHECK (a <> 42)")
   321  
   322  				constraints := backup.GetConstraints(connectionPool)
   323  
   324  				Expect(constraints).To(HaveLen(4))
   325  				structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &checkConstraint, "Oid")
   326  
   327  				fkConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "fk1", ConType: "f", Def: sql.NullString{String: "FOREIGN KEY (a, b) REFERENCES public.constraints_table(a, b)", Valid: true}, OwningObject: "public.constraints_other_table", IsDomainConstraint: false, IsPartitionParent: false}
   328  				if true {
   329  					fkConstraint.ConIsLocal = true
   330  				}
   331  				structmatcher.ExpectStructsToMatchExcluding(&constraints[1], &fkConstraint, "Oid")
   332  
   333  				pkConstraint = backup.Constraint{Oid: 0, Schema: "public", Name: "pk1", ConType: "p", Def: sql.NullString{String: "PRIMARY KEY (a, b)", Valid: true}, OwningObject: "public.constraints_table", IsDomainConstraint: false, IsPartitionParent: false}
   334  				if true {
   335  					pkConstraint.ConIsLocal = true
   336  				}
   337  				structmatcher.ExpectStructsToMatchExcluding(&constraints[2], &pkConstraint, "Oid")
   338  				structmatcher.ExpectStructsToMatchExcluding(&constraints[3], &uniqueConstraint, "Oid")
   339  			})
   340  		})
   341  		It("returns a constraint array for a table with PRIMARY KEY constraint that includes non-key columns", func() {
   342  			testutils.SkipIfBefore7(connectionPool)
   343  			testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.table_with_constr (a int NOT NULL, b int NOT NULL, c int, d int) DISTRIBUTED BY (a);")
   344  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.table_with_constr")
   345  			testhelper.AssertQueryRuns(connectionPool, "ALTER TABLE ONLY public.table_with_constr ADD CONSTRAINT table_with_constr_pkey PRIMARY KEY (a, b) INCLUDE (c, d);")
   346  
   347  			constraints := backup.GetConstraints(connectionPool)
   348  			expectedConstraint := backup.Constraint{Oid: 0, Schema: "public", Name: "table_with_constr_pkey", ConType: "p", Def: sql.NullString{String: "PRIMARY KEY (a, b) INCLUDE (c, d)", Valid: true}, ConIsLocal: true, OwningObject: "public.table_with_constr", IsDomainConstraint: false, IsPartitionParent: false}
   349  
   350  			Expect(constraints).To(HaveLen(1))
   351  			structmatcher.ExpectStructsToMatchExcluding(&constraints[0], &expectedConstraint, "Oid")
   352  		})
   353  	})
   354  	Describe("GetAccessMethods", func() {
   355  		It("returns information for user defined access methods", func() {
   356  			testutils.SkipIfBefore7(connectionPool)
   357  
   358  			testhelper.AssertQueryRuns(connectionPool, "CREATE ACCESS METHOD test_tableam_table TYPE TABLE HANDLER heap_tableam_handler;")
   359  			defer testhelper.AssertQueryRuns(connectionPool, "DROP ACCESS METHOD test_tableam_table;")
   360  
   361  			testhelper.AssertQueryRuns(connectionPool, "CREATE ACCESS METHOD test_tableam_index TYPE INDEX HANDLER gisthandler;")
   362  			defer testhelper.AssertQueryRuns(connectionPool, "DROP ACCESS METHOD test_tableam_index;")
   363  
   364  			accessMethods := backup.GetAccessMethods(connectionPool)
   365  
   366  			accessMethodTable := backup.AccessMethod{Oid: 1, Name: "test_tableam_table", Handler: "heap_tableam_handler", Type: "t"}
   367  			accessMethodIndex := backup.AccessMethod{Oid: 2, Name: "test_tableam_index", Handler: "gisthandler", Type: "i"}
   368  
   369  			Expect(accessMethods).To(HaveLen(2))
   370  			structmatcher.ExpectStructsToMatchExcluding(&accessMethodTable, &accessMethods[0], "Oid")
   371  			structmatcher.ExpectStructsToMatchExcluding(&accessMethodIndex, &accessMethods[1], "Oid")
   372  
   373  		})
   374  	})
   375  })