github.com/cloudberrydb/gpbackup@v1.0.3-0.20240118031043-5410fd45eed6/integration/predata_types_create_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"github.com/cloudberrydb/gp-common-go-libs/structmatcher"
     5  	"github.com/cloudberrydb/gp-common-go-libs/testhelper"
     6  	"github.com/cloudberrydb/gpbackup/backup"
     7  	"github.com/cloudberrydb/gpbackup/testutils"
     8  
     9  	. "github.com/onsi/ginkgo/v2"
    10  	. "github.com/onsi/gomega"
    11  )
    12  
    13  var _ = Describe("backup integration create statement tests", func() {
    14  	var (
    15  		emptyMetadata    backup.ObjectMetadata
    16  		emptyMetadataMap backup.MetadataMap
    17  	)
    18  	BeforeEach(func() {
    19  		tocfile, backupfile = testutils.InitializeTestTOC(buffer, "predata")
    20  		emptyMetadata = backup.ObjectMetadata{}
    21  		emptyMetadataMap = backup.MetadataMap{}
    22  	})
    23  	Describe("PrintTypeStatements", func() {
    24  		var (
    25  			shellType backup.ShellType
    26  			baseType  backup.BaseType
    27  			rangeType backup.RangeType
    28  		)
    29  		BeforeEach(func() {
    30  			shellType = backup.ShellType{Schema: "public", Name: "shell_type"}
    31  			baseType = backup.BaseType{
    32  				Schema: "public", Name: "base_type", Input: "public.base_fn_in", Output: "public.base_fn_out", Receive: "",
    33  				Send: "", ModIn: "", ModOut: "", InternalLength: 4, IsPassedByValue: true, Alignment: "i", Storage: "p",
    34  				DefaultVal: "default", Element: "text", Category: "U", Preferred: false, Delimiter: ";", StorageOptions: "compresstype=zlib, compresslevel=1, blocksize=32768",
    35  			}
    36  			rangeType = backup.RangeType{
    37  				Oid:            0,
    38  				Schema:         "public",
    39  				Name:           "textrange",
    40  				SubType:        "text",
    41  				Collation:      "public.some_coll",
    42  				SubTypeOpClass: "pg_catalog.text_ops",
    43  			}
    44  		})
    45  		Describe("PrintCreateShellTypeStatements", func() {
    46  			It("creates shell types for base, shell and range types", func() {
    47  				backup.PrintCreateShellTypeStatements(backupfile, tocfile, []backup.ShellType{shellType}, []backup.BaseType{baseType}, []backup.RangeType{rangeType})
    48  
    49  				testhelper.AssertQueryRuns(connectionPool, buffer.String())
    50  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.shell_type")
    51  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.base_type")
    52  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.textrange")
    53  
    54  				shells := backup.GetShellTypes(connectionPool)
    55  				Expect(shells).To(HaveLen(3))
    56  				Expect(shells[0].Name).To(Equal("base_type"))
    57  				Expect(shells[1].Name).To(Equal("shell_type"))
    58  				Expect(shells[2].Name).To(Equal("textrange"))
    59  			})
    60  		})
    61  
    62  		Describe("PrintCreateCompositeTypeStatement", func() {
    63  			var compositeType backup.CompositeType
    64  			BeforeEach(func() {
    65  				atts := []backup.Attribute{{Name: "att1", Type: "text"}, {Name: "att2", Type: "integer"}}
    66  				compositeType = backup.CompositeType{
    67  					Schema: "public", Name: "composite_type", Attributes: atts,
    68  				}
    69  			})
    70  			It("creates composite types", func() {
    71  				backup.PrintCreateCompositeTypeStatement(backupfile, tocfile, compositeType, emptyMetadata)
    72  
    73  				testhelper.AssertQueryRuns(connectionPool, buffer.String())
    74  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.composite_type")
    75  
    76  				resultTypes := backup.GetCompositeTypes(connectionPool)
    77  
    78  				Expect(resultTypes).To(HaveLen(1))
    79  				structmatcher.ExpectStructsToMatchExcluding(&compositeType, &resultTypes[0], "Oid", "Attributes.CompositeTypeOid")
    80  			})
    81  			It("creates composite types with a collation", func() {
    82  				testutils.SkipIfBefore6(connectionPool)
    83  				testhelper.AssertQueryRuns(connectionPool, `CREATE COLLATION public.some_coll (lc_collate = 'POSIX', lc_ctype = 'POSIX');`)
    84  				defer testhelper.AssertQueryRuns(connectionPool, "DROP COLLATION public.some_coll")
    85  				compositeType.Attributes[0].Collation = "public.some_coll"
    86  				backup.PrintCreateCompositeTypeStatement(backupfile, tocfile, compositeType, emptyMetadata)
    87  
    88  				testhelper.AssertQueryRuns(connectionPool, buffer.String())
    89  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.composite_type")
    90  
    91  				resultTypes := backup.GetCompositeTypes(connectionPool)
    92  
    93  				Expect(resultTypes).To(HaveLen(1))
    94  				structmatcher.ExpectStructsToMatchExcluding(&compositeType, &resultTypes[0], "Oid", "Attributes.CompositeTypeOid")
    95  			})
    96  			It("creates composite types with attribute comments", func() {
    97  				compositeType.Attributes[0].Comment = "'comment for att1'"
    98  				backup.PrintCreateCompositeTypeStatement(backupfile, tocfile, compositeType, emptyMetadata)
    99  
   100  				testhelper.AssertQueryRuns(connectionPool, buffer.String())
   101  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.composite_type")
   102  
   103  				resultTypes := backup.GetCompositeTypes(connectionPool)
   104  
   105  				Expect(resultTypes).To(HaveLen(1))
   106  				structmatcher.ExpectStructsToMatchExcluding(&compositeType, &resultTypes[0], "Oid", "Attributes.CompositeTypeOid")
   107  			})
   108  		})
   109  		Describe("PrintCreateBaseTypeStatement", func() {
   110  			It("creates base types", func() {
   111  				if true {
   112  					baseType.Category = "N"
   113  					baseType.Preferred = true
   114  					baseType.Collatable = true
   115  				}
   116  				metadata := testutils.DefaultMetadata("TYPE", false, true, true, includeSecurityLabels)
   117  				backup.PrintCreateBaseTypeStatement(backupfile, tocfile, baseType, metadata)
   118  
   119  				//Run queries to set up the database state so we can successfully create base types
   120  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_type")
   121  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.base_type CASCADE")
   122  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_fn_in(cstring) RETURNS public.base_type AS 'boolin' LANGUAGE internal")
   123  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_fn_out(public.base_type) RETURNS cstring AS 'boolout' LANGUAGE internal")
   124  
   125  				testhelper.AssertQueryRuns(connectionPool, buffer.String())
   126  
   127  				resultTypes := backup.GetBaseTypes(connectionPool)
   128  
   129  				Expect(resultTypes).To(HaveLen(1))
   130  				structmatcher.ExpectStructsToMatchExcluding(&baseType, &resultTypes[0], "Oid")
   131  			})
   132  		})
   133  		Describe("PrintCreateEnumTypeStatements", func() {
   134  			It("creates enum types", func() {
   135  				testutils.SkipIfBefore5(connectionPool)
   136  				enumType := backup.EnumType{Schema: "public", Name: "enum_type", EnumLabels: "'enum_labels'"}
   137  				enums := []backup.EnumType{enumType}
   138  				backup.PrintCreateEnumTypeStatements(backupfile, tocfile, enums, emptyMetadataMap)
   139  
   140  				testhelper.AssertQueryRuns(connectionPool, buffer.String())
   141  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.enum_type")
   142  
   143  				resultTypes := backup.GetEnumTypes(connectionPool)
   144  
   145  				Expect(resultTypes).To(HaveLen(1))
   146  				structmatcher.ExpectStructsToMatchExcluding(&resultTypes[0], &enumType, "Oid")
   147  			})
   148  		})
   149  		Describe("PrintCreateDomainStatement", func() {
   150  			domainType := backup.Domain{
   151  				Oid: 1, Schema: "public", Name: "domain_type", BaseType: "character(8)", DefaultVal: "'abc'::bpchar", NotNull: true, Collation: ""}
   152  			It("creates domain types", func() {
   153  				constraints := make([]backup.Constraint, 0)
   154  				if true {
   155  					testhelper.AssertQueryRuns(connectionPool, "CREATE COLLATION public.some_coll (lc_collate = 'POSIX', lc_ctype = 'POSIX')")
   156  					defer testhelper.AssertQueryRuns(connectionPool, "DROP COLLATION public.some_coll")
   157  					domainType.Collation = "public.some_coll"
   158  				}
   159  				metadata := testutils.DefaultMetadata("DOMAIN", false, true, true, includeSecurityLabels)
   160  				backup.PrintCreateDomainStatement(backupfile, tocfile, domainType, metadata, constraints)
   161  
   162  				testhelper.AssertQueryRuns(connectionPool, buffer.String())
   163  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.domain_type")
   164  
   165  				resultTypes := backup.GetDomainTypes(connectionPool)
   166  
   167  				Expect(resultTypes).To(HaveLen(1))
   168  				structmatcher.ExpectStructsToMatchIncluding(&domainType, &resultTypes[0], "Schema", "Name", "Type", "DefaultVal", "BaseType", "NotNull", "Collation")
   169  			})
   170  		})
   171  		Describe("PrintCreateRangeTypeStatement", func() {
   172  			It("creates a range type with a collation and opclass", func() {
   173  				testutils.SkipIfBefore6(connectionPool)
   174  				testhelper.AssertQueryRuns(connectionPool, "CREATE COLLATION public.some_coll (lc_collate = 'POSIX', lc_ctype = 'POSIX');")
   175  				defer testhelper.AssertQueryRuns(connectionPool, "DROP COLLATION public.some_coll")
   176  
   177  				metadata := testutils.DefaultMetadata("TYPE", false, true, true, includeSecurityLabels)
   178  				backup.PrintCreateRangeTypeStatement(backupfile, tocfile, rangeType, metadata)
   179  
   180  				testhelper.AssertQueryRuns(connectionPool, buffer.String())
   181  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.textrange")
   182  
   183  				resultTypes := backup.GetRangeTypes(connectionPool)
   184  
   185  				Expect(len(resultTypes)).To(Equal(1))
   186  				structmatcher.ExpectStructsToMatchExcluding(&rangeType, &resultTypes[0], "Oid")
   187  			})
   188  			It("creates a range type in a specific schema with a subtype diff function", func() {
   189  				testutils.SkipIfBefore6(connectionPool)
   190  				rangeType := backup.RangeType{
   191  					Oid:            0,
   192  					Schema:         "testschema",
   193  					Name:           "timerange",
   194  					SubType:        "time without time zone",
   195  					SubTypeOpClass: "pg_catalog.time_ops",
   196  					SubTypeDiff:    "testschema.time_subtype_diff",
   197  				}
   198  				testhelper.AssertQueryRuns(connectionPool, "CREATE SCHEMA testschema;")
   199  				defer testhelper.AssertQueryRuns(connectionPool, "DROP SCHEMA testschema CASCADE;")
   200  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION testschema.time_subtype_diff(x time, y time) RETURNS float8 AS 'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE;")
   201  
   202  				backup.PrintCreateRangeTypeStatement(backupfile, tocfile, rangeType, emptyMetadata)
   203  
   204  				testhelper.AssertQueryRuns(connectionPool, buffer.String())
   205  
   206  				resultTypes := backup.GetRangeTypes(connectionPool)
   207  
   208  				Expect(len(resultTypes)).To(Equal(1))
   209  				structmatcher.ExpectStructsToMatchExcluding(&rangeType, &resultTypes[0], "Oid")
   210  			})
   211  		})
   212  	})
   213  	Describe("PrintCreateCollationStatement", func() {
   214  		It("creates a basic collation", func() {
   215  			testutils.SkipIfBefore6(connectionPool)
   216  			collation := backup.Collation{Oid: 1, Schema: "public", Name: "testcollation", Collate: "POSIX", Ctype: "POSIX"}
   217  			if true {
   218  				collation.IsDeterministic = "true"
   219  				collation.Provider = "c"
   220  			}
   221  			backup.PrintCreateCollationStatements(backupfile, tocfile, []backup.Collation{collation}, backup.MetadataMap{})
   222  
   223  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   224  			defer testhelper.AssertQueryRuns(connectionPool, "DROP COLLATION public.testcollation")
   225  
   226  			resultCollations := backup.GetCollations(connectionPool)
   227  
   228  			Expect(resultCollations).To(HaveLen(1))
   229  			structmatcher.ExpectStructsToMatchExcluding(&collation, &resultCollations[0], "Oid")
   230  		})
   231  		It("creates a basic collation with comment and owner", func() {
   232  			testutils.SkipIfBefore6(connectionPool)
   233  			collation := backup.Collation{Oid: 1, Schema: "public", Name: "testcollation", Collate: "POSIX", Ctype: "POSIX"}
   234  			if true {
   235  				collation.IsDeterministic = "true"
   236  				collation.Provider = "c"
   237  			}
   238  			collationMetadataMap := testutils.DefaultMetadataMap("COLLATION", false, true, true, false)
   239  			collationMetadata := collationMetadataMap[collation.GetUniqueID()]
   240  
   241  			backup.PrintCreateCollationStatements(backupfile, tocfile, []backup.Collation{collation}, collationMetadataMap)
   242  
   243  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   244  			defer testhelper.AssertQueryRuns(connectionPool, "DROP COLLATION public.testcollation")
   245  
   246  			resultCollations := backup.GetCollations(connectionPool)
   247  			resultMetadataMap := backup.GetMetadataForObjectType(connectionPool, backup.TYPE_COLLATION)
   248  
   249  			Expect(resultCollations).To(HaveLen(1))
   250  			uniqueID := testutils.UniqueIDFromObjectName(connectionPool, "public", "testcollation", backup.TYPE_COLLATION)
   251  			resultMetadata := resultMetadataMap[uniqueID]
   252  			structmatcher.ExpectStructsToMatchExcluding(&collation, &resultCollations[0], "Oid")
   253  			structmatcher.ExpectStructsToMatch(&collationMetadata, &resultMetadata)
   254  
   255  		})
   256  		It("creates a specific collation", func() {
   257  			testutils.SkipIfBefore7(connectionPool)
   258  			collation := backup.Collation{Oid: 1, Schema: "public", Name: "testcollation", Collate: "de_DE", Ctype: "de_DE", Provider: "c", IsDeterministic: "true"}
   259  			backup.PrintCreateCollationStatements(backupfile, tocfile, []backup.Collation{collation}, backup.MetadataMap{})
   260  
   261  			testhelper.AssertQueryRuns(connectionPool, buffer.String())
   262  			defer testhelper.AssertQueryRuns(connectionPool, "DROP COLLATION public.testcollation")
   263  
   264  			resultCollations := backup.GetCollations(connectionPool)
   265  
   266  			Expect(resultCollations).To(HaveLen(1))
   267  			structmatcher.ExpectStructsToMatchExcluding(&collation, &resultCollations[0], "Oid")
   268  		})
   269  	})
   270  })