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

     1  package integration
     2  
     3  import (
     4  	"database/sql"
     5  	"fmt"
     6  	"math"
     7  
     8  	"github.com/tuhaihe/gp-common-go-libs/structmatcher"
     9  	"github.com/tuhaihe/gp-common-go-libs/testhelper"
    10  	"github.com/tuhaihe/gpbackup/backup"
    11  	"github.com/tuhaihe/gpbackup/testutils"
    12  
    13  	. "github.com/onsi/ginkgo/v2"
    14  	. "github.com/onsi/gomega"
    15  )
    16  
    17  var _ = Describe("backup integration create statement tests", func() {
    18  	BeforeEach(func() {
    19  		tocfile, backupfile = testutils.InitializeTestTOC(buffer, "predata")
    20  	})
    21  	Describe("PrintRegularTableCreateStatement", func() {
    22  		var (
    23  			extTableEmpty                 backup.ExternalTableDefinition
    24  			testTable                     backup.Table
    25  			partitionPartFalseExpectation = "false"
    26  		)
    27  		BeforeEach(func() {
    28  			extTableEmpty = backup.ExternalTableDefinition{Oid: 0, Type: -2, Protocol: -2, Location: sql.NullString{String: "", Valid: true}, ExecLocation: "ALL_SEGMENTS", FormatType: "t", FormatOpts: "", Command: "", RejectLimit: 0, RejectLimitType: "", ErrTableName: "", ErrTableSchema: "", Encoding: "UTF-8", Writable: false, URIs: nil}
    29  			testTable = backup.Table{
    30  				Relation:        backup.Relation{Schema: "public", Name: "testtable"},
    31  				TableDefinition: backup.TableDefinition{DistPolicy: "DISTRIBUTED RANDOMLY", ExtTableDef: extTableEmpty, Inherits: []string{}},
    32  			}
    33  			if true {
    34  				partitionPartFalseExpectation = "'false'"
    35  				testTable.ReplicaIdentity = "d"
    36  			}
    37  		})
    38  		AfterEach(func() {
    39  			testhelper.AssertQueryRuns(connectionPool, "DROP TABLE IF EXISTS public.testtable")
    40  		})
    41  		It("creates a table with no attributes", func() {
    42  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
    43  
    44  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
    45  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
    46  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
    47  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
    48  		})
    49  		It("creates a table of a type", func() {
    50  			testutils.SkipIfBefore6(connectionPool)
    51  			testhelper.AssertQueryRuns(connectionPool, `CREATE TYPE public.some_type AS (i text, j numeric)`)
    52  			defer testhelper.AssertQueryRuns(connectionPool, `DROP TYPE public.some_type CASCADE`)
    53  
    54  			rowOne := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "i", NotNull: false, HasDefault: false, Type: "text", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
    55  			rowTwo := backup.ColumnDefinition{Oid: 0, Num: 2, Name: "j", NotNull: false, HasDefault: false, Type: "numeric", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
    56  			testTable.ColumnDefs = []backup.ColumnDefinition{rowOne, rowTwo}
    57  
    58  			testTable.TableType = "public.some_type"
    59  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
    60  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
    61  
    62  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
    63  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
    64  
    65  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
    66  		})
    67  
    68  		It("creates a basic heap table", func() {
    69  			rowOne := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "i", NotNull: false, HasDefault: false, Type: "integer", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
    70  			rowTwo := backup.ColumnDefinition{Oid: 0, Num: 2, Name: "j", NotNull: false, HasDefault: false, Type: "character varying(20)", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
    71  			testTable.ColumnDefs = []backup.ColumnDefinition{rowOne, rowTwo}
    72  
    73  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
    74  
    75  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
    76  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
    77  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
    78  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
    79  		})
    80  		It("creates a complex heap table", func() {
    81  			rowOneDefault := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "i", NotNull: false, HasDefault: true, Type: "integer", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "(42)", Comment: ""}
    82  			rowNotNullDefault := backup.ColumnDefinition{Oid: 0, Num: 2, Name: "j", NotNull: true, HasDefault: true, Type: "character varying(20)", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "('bar'::text)", Comment: ""}
    83  			rowNonDefaultStorageAndStats := backup.ColumnDefinition{Oid: 0, Num: 3, Name: "k", NotNull: false, HasDefault: false, Type: "text", Encoding: "", StatTarget: 3, StorageType: "PLAIN", DefaultVal: "", Comment: ""}
    84  			if true {
    85  				testhelper.AssertQueryRuns(connectionPool, "CREATE COLLATION public.some_coll (lc_collate = 'POSIX', lc_ctype = 'POSIX')")
    86  				defer testhelper.AssertQueryRuns(connectionPool, "DROP COLLATION public.some_coll CASCADE")
    87  				rowNonDefaultStorageAndStats.Collation = "public.some_coll"
    88  			}
    89  			testTable.DistPolicy = "DISTRIBUTED BY (i, j)"
    90  			testTable.ColumnDefs = []backup.ColumnDefinition{rowOneDefault, rowNotNullDefault, rowNonDefaultStorageAndStats}
    91  
    92  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
    93  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
    94  
    95  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
    96  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
    97  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
    98  		})
    99  		It("creates a basic append-optimized column-oriented table", func() {
   100  			rowOne := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "i", NotNull: false, HasDefault: false, Type: "integer", Encoding: "compresstype=zlib,blocksize=32768,compresslevel=1", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   101  			rowTwo := backup.ColumnDefinition{Oid: 0, Num: 2, Name: "j", NotNull: false, HasDefault: false, Type: "character varying(20)", Encoding: "compresstype=zlib,blocksize=32768,compresslevel=1", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   102  			testTable.StorageOpts = "appendonly=true, orientation=column, fillfactor=42, compresstype=zlib, blocksize=32768, compresslevel=1"
   103  			if true {
   104  				// Apparently, fillfactor is not backwards compatible with GPDB 7
   105  				testTable.StorageOpts = "appendonly=true, orientation=column, compresstype=zlib, blocksize=32768, compresslevel=1"
   106  			}
   107  			testTable.ColumnDefs = []backup.ColumnDefinition{rowOne, rowTwo}
   108  
   109  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
   110  
   111  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   112  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   113  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   114  			if true {
   115  				// For GPDB 7+, the storage options no longer store the appendonly and orientation field
   116  				testTable.StorageOpts = "compresstype=zlib, blocksize=32768, compresslevel=1"
   117  				testTable.TableDefinition.AccessMethodName = "ao_column"
   118  			}
   119  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
   120  		})
   121  		It("creates a basic GPDB 7+ append-optimized table", func() {
   122  			testutils.SkipIfBefore7(connectionPool)
   123  			testTable.TableDefinition.AccessMethodName = "ao_column"
   124  
   125  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
   126  
   127  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   128  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   129  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   130  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
   131  		})
   132  		It("creates a one-level partition table", func() {
   133  			rowOne := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "region", NotNull: false, HasDefault: false, Type: "text", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   134  			rowTwo := backup.ColumnDefinition{Oid: 0, Num: 2, Name: "gender", NotNull: false, HasDefault: false, Type: "text", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   135  
   136  			if false {
   137  				testTable.PartDef = fmt.Sprintf(`PARTITION BY LIST(gender) `+`
   138            (
   139            PARTITION girls VALUES('F') WITH (tablename='public.rank_1_prt_girls', appendonly=%[1]s ), `+`
   140            PARTITION boys VALUES('M') WITH (tablename='public.rank_1_prt_boys', appendonly=%[1]s ), `+`
   141            DEFAULT PARTITION other  WITH (tablename='public.rank_1_prt_other', appendonly=%[1]s )
   142            )`, partitionPartFalseExpectation)
   143  			} else {
   144  				testTable.PartitionKeyDef = "LIST (gender)"
   145  			}
   146  
   147  			testTable.ColumnDefs = []backup.ColumnDefinition{rowOne, rowTwo}
   148  			testTable.PartitionLevelInfo.Level = "p"
   149  
   150  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
   151  
   152  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   153  			testTable.PartitionLevelInfo.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   154  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   155  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   156  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
   157  		})
   158  		It("creates a two-level partition table", func() {
   159  			/*
   160  			 * The spacing is very specific here and is output from the postgres function
   161  			 * The only difference between the below statements is spacing
   162  			 */
   163  			if false {
   164  				testTable.PartDef = `PARTITION BY LIST(gender)
   165            SUBPARTITION BY LIST(region) ` + `
   166            (
   167            PARTITION girls VALUES('F') WITH (tablename='public.rank_1_prt_girls', appendonly=false ) ` + `
   168                    (
   169                    SUBPARTITION usa VALUES('usa') WITH (tablename='public.rank_1_prt_girls_2_prt_usa', appendonly=false ), ` + `
   170                    SUBPARTITION asia VALUES('asia') WITH (tablename='public.rank_1_prt_girls_2_prt_asia', appendonly=false ), ` + `
   171                    SUBPARTITION europe VALUES('europe') WITH (tablename='public.rank_1_prt_girls_2_prt_europe', appendonly=false ), ` + `
   172                    DEFAULT SUBPARTITION other_regions  WITH (tablename='public.rank_1_prt_girls_2_prt_other_regions', appendonly=false )
   173                    ), ` + `
   174            PARTITION boys VALUES('M') WITH (tablename='rank_1_prt_boys', appendonly=false ) ` + `
   175                    (
   176                    SUBPARTITION usa VALUES('usa') WITH (tablename='public.rank_1_prt_boys_2_prt_usa', appendonly=false ), ` + `
   177                    SUBPARTITION asia VALUES('asia') WITH (tablename='public.rank_1_prt_boys_2_prt_asia', appendonly=false ), ` + `
   178                    SUBPARTITION europe VALUES('europe') WITH (tablename='public.rank_1_prt_boys_2_prt_europe', appendonly=false ), ` + `
   179                    DEFAULT SUBPARTITION other_regions  WITH (tablename='public.rank_1_prt_boys_2_prt_other_regions', appendonly=false )
   180                    ), ` + `
   181            DEFAULT PARTITION other  WITH (tablename='public.rank_1_prt_other', appendonly=false ) ` + `
   182                    (
   183                    SUBPARTITION usa VALUES('usa') WITH (tablename='public.rank_1_prt_other_2_prt_usa', appendonly=false ), ` + `
   184                    SUBPARTITION asia VALUES('asia') WITH (tablename='public.rank_1_prt_other_2_prt_asia', appendonly=false ), ` + `
   185                    SUBPARTITION europe VALUES('europe') WITH (tablename='public.rank_1_prt_other_2_prt_europe', appendonly=false ), ` + `
   186                    DEFAULT SUBPARTITION other_regions  WITH (tablename='public.rank_1_prt_other_2_prt_other_regions', appendonly=false )
   187                    )
   188            )`
   189  				testTable.PartTemplateDef = `ALTER TABLE public.testtable ` + `
   190  SET SUBPARTITION TEMPLATE  ` + `
   191            (
   192            SUBPARTITION usa VALUES('usa') WITH (tablename='testtable'), ` + `
   193            SUBPARTITION asia VALUES('asia') WITH (tablename='testtable'), ` + `
   194            SUBPARTITION europe VALUES('europe') WITH (tablename='testtable'), ` + `
   195            DEFAULT SUBPARTITION other_regions  WITH (tablename='testtable')
   196            )
   197  `
   198  			} else if false {
   199  				testTable.PartDef = fmt.Sprintf(`PARTITION BY LIST(gender)
   200            SUBPARTITION BY LIST(region) `+`
   201            (
   202            PARTITION girls VALUES('F') WITH (tablename='public.rank_1_prt_girls', appendonly=%[1]s )`+`
   203                    (
   204                    SUBPARTITION usa VALUES('usa') WITH (tablename='public.rank_1_prt_girls_2_prt_usa', appendonly=%[1]s ), `+`
   205                    SUBPARTITION asia VALUES('asia') WITH (tablename='public.rank_1_prt_girls_2_prt_asia', appendonly=%[1]s ), `+`
   206                    SUBPARTITION europe VALUES('europe') WITH (tablename='public.rank_1_prt_girls_2_prt_europe', appendonly=%[1]s ), `+`
   207                    DEFAULT SUBPARTITION other_regions  WITH (tablename='public.rank_1_prt_girls_2_prt_other_regions', appendonly=%[1]s )
   208                    ), `+`
   209            PARTITION boys VALUES('M') WITH (tablename='rank_1_prt_boys', appendonly=%[1]s )`+`
   210                    (
   211                    SUBPARTITION usa VALUES('usa') WITH (tablename='public.rank_1_prt_boys_2_prt_usa', appendonly=%[1]s ), `+`
   212                    SUBPARTITION asia VALUES('asia') WITH (tablename='public.rank_1_prt_boys_2_prt_asia', appendonly=%[1]s ), `+`
   213                    SUBPARTITION europe VALUES('europe') WITH (tablename='public.rank_1_prt_boys_2_prt_europe', appendonly=%[1]s ), `+`
   214                    DEFAULT SUBPARTITION other_regions  WITH (tablename='public.rank_1_prt_boys_2_prt_other_regions', appendonly=%[1]s )
   215                    ), `+`
   216            DEFAULT PARTITION other  WITH (tablename='public.rank_1_prt_other', appendonly=%[1]s )`+`
   217                    (
   218                    SUBPARTITION usa VALUES('usa') WITH (tablename='public.rank_1_prt_other_2_prt_usa', appendonly=%[1]s ), `+`
   219                    SUBPARTITION asia VALUES('asia') WITH (tablename='public.rank_1_prt_other_2_prt_asia', appendonly=%[1]s ), `+`
   220                    SUBPARTITION europe VALUES('europe') WITH (tablename='public.rank_1_prt_other_2_prt_europe', appendonly=%[1]s ), `+`
   221                    DEFAULT SUBPARTITION other_regions  WITH (tablename='public.rank_1_prt_other_2_prt_other_regions', appendonly=%[1]s )
   222                    )
   223            )`, partitionPartFalseExpectation)
   224  				testTable.PartTemplateDef = `ALTER TABLE public.testtable ` + `
   225  SET SUBPARTITION TEMPLATE ` + `
   226            (
   227            SUBPARTITION usa VALUES('usa') WITH (tablename='testtable'), ` + `
   228            SUBPARTITION asia VALUES('asia') WITH (tablename='testtable'), ` + `
   229            SUBPARTITION europe VALUES('europe') WITH (tablename='testtable'), ` + `
   230            DEFAULT SUBPARTITION other_regions  WITH (tablename='testtable')
   231            )
   232  `
   233  			} else {
   234  				testTable.PartitionKeyDef = "LIST (gender)"
   235  			}
   236  
   237  			rowOne := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "region", NotNull: false, HasDefault: false, Type: "text", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   238  			rowTwo := backup.ColumnDefinition{Oid: 0, Num: 2, Name: "gender", NotNull: false, HasDefault: false, Type: "text", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   239  			testTable.ColumnDefs = []backup.ColumnDefinition{rowOne, rowTwo}
   240  			testTable.PartitionLevelInfo.Level = "p"
   241  
   242  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
   243  
   244  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   245  			testTable.PartitionLevelInfo.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   246  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   247  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   248  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
   249  
   250  		})
   251  		It("creates a GPDB 7+ root table", func() {
   252  			testutils.SkipIfBefore7(connectionPool)
   253  
   254  			testTable.PartitionKeyDef = "RANGE (b)"
   255  			rowOne := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "a", NotNull: false, HasDefault: false, Type: "integer", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   256  			rowTwo := backup.ColumnDefinition{Oid: 0, Num: 2, Name: "b", NotNull: false, HasDefault: false, Type: "integer", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   257  			testTable.ColumnDefs = []backup.ColumnDefinition{rowOne, rowTwo}
   258  			testTable.PartitionLevelInfo.Level = "p"
   259  
   260  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
   261  
   262  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   263  
   264  			testTable.PartitionLevelInfo.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   265  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   266  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   267  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
   268  		})
   269  		It("creates a table with a non-default tablespace", func() {
   270  			if false {
   271  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLESPACE test_tablespace FILESPACE test_dir")
   272  			} else {
   273  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLESPACE test_tablespace LOCATION '/tmp/test_dir'")
   274  			}
   275  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLESPACE test_tablespace")
   276  			testTable.TablespaceName = "test_tablespace"
   277  
   278  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
   279  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.testtable")
   280  
   281  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   282  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   283  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   284  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
   285  
   286  		})
   287  		It("creates a table that inherits from one table", func() {
   288  			testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.parent (i int)")
   289  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.parent")
   290  			testTable.ColumnDefs = []backup.ColumnDefinition{}
   291  			testTable.Inherits = []string{"public.parent"}
   292  
   293  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
   294  
   295  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   296  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.testtable")
   297  
   298  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   299  			backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})
   300  
   301  			Expect(testTable.Inherits).To(ConsistOf("public.parent"))
   302  		})
   303  		It("creates a table that inherits from two tables", func() {
   304  			testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.parent_one (i int)")
   305  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.parent_one")
   306  			testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.parent_two (j character varying(20))")
   307  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.parent_two")
   308  			testTable.ColumnDefs = []backup.ColumnDefinition{}
   309  			testTable.Inherits = []string{"public.parent_one", "public.parent_two"}
   310  
   311  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
   312  
   313  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   314  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.testtable")
   315  
   316  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   317  			backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})
   318  
   319  			Expect(testTable.Inherits).To(Equal([]string{"public.parent_one", "public.parent_two"}))
   320  		})
   321  		It("creates an unlogged table", func() {
   322  			testutils.SkipIfBefore6(connectionPool)
   323  			rowOne := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "i", NotNull: false, HasDefault: false, Type: "integer", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   324  			rowTwo := backup.ColumnDefinition{Oid: 0, Num: 2, Name: "j", NotNull: false, HasDefault: false, Type: "character varying(20)", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   325  			testTable.ColumnDefs = []backup.ColumnDefinition{rowOne, rowTwo}
   326  			testTable.IsUnlogged = true
   327  
   328  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
   329  
   330  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   331  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   332  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   333  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
   334  
   335  		})
   336  		It("creates a foreign table", func() {
   337  			testutils.SkipIfBefore6(connectionPool)
   338  			testhelper.AssertQueryRuns(connectionPool, "CREATE FOREIGN DATA WRAPPER dummy;")
   339  			defer testhelper.AssertQueryRuns(connectionPool, "DROP FOREIGN DATA WRAPPER dummy")
   340  			testhelper.AssertQueryRuns(connectionPool, "CREATE SERVER sc FOREIGN DATA WRAPPER dummy;")
   341  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SERVER sc")
   342  
   343  			testTable.TableDefinition = backup.TableDefinition{DistPolicy: "", ExtTableDef: extTableEmpty, Inherits: []string{}}
   344  			rowOne := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "i", NotNull: false, HasDefault: false, Type: "integer", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: "", FdwOptions: "option1 'value1', option2 'value2'"}
   345  			testTable.ColumnDefs = []backup.ColumnDefinition{rowOne}
   346  			testTable.ForeignDef = backup.ForeignTableDefinition{Oid: 0, Options: "", Server: "sc"}
   347  			backup.PrintRegularTableCreateStatement(backupfile, tocfile, testTable)
   348  
   349  			metadata := testutils.DefaultMetadata("TABLE", true, true, true, true)
   350  			backup.PrintPostCreateTableStatements(backupfile, tocfile, testTable, metadata)
   351  
   352  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   353  			defer testhelper.AssertQueryRuns(connectionPool, "DROP FOREIGN TABLE public.testtable")
   354  
   355  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   356  			testTable.ForeignDef.Oid = testTable.Oid
   357  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   358  			structmatcher.ExpectStructsToMatchExcluding(testTable.TableDefinition, resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
   359  		})
   360  	})
   361  	Describe("PrintPostCreateTableStatements", func() {
   362  		var (
   363  			extTableEmpty = backup.ExternalTableDefinition{Oid: 0, Type: -2, Protocol: -2, Location: sql.NullString{String: "", Valid: true}, ExecLocation: "ALL_SEGMENTS", FormatType: "t", FormatOpts: "", Command: "", RejectLimit: 0, RejectLimitType: "", ErrTableName: "", ErrTableSchema: "", Encoding: "UTF-8", Writable: false, URIs: nil}
   364  			tableRow      = backup.ColumnDefinition{Oid: 0, Num: 1, Name: "i", NotNull: false, HasDefault: false, Type: "integer", Encoding: "", StatTarget: -1, StorageType: "", DefaultVal: "", Comment: ""}
   365  			testTable     backup.Table
   366  			tableMetadata backup.ObjectMetadata
   367  		)
   368  		BeforeEach(func() {
   369  			testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.testtable(i int)")
   370  			tableMetadata = backup.ObjectMetadata{Privileges: []backup.ACL{}, ObjectType: "RELATION"}
   371  			testTable = backup.Table{
   372  				Relation:        backup.Relation{Schema: "public", Name: "testtable"},
   373  				TableDefinition: backup.TableDefinition{DistPolicy: "DISTRIBUTED BY (i)", ColumnDefs: []backup.ColumnDefinition{tableRow}, ExtTableDef: extTableEmpty, Inherits: []string{}},
   374  			}
   375  			if true {
   376  				testTable.ReplicaIdentity = "d"
   377  			}
   378  		})
   379  		AfterEach(func() {
   380  			testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.testtable")
   381  		})
   382  		It("prints only owner for a table with no comment or column comments", func() {
   383  			tableMetadata.Owner = "testrole"
   384  			backup.PrintPostCreateTableStatements(backupfile, tocfile, testTable, tableMetadata)
   385  
   386  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   387  			testTableUniqueID := testutils.UniqueIDFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   388  			testTable.Oid = testTableUniqueID.Oid
   389  
   390  			resultMetadata := backup.GetMetadataForObjectType(connectionPool, backup.TYPE_RELATION)
   391  			resultTableMetadata := resultMetadata[testTableUniqueID]
   392  
   393  			structmatcher.ExpectStructsToMatch(&tableMetadata, &resultTableMetadata)
   394  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   395  			structmatcher.ExpectStructsToMatchExcluding(&testTable.TableDefinition, &resultTable.TableDefinition, "ColumnDefs.Oid", "ColumnDefs.ACL", "ExtTableDef")
   396  		})
   397  		It("prints table comment, table privileges, table owner, table security label, and column comments for a table", func() {
   398  			tableMetadata = testutils.DefaultMetadata("TABLE", true, true, true, includeSecurityLabels)
   399  			testTable.ColumnDefs[0].Comment = "This is a column comment."
   400  			backup.PrintPostCreateTableStatements(backupfile, tocfile, testTable, tableMetadata)
   401  
   402  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   403  
   404  			testTableUniqueID := testutils.UniqueIDFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   405  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   406  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   407  			structmatcher.ExpectStructsToMatchExcluding(&testTable.TableDefinition, &resultTable.TableDefinition, "ColumnDefs.Oid", "ExtTableDef")
   408  
   409  			resultMetadata := backup.GetMetadataForObjectType(connectionPool, backup.TYPE_RELATION)
   410  			resultTableMetadata := resultMetadata[testTableUniqueID]
   411  			structmatcher.ExpectStructsToMatch(&tableMetadata, &resultTableMetadata)
   412  		})
   413  		It("prints column level privileges", func() {
   414  			testutils.SkipIfBefore6(connectionPool)
   415  			privilegesColumnOne := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "i", Type: "integer", StatTarget: -1, Privileges: sql.NullString{String: "testrole=r/testrole", Valid: true}}
   416  			tableMetadata.Owner = "testrole"
   417  			testTable.ColumnDefs = []backup.ColumnDefinition{privilegesColumnOne}
   418  			backup.PrintPostCreateTableStatements(backupfile, tocfile, testTable, tableMetadata)
   419  
   420  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   421  
   422  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   423  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   424  			resultColumnOne := resultTable.ColumnDefs[0]
   425  			structmatcher.ExpectStructsToMatchExcluding(privilegesColumnOne, resultColumnOne, "Oid")
   426  		})
   427  		It("prints column level security label", func() {
   428  			testutils.SkipIfBefore6(connectionPool)
   429  			securityLabelColumnOne := backup.ColumnDefinition{Oid: 0, Num: 1, Name: "i", Type: "integer", StatTarget: -1, SecurityLabelProvider: "dummy", SecurityLabel: "unclassified"}
   430  			testTable.ColumnDefs = []backup.ColumnDefinition{securityLabelColumnOne}
   431  			backup.PrintPostCreateTableStatements(backupfile, tocfile, testTable, tableMetadata)
   432  
   433  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   434  
   435  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   436  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   437  			resultColumnOne := resultTable.ColumnDefs[0]
   438  			structmatcher.ExpectStructsToMatchExcluding(securityLabelColumnOne, resultColumnOne, "Oid")
   439  		})
   440  		It("prints table replica identity value", func() {
   441  			testutils.SkipIfBefore6(connectionPool)
   442  
   443  			testTable.ReplicaIdentity = "f"
   444  			backup.PrintPostCreateTableStatements(backupfile, tocfile, testTable, tableMetadata)
   445  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   446  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   447  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   448  			Expect(resultTable.ReplicaIdentity).To(Equal("f"))
   449  		})
   450  		It("prints a GPDB 7+ ALTER statement to ATTACH a child table to it's root", func() {
   451  			testutils.SkipIfBefore7(connectionPool)
   452  			testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.testroottable(i int) PARTITION BY RANGE (i) DISTRIBUTED BY (i); ")
   453  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.testroottable;")
   454  			testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.testchildtable(i int) DISTRIBUTED BY (i);")
   455  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.testchildtable;")
   456  			tableMetadata = backup.ObjectMetadata{Privileges: []backup.ACL{}, ObjectType: "RELATION"}
   457  			testChildTable := backup.Table{
   458  				Relation: backup.Relation{Schema: "public", Name: "testChildTable"},
   459  				TableDefinition: backup.TableDefinition{
   460  					DistPolicy:  "DISTRIBUTED BY (i)",
   461  					ColumnDefs:  []backup.ColumnDefinition{tableRow},
   462  					ExtTableDef: extTableEmpty,
   463  					Inherits:    []string{"public.testroottable"},
   464  					AttachPartitionInfo: backup.AttachPartitionInfo{
   465  						Relname: "public.testchildtable",
   466  						Parent:  "public.testroottable",
   467  						Expr:    "FOR VALUES FROM (1) TO (2)",
   468  					},
   469  				},
   470  			}
   471  
   472  			backup.PrintPostCreateTableStatements(backupfile, tocfile, testChildTable, tableMetadata)
   473  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   474  
   475  			attachPartitionInfoMap := backup.GetAttachPartitionInfo(connectionPool)
   476  			childTableOid := testutils.OidFromObjectName(connectionPool, "public", "testchildtable", backup.TYPE_RELATION)
   477  			testChildTable.AttachPartitionInfo.Oid = childTableOid
   478  			structmatcher.ExpectStructsToMatch(&testChildTable.AttachPartitionInfo, attachPartitionInfoMap[childTableOid])
   479  		})
   480  		It("prints an ALTER statement to force row level security on the table owner", func() {
   481  			testutils.SkipIfBefore7(connectionPool)
   482  
   483  			testTable.ForceRowSecurity = true
   484  			backup.PrintPostCreateTableStatements(backupfile, tocfile, testTable, tableMetadata)
   485  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   486  			testTable.Oid = testutils.OidFromObjectName(connectionPool, "public", "testtable", backup.TYPE_RELATION)
   487  			resultTable := backup.ConstructDefinitionsForTables(connectionPool, []backup.Relation{testTable.Relation})[0]
   488  			Expect(resultTable.ForceRowSecurity).To(Equal(true))
   489  		})
   490  	})
   491  	Describe("PrintCreateViewStatements", func() {
   492  		var viewDef sql.NullString
   493  		BeforeEach(func() {
   494  			if false {
   495  				viewDef = sql.NullString{String: "SELECT 1;", Valid: true}
   496  			} else {
   497  				viewDef = sql.NullString{String: " SELECT 1;", Valid: true}
   498  			}
   499  		})
   500  		It("creates a view with privileges, owner, security label, and comment", func() {
   501  			view := backup.View{Oid: 1, Schema: "public", Name: "simpleview", Definition: viewDef}
   502  			viewMetadata := testutils.DefaultMetadata("VIEW", true, true, true, includeSecurityLabels)
   503  
   504  			backup.PrintCreateViewStatement(backupfile, tocfile, view, viewMetadata)
   505  
   506  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   507  			defer testhelper.AssertQueryRuns(connectionPool, "DROP VIEW public.simpleview")
   508  
   509  			resultViews := backup.GetAllViews(connectionPool)
   510  			resultMetadataMap := backup.GetMetadataForObjectType(connectionPool, backup.TYPE_RELATION)
   511  
   512  			view.Oid = testutils.OidFromObjectName(connectionPool, "public", "simpleview", backup.TYPE_RELATION)
   513  			Expect(resultViews).To(HaveLen(1))
   514  			resultMetadata := resultMetadataMap[view.GetUniqueID()]
   515  			structmatcher.ExpectStructsToMatch(&view, &resultViews[0])
   516  			structmatcher.ExpectStructsToMatch(&viewMetadata, &resultMetadata)
   517  		})
   518  		It("creates a view with options", func() {
   519  			testutils.SkipIfBefore6(connectionPool)
   520  			view := backup.View{Oid: 1, Schema: "public", Name: "simpleview", Options: " WITH (security_barrier=true)", Definition: viewDef}
   521  
   522  			backup.PrintCreateViewStatement(backupfile, tocfile, view, backup.ObjectMetadata{})
   523  
   524  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   525  			defer testhelper.AssertQueryRuns(connectionPool, "DROP VIEW public.simpleview")
   526  
   527  			resultViews := backup.GetAllViews(connectionPool)
   528  
   529  			view.Oid = testutils.OidFromObjectName(connectionPool, "public", "simpleview", backup.TYPE_RELATION)
   530  			Expect(resultViews).To(HaveLen(1))
   531  			structmatcher.ExpectStructsToMatch(&view, &resultViews[0])
   532  		})
   533  	})
   534  	Describe("PrintMaterializedCreateViewStatements", func() {
   535  		BeforeEach(func() {
   536  			if false {
   537  				Skip("test only applicable to GPDB 6.2 and above")
   538  			}
   539  		})
   540  		It("creates a view with privileges, owner, security label, and comment", func() {
   541  			view := backup.View{Oid: 1, Schema: "public", Name: "simplemview", Definition: sql.NullString{String: " SELECT 1 AS a;", Valid: true}, IsMaterialized: true, DistPolicy: "DISTRIBUTED BY (a)"}
   542  			viewMetadata := testutils.DefaultMetadata("MATERIALIZED VIEW", true, true, true, includeSecurityLabels)
   543  
   544  			backup.PrintCreateViewStatement(backupfile, tocfile, view, viewMetadata)
   545  
   546  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   547  			defer testhelper.AssertQueryRuns(connectionPool, "DROP MATERIALIZED VIEW public.simplemview")
   548  
   549  			resultViews := backup.GetAllViews(connectionPool)
   550  			resultMetadataMap := backup.GetMetadataForObjectType(connectionPool, backup.TYPE_RELATION)
   551  
   552  			view.Oid = testutils.OidFromObjectName(connectionPool, "public", "simplemview", backup.TYPE_RELATION)
   553  			Expect(resultViews).To(HaveLen(1))
   554  			resultMetadata := resultMetadataMap[view.GetUniqueID()]
   555  			structmatcher.ExpectStructsToMatch(&view, &resultViews[0])
   556  			structmatcher.ExpectStructsToMatch(&viewMetadata, &resultMetadata)
   557  		})
   558  		It("creates a materialized view with options", func() {
   559  			view := backup.View{Oid: 1, Schema: "public", Name: "simplemview", Options: " WITH (fillfactor=10)", Definition: sql.NullString{String: " SELECT 1 AS a;", Valid: true}, IsMaterialized: true, DistPolicy: "DISTRIBUTED BY (a)"}
   560  
   561  			backup.PrintCreateViewStatement(backupfile, tocfile, view, backup.ObjectMetadata{})
   562  
   563  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   564  			defer testhelper.AssertQueryRuns(connectionPool, "DROP MATERIALIZED VIEW public.simplemview")
   565  
   566  			resultViews := backup.GetAllViews(connectionPool)
   567  
   568  			view.Oid = testutils.OidFromObjectName(connectionPool, "public", "simplemview", backup.TYPE_RELATION)
   569  			Expect(resultViews).To(HaveLen(1))
   570  			structmatcher.ExpectStructsToMatch(&view, &resultViews[0])
   571  		})
   572  	})
   573  	Describe("PrintCreateSequenceStatements", func() {
   574  		var (
   575  			sequenceRel         backup.Relation
   576  			sequence            backup.Sequence
   577  			sequenceMetadataMap backup.MetadataMap
   578  			dataType            string
   579  		)
   580  		BeforeEach(func() {
   581  			sequenceRel = backup.Relation{SchemaOid: 0, Oid: 1, Schema: "public", Name: "my_sequence"}
   582  			sequence = backup.Sequence{Relation: sequenceRel}
   583  			sequenceMetadataMap = backup.MetadataMap{}
   584  
   585  			dataType = ""
   586  			if true {
   587  				dataType = "bigint"
   588  			}
   589  		})
   590  		It("creates a basic sequence", func() {
   591  			startValue := int64(0)
   592  			if true {
   593  				startValue = 1
   594  			}
   595  			sequence.Definition = backup.SequenceDefinition{LastVal: 1, Type: dataType, Increment: 1, MaxVal: math.MaxInt64, MinVal: 1, CacheVal: 1, StartVal: startValue}
   596  			backup.PrintCreateSequenceStatements(backupfile, tocfile, []backup.Sequence{sequence}, sequenceMetadataMap)
   597  
   598  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   599  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SEQUENCE public.my_sequence")
   600  
   601  			resultSequences := backup.GetAllSequences(connectionPool)
   602  
   603  			Expect(resultSequences).To(HaveLen(1))
   604  			structmatcher.ExpectStructsToMatchExcluding(&sequenceRel, &resultSequences[0].Relation, "SchemaOid", "Oid")
   605  			structmatcher.ExpectStructsToMatch(&sequence.Definition, &resultSequences[0].Definition)
   606  		})
   607  		It("creates a complex sequence", func() {
   608  			startValue := int64(0)
   609  			if true {
   610  				startValue = 105
   611  			}
   612  			sequence.Definition = backup.SequenceDefinition{LastVal: 105, Type: dataType, Increment: 5, MaxVal: 1000, MinVal: 20, CacheVal: 1, IsCycled: false, IsCalled: true, StartVal: startValue}
   613  			backup.PrintCreateSequenceStatements(backupfile, tocfile, []backup.Sequence{sequence}, sequenceMetadataMap)
   614  
   615  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   616  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SEQUENCE public.my_sequence")
   617  
   618  			resultSequences := backup.GetAllSequences(connectionPool)
   619  
   620  			Expect(resultSequences).To(HaveLen(1))
   621  			structmatcher.ExpectStructsToMatchExcluding(&sequenceRel, &resultSequences[0].Relation, "SchemaOid", "Oid")
   622  			structmatcher.ExpectStructsToMatch(&sequence.Definition, &resultSequences[0].Definition)
   623  		})
   624  		It("creates a sequence with privileges, owner, and comment", func() {
   625  			startValue := int64(0)
   626  			if true {
   627  				startValue = 1
   628  			}
   629  			sequence.Definition = backup.SequenceDefinition{LastVal: 1, Type: dataType, Increment: 1, MaxVal: math.MaxInt64, MinVal: 1, CacheVal: 1, StartVal: startValue}
   630  			sequenceMetadata := testutils.DefaultMetadata("SEQUENCE", true, true, true, includeSecurityLabels)
   631  			sequenceMetadataMap[backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: 1}] = sequenceMetadata
   632  			backup.PrintCreateSequenceStatements(backupfile, tocfile, []backup.Sequence{sequence}, sequenceMetadataMap)
   633  
   634  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   635  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SEQUENCE public.my_sequence")
   636  
   637  			resultSequences := backup.GetAllSequences(connectionPool)
   638  
   639  			Expect(resultSequences).To(HaveLen(1))
   640  			resultMetadataMap := backup.GetMetadataForObjectType(connectionPool, backup.TYPE_RELATION)
   641  			uniqueID := testutils.UniqueIDFromObjectName(connectionPool, "public", "my_sequence", backup.TYPE_RELATION)
   642  			resultMetadata := resultMetadataMap[uniqueID]
   643  			structmatcher.ExpectStructsToMatchExcluding(&sequenceRel, &resultSequences[0].Relation, "SchemaOid", "Oid")
   644  			structmatcher.ExpectStructsToMatch(&sequence.Definition, &resultSequences[0].Definition)
   645  			structmatcher.ExpectStructsToMatch(&sequenceMetadata, &resultMetadata)
   646  		})
   647  		It("doesn't create identity sequences", func() {
   648  			testutils.SkipIfBefore7(connectionPool)
   649  			startValue := int64(0)
   650  			sequence.Definition = backup.SequenceDefinition{LastVal: 1, Type: dataType, MinVal: math.MinInt64, MaxVal: math.MaxInt64, Increment: 1, CacheVal: 1, StartVal: startValue}
   651  
   652  			identitySequenceRel := backup.Relation{SchemaOid: 0, Oid: 1, Schema: "public", Name: "my_identity_sequence"}
   653  			identitySequence := backup.Sequence{Relation: identitySequenceRel, IsIdentity: true}
   654  			identitySequence.Definition = backup.SequenceDefinition{LastVal: 1, Type: dataType, MinVal: math.MinInt64, MaxVal: math.MaxInt64, Increment: 1, CacheVal: 20, StartVal: startValue}
   655  
   656  			backup.PrintCreateSequenceStatements(backupfile, tocfile, []backup.Sequence{sequence, identitySequence}, sequenceMetadataMap)
   657  
   658  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   659  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SEQUENCE public.my_sequence")
   660  
   661  			resultSequences := backup.GetAllSequences(connectionPool)
   662  
   663  			Expect(resultSequences).To(HaveLen(1))
   664  			structmatcher.ExpectStructsToMatchExcluding(&sequenceRel, &resultSequences[0].Relation, "SchemaOid", "Oid")
   665  			structmatcher.ExpectStructsToMatch(&sequence.Definition, &resultSequences[0].Definition)
   666  		})
   667  	})
   668  	Describe("PrintAlterSequenceStatements", func() {
   669  		It("creates a sequence owned by a table column", func() {
   670  			startValue := int64(0)
   671  			if true {
   672  				startValue = 1
   673  			}
   674  			sequence := backup.Sequence{Relation: backup.Relation{SchemaOid: 0, Oid: 1, Schema: "public", Name: "my_sequence"}}
   675  			sequence.OwningColumn = "public.sequence_table.a"
   676  
   677  			sequence.Definition = backup.SequenceDefinition{LastVal: 1, Increment: 1, MaxVal: math.MaxInt64, MinVal: 1, CacheVal: 1, StartVal: startValue}
   678  			if true {
   679  				sequence.Definition.Type = "bigint"
   680  			}
   681  
   682  			backup.PrintCreateSequenceStatements(backupfile, tocfile, []backup.Sequence{sequence}, backup.MetadataMap{})
   683  			backup.PrintAlterSequenceStatements(backupfile, tocfile, []backup.Sequence{sequence})
   684  
   685  			//Create table that sequence can be owned by
   686  			testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.sequence_table(a int)")
   687  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.sequence_table")
   688  
   689  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   690  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SEQUENCE public.my_sequence")
   691  
   692  			sequences := backup.GetAllSequences(connectionPool)
   693  			Expect(sequences).To(HaveLen(1))
   694  			Expect(sequences[0].OwningTable).To(Equal("public.sequence_table"))
   695  			Expect(sequences[0].OwningColumn).To(Equal("public.sequence_table.a"))
   696  		})
   697  		It("skips identity sequences", func() {
   698  			testutils.SkipIfBefore7(connectionPool)
   699  			sequenceRel := backup.Relation{SchemaOid: 0, Oid: 1, Schema: "public", Name: "my_sequence"}
   700  			sequence := backup.Sequence{Relation: sequenceRel}
   701  			sequence.Definition = backup.SequenceDefinition{LastVal: 1, Increment: 1, MaxVal: math.MaxInt64, MinVal: 1, CacheVal: 1, StartVal: 1, Type: "bigint"}
   702  
   703  			identitySequenceRel := backup.Relation{SchemaOid: 0, Oid: 1, Schema: "public", Name: "my_identity_sequence"}
   704  			identitySequence := backup.Sequence{Relation: identitySequenceRel, IsIdentity: true}
   705  			identitySequence.Definition = backup.SequenceDefinition{LastVal: 1, Increment: 1, MaxVal: math.MaxInt64, MinVal: 1, CacheVal: 20, StartVal: 1, Type: "bigint"}
   706  
   707  			backup.PrintCreateSequenceStatements(backupfile, tocfile, []backup.Sequence{sequence, identitySequence}, backup.MetadataMap{})
   708  			backup.PrintAlterSequenceStatements(backupfile, tocfile, []backup.Sequence{sequence, identitySequence})
   709  
   710  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   711  			defer testhelper.AssertQueryRuns(connectionPool, "DROP SEQUENCE public.my_sequence")
   712  
   713  			sequences := backup.GetAllSequences(connectionPool)
   714  			Expect(sequences).To(HaveLen(1))
   715  			structmatcher.ExpectStructsToMatchExcluding(&sequenceRel, &sequences[0].Relation, "SchemaOid", "Oid")
   716  			structmatcher.ExpectStructsToMatch(&sequence.Definition, &sequences[0].Definition)
   717  		})
   718  	})
   719  })