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

     1  package integration
     2  
     3  import (
     4  	"github.com/tuhaihe/gp-common-go-libs/testhelper"
     5  	"github.com/tuhaihe/gpbackup/backup"
     6  	"github.com/tuhaihe/gpbackup/testutils"
     7  
     8  	. "github.com/onsi/ginkgo/v2"
     9  	. "github.com/onsi/gomega"
    10  )
    11  
    12  var _ = Describe("backup integration tests", func() {
    13  	Describe("GetDependencies", func() {
    14  		It("correctly constructs table inheritance dependencies", func() {
    15  			testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.foo(i int, j text, k bool)")
    16  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.foo")
    17  			testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.bar(m int) inherits (public.foo)")
    18  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.bar")
    19  
    20  			oidFoo := testutils.OidFromObjectName(connectionPool, "public", "foo", backup.TYPE_RELATION)
    21  			oidBar := testutils.OidFromObjectName(connectionPool, "public", "bar", backup.TYPE_RELATION)
    22  			fooEntry := backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: oidFoo}
    23  			barEntry := backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: oidBar}
    24  			backupSet := map[backup.UniqueID]bool{fooEntry: true, barEntry: true}
    25  			tables := make([]backup.Table, 0)
    26  
    27  			deps := backup.GetDependencies(connectionPool, backupSet, tables)
    28  
    29  			Expect(deps).To(HaveLen(1))
    30  			Expect(deps[barEntry]).To(HaveLen(1))
    31  			Expect(deps[barEntry]).To(HaveKey(fooEntry))
    32  		})
    33  		It("constructs dependencies correctly for a table dependent on a protocol", func() {
    34  			testhelper.AssertQueryRuns(connectionPool, `CREATE FUNCTION public.read_from_s3() RETURNS integer
    35  		AS '$libdir/gps3ext.so', 's3_import'
    36  		LANGUAGE c STABLE NO SQL;`)
    37  			defer testhelper.AssertQueryRuns(connectionPool, "DROP FUNCTION public.read_from_s3()")
    38  			testhelper.AssertQueryRuns(connectionPool, `CREATE PROTOCOL s3 (readfunc = public.read_from_s3);`)
    39  			defer testhelper.AssertQueryRuns(connectionPool, "DROP PROTOCOL s3")
    40  			testhelper.AssertQueryRuns(connectionPool, `CREATE EXTERNAL TABLE public.ext_tbl (
    41  		i int
    42  		) LOCATION (
    43  		's3://192.168.0.1'
    44  		)
    45  		FORMAT 'csv' (delimiter E',' null E'' escape E'"' quote E'"')
    46  		ENCODING 'UTF8';`)
    47  			defer testhelper.AssertQueryRuns(connectionPool, "DROP EXTERNAL TABLE public.ext_tbl")
    48  
    49  			tableOid := testutils.OidFromObjectName(connectionPool, "public", "ext_tbl", backup.TYPE_RELATION)
    50  			protocolOid := testutils.OidFromObjectName(connectionPool, "", "s3", backup.TYPE_PROTOCOL)
    51  			functionOid := testutils.OidFromObjectName(connectionPool, "public", "read_from_s3", backup.TYPE_FUNCTION)
    52  
    53  			tableEntry := backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: tableOid}
    54  			protocolEntry := backup.UniqueID{ClassID: backup.PG_EXTPROTOCOL_OID, Oid: protocolOid}
    55  			functionEntry := backup.UniqueID{ClassID: backup.PG_PROC_OID, Oid: functionOid}
    56  			backupSet := map[backup.UniqueID]bool{tableEntry: true, protocolEntry: true, functionEntry: true}
    57  			tables := make([]backup.Table, 0)
    58  
    59  			deps := backup.GetDependencies(connectionPool, backupSet, tables)
    60  
    61  			Expect(deps).To(HaveLen(2))
    62  			Expect(deps[tableEntry]).To(HaveLen(1))
    63  			Expect(deps[tableEntry]).To(HaveKey(protocolEntry))
    64  			Expect(deps[protocolEntry]).To(HaveLen(1))
    65  			Expect(deps[protocolEntry]).To(HaveKey(functionEntry))
    66  		})
    67  		It("constructs dependencies correctly for a view that depends on two other views", func() {
    68  			testhelper.AssertQueryRuns(connectionPool, "CREATE VIEW public.parent1 AS SELECT relname FROM pg_class")
    69  			defer testhelper.AssertQueryRuns(connectionPool, "DROP VIEW public.parent1")
    70  			testhelper.AssertQueryRuns(connectionPool, "CREATE VIEW public.parent2 AS SELECT relname FROM pg_class")
    71  			defer testhelper.AssertQueryRuns(connectionPool, "DROP VIEW public.parent2")
    72  			testhelper.AssertQueryRuns(connectionPool, "CREATE VIEW public.child AS (SELECT * FROM public.parent1 UNION SELECT * FROM public.parent2)")
    73  			defer testhelper.AssertQueryRuns(connectionPool, "DROP VIEW public.child")
    74  
    75  			parent1Oid := testutils.OidFromObjectName(connectionPool, "public", "parent1", backup.TYPE_RELATION)
    76  			parent2Oid := testutils.OidFromObjectName(connectionPool, "public", "parent2", backup.TYPE_RELATION)
    77  			childOid := testutils.OidFromObjectName(connectionPool, "public", "child", backup.TYPE_RELATION)
    78  
    79  			parent1Entry := backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: parent1Oid}
    80  			parent2Entry := backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: parent2Oid}
    81  			childEntry := backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: childOid}
    82  			backupSet := map[backup.UniqueID]bool{parent1Entry: true, parent2Entry: true, childEntry: true}
    83  			tables := make([]backup.Table, 0)
    84  
    85  			deps := backup.GetDependencies(connectionPool, backupSet, tables)
    86  
    87  			Expect(deps).To(HaveLen(1))
    88  			Expect(deps[childEntry]).To(HaveLen(2))
    89  			Expect(deps[childEntry]).To(HaveKey(parent1Entry))
    90  			Expect(deps[childEntry]).To(HaveKey(parent2Entry))
    91  		})
    92  		It("constructs dependencies correctly for a materialized view that depends on two other materialized views", func() {
    93  			if false {
    94  				Skip("Test only applicable to GPDB 6.2 and above")
    95  			}
    96  			testhelper.AssertQueryRuns(connectionPool, "CREATE MATERIALIZED VIEW public.parent1 AS SELECT relname FROM pg_class")
    97  			defer testhelper.AssertQueryRuns(connectionPool, "DROP MATERIALIZED VIEW public.parent1")
    98  			testhelper.AssertQueryRuns(connectionPool, "CREATE MATERIALIZED VIEW public.parent2 AS SELECT relname FROM pg_class")
    99  			defer testhelper.AssertQueryRuns(connectionPool, "DROP MATERIALIZED VIEW public.parent2")
   100  			testhelper.AssertQueryRuns(connectionPool, "CREATE MATERIALIZED VIEW public.child AS (SELECT * FROM public.parent1 UNION SELECT * FROM public.parent2)")
   101  			defer testhelper.AssertQueryRuns(connectionPool, "DROP MATERIALIZED VIEW public.child")
   102  
   103  			parent1Oid := testutils.OidFromObjectName(connectionPool, "public", "parent1", backup.TYPE_RELATION)
   104  			parent2Oid := testutils.OidFromObjectName(connectionPool, "public", "parent2", backup.TYPE_RELATION)
   105  			childOid := testutils.OidFromObjectName(connectionPool, "public", "child", backup.TYPE_RELATION)
   106  
   107  			parent1Entry := backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: parent1Oid}
   108  			parent2Entry := backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: parent2Oid}
   109  			childEntry := backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: childOid}
   110  			backupSet := map[backup.UniqueID]bool{parent1Entry: true, parent2Entry: true, childEntry: true}
   111  			tables := make([]backup.Table, 0)
   112  
   113  			deps := backup.GetDependencies(connectionPool, backupSet, tables)
   114  
   115  			Expect(deps).To(HaveLen(1))
   116  			Expect(deps[childEntry]).To(HaveLen(2))
   117  			Expect(deps[childEntry]).To(HaveKey(parent1Entry))
   118  			Expect(deps[childEntry]).To(HaveKey(parent2Entry))
   119  		})
   120  		It("constructs dependencies correctly for a view dependent on text search objects", func() {
   121  			testutils.SkipIfBefore5(connectionPool)
   122  			testhelper.AssertQueryRuns(connectionPool, "CREATE TEXT SEARCH PARSER public.testparser(START = prsd_start, GETTOKEN = prsd_nexttoken, END = prsd_end, LEXTYPES = prsd_lextype);")
   123  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TEXT SEARCH PARSER public.testparser;")
   124  			testhelper.AssertQueryRuns(connectionPool, "CREATE TEXT SEARCH CONFIGURATION public.testconfig(PARSER = public.testparser);")
   125  			defer testhelper.AssertQueryRuns(connectionPool, "DROP TEXT SEARCH CONFIGURATION public.testconfig;")
   126  			testhelper.AssertQueryRuns(connectionPool, `CREATE VIEW public.ts_config_view AS SELECT * FROM ts_debug('public.testconfig',
   127  'PostgreSQL, the highly scalable, SQL compliant, open source
   128  object-relational database management system');`)
   129  			defer testhelper.AssertQueryRuns(connectionPool, "DROP VIEW public.ts_config_view;")
   130  
   131  			parserID := testutils.UniqueIDFromObjectName(connectionPool, "public", "testparser", backup.TYPE_TSPARSER)
   132  			configID := testutils.UniqueIDFromObjectName(connectionPool, "public", "testconfig", backup.TYPE_TSCONFIGURATION)
   133  			viewID := testutils.UniqueIDFromObjectName(connectionPool, "public", "ts_config_view", backup.TYPE_RELATION)
   134  			backupSet := map[backup.UniqueID]bool{parserID: true, configID: true, viewID: true}
   135  			tables := make([]backup.Table, 0)
   136  
   137  			deps := backup.GetDependencies(connectionPool, backupSet, tables)
   138  			Expect(deps).To(HaveLen(2))
   139  			Expect(deps[configID]).To(HaveLen(1))
   140  			Expect(deps[configID]).To(HaveKey(parserID))
   141  			Expect(deps[viewID]).To(HaveLen(1))
   142  			Expect(deps[viewID]).To(HaveKey(configID))
   143  		})
   144  		Describe("function dependencies", func() {
   145  			var compositeEntry backup.UniqueID
   146  			BeforeEach(func() {
   147  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.composite_ints AS (one integer, two integer)")
   148  				compositeOid := testutils.OidFromObjectName(connectionPool, "public", "composite_ints", backup.TYPE_TYPE)
   149  				compositeEntry = backup.UniqueID{ClassID: backup.PG_TYPE_OID, Oid: compositeOid}
   150  			})
   151  			AfterEach(func() {
   152  				testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.composite_ints CASCADE")
   153  			})
   154  			It("constructs dependencies correctly for a function dependent on a user-defined type in the arguments", func() {
   155  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.add(public.composite_ints) RETURNS integer STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT ($1.one + $1.two);'")
   156  				defer testhelper.AssertQueryRuns(connectionPool, "DROP FUNCTION public.add(public.composite_ints)")
   157  
   158  				functionOid := testutils.OidFromObjectName(connectionPool, "public", "add", backup.TYPE_FUNCTION)
   159  				funcEntry := backup.UniqueID{ClassID: backup.PG_PROC_OID, Oid: functionOid}
   160  				backupSet := map[backup.UniqueID]bool{funcEntry: true, compositeEntry: true}
   161  				tables := make([]backup.Table, 0)
   162  
   163  				functionDeps := backup.GetDependencies(connectionPool, backupSet, tables)
   164  
   165  				Expect(functionDeps).To(HaveLen(1))
   166  				Expect(functionDeps[funcEntry]).To(HaveLen(1))
   167  				Expect(functionDeps[funcEntry]).To(HaveKey(compositeEntry))
   168  			})
   169  			It("constructs dependencies correctly for a function dependent on a user-defined type in the return type", func() {
   170  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.compose(integer, integer) RETURNS public.composite_ints STRICT IMMUTABLE LANGUAGE PLPGSQL AS 'DECLARE comp public.composite_ints; BEGIN SELECT $1, $2 INTO comp; RETURN comp; END;';")
   171  				defer testhelper.AssertQueryRuns(connectionPool, "DROP FUNCTION public.compose(integer, integer)")
   172  
   173  				functionOid := testutils.OidFromObjectName(connectionPool, "public", "compose", backup.TYPE_FUNCTION)
   174  				funcEntry := backup.UniqueID{ClassID: backup.PG_PROC_OID, Oid: functionOid}
   175  				backupSet := map[backup.UniqueID]bool{funcEntry: true, compositeEntry: true}
   176  				tables := make([]backup.Table, 0)
   177  
   178  				functionDeps := backup.GetDependencies(connectionPool, backupSet, tables)
   179  
   180  				Expect(functionDeps).To(HaveLen(1))
   181  				Expect(functionDeps[funcEntry]).To(HaveLen(1))
   182  				Expect(functionDeps[funcEntry]).To(HaveKey(compositeEntry))
   183  			})
   184  			It("constructs dependencies correctly for a function dependent on an implicit array type", func() {
   185  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_type")
   186  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.base_type CASCADE")
   187  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_fn_in(cstring) RETURNS public.base_type AS 'boolin' LANGUAGE internal")
   188  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_fn_out(public.base_type) RETURNS cstring AS 'boolout' LANGUAGE internal")
   189  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_type(INPUT=public.base_fn_in, OUTPUT=public.base_fn_out)")
   190  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.compose(public.base_type[], public.composite_ints) RETURNS public.composite_ints STRICT IMMUTABLE LANGUAGE PLPGSQL AS 'DECLARE comp public.composite_ints; BEGIN SELECT $1[0].one+$2.one, $1[0].two+$2.two INTO comp; RETURN comp; END;';")
   191  				defer testhelper.AssertQueryRuns(connectionPool, "DROP FUNCTION public.compose(public.base_type[], public.composite_ints)")
   192  
   193  				functionOid := testutils.OidFromObjectName(connectionPool, "public", "compose", backup.TYPE_FUNCTION)
   194  				funcEntry := backup.UniqueID{ClassID: backup.PG_PROC_OID, Oid: functionOid}
   195  				baseOid := testutils.OidFromObjectName(connectionPool, "public", "base_type", backup.TYPE_TYPE)
   196  				baseEntry := backup.UniqueID{ClassID: backup.PG_TYPE_OID, Oid: baseOid}
   197  				backupSet := map[backup.UniqueID]bool{funcEntry: true, compositeEntry: true, baseEntry: true}
   198  				tables := make([]backup.Table, 0)
   199  
   200  				functionDeps := backup.GetDependencies(connectionPool, backupSet, tables)
   201  
   202  				Expect(functionDeps).To(HaveLen(1))
   203  				Expect(functionDeps[funcEntry]).To(HaveLen(2))
   204  				Expect(functionDeps[funcEntry]).To(HaveKey(compositeEntry))
   205  				Expect(functionDeps[funcEntry]).To(HaveKey(baseEntry))
   206  			})
   207  		})
   208  		Describe("type dependencies", func() {
   209  			var (
   210  				baseOid   uint32
   211  				baseEntry backup.UniqueID
   212  			)
   213  			BeforeEach(func() {
   214  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_type")
   215  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_fn_in(cstring) RETURNS public.base_type AS 'boolin' LANGUAGE internal")
   216  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_fn_out(public.base_type) RETURNS cstring AS 'boolout' LANGUAGE internal")
   217  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_type(INPUT=public.base_fn_in, OUTPUT=public.base_fn_out)")
   218  
   219  				baseOid = testutils.OidFromObjectName(connectionPool, "public", "base_type", backup.TYPE_TYPE)
   220  				baseEntry = backup.UniqueID{ClassID: backup.PG_TYPE_OID, Oid: baseOid}
   221  			})
   222  			AfterEach(func() {
   223  				testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.base_type CASCADE")
   224  			})
   225  			It("constructs domain dependencies on user-defined types", func() {
   226  				testhelper.AssertQueryRuns(connectionPool, "CREATE DOMAIN public.parent_domain AS integer")
   227  				defer testhelper.AssertQueryRuns(connectionPool, "DROP DOMAIN public.parent_domain")
   228  				testhelper.AssertQueryRuns(connectionPool, "CREATE DOMAIN public.domain_type AS public.parent_domain")
   229  				defer testhelper.AssertQueryRuns(connectionPool, "DROP DOMAIN public.domain_type")
   230  
   231  				domainOid := testutils.OidFromObjectName(connectionPool, "public", "parent_domain", backup.TYPE_TYPE)
   232  				domain2Oid := testutils.OidFromObjectName(connectionPool, "public", "domain_type", backup.TYPE_TYPE)
   233  
   234  				domainEntry := backup.UniqueID{ClassID: backup.PG_TYPE_OID, Oid: domainOid}
   235  				domain2Entry := backup.UniqueID{ClassID: backup.PG_TYPE_OID, Oid: domain2Oid}
   236  				backupSet := map[backup.UniqueID]bool{domainEntry: true, domain2Entry: true}
   237  				tables := make([]backup.Table, 0)
   238  
   239  				deps := backup.GetDependencies(connectionPool, backupSet, tables)
   240  
   241  				Expect(deps).To(HaveLen(1))
   242  				Expect(deps[domain2Entry]).To(HaveLen(1))
   243  				Expect(deps[domain2Entry]).To(HaveKey(domainEntry))
   244  			})
   245  
   246  			It("constructs dependencies correctly for a function/base type dependency loop", func() {
   247  				baseInOid := testutils.OidFromObjectName(connectionPool, "public", "base_fn_in", backup.TYPE_FUNCTION)
   248  				baseOutOid := testutils.OidFromObjectName(connectionPool, "public", "base_fn_out", backup.TYPE_FUNCTION)
   249  
   250  				baseInEntry := backup.UniqueID{ClassID: backup.PG_PROC_OID, Oid: baseInOid}
   251  				baseOutEntry := backup.UniqueID{ClassID: backup.PG_PROC_OID, Oid: baseOutOid}
   252  				backupSet := map[backup.UniqueID]bool{baseEntry: true, baseInEntry: true, baseOutEntry: true}
   253  				tables := make([]backup.Table, 0)
   254  
   255  				deps := backup.GetDependencies(connectionPool, backupSet, tables)
   256  
   257  				Expect(deps).To(HaveLen(1))
   258  				Expect(deps[baseEntry]).To(HaveLen(2))
   259  				Expect(deps[baseEntry]).To(HaveKey(baseInEntry))
   260  				Expect(deps[baseEntry]).To(HaveKey(baseOutEntry))
   261  			})
   262  			It("constructs dependencies correctly for a composite type dependent on one user-defined type", func() {
   263  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.comp_type AS (base public.base_type, builtin integer)")
   264  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.comp_type")
   265  
   266  				compositeOid := testutils.OidFromObjectName(connectionPool, "public", "comp_type", backup.TYPE_TYPE)
   267  				compositeEntry := backup.UniqueID{ClassID: backup.PG_TYPE_OID, Oid: compositeOid}
   268  				backupSet := map[backup.UniqueID]bool{baseEntry: true, compositeEntry: true}
   269  				tables := make([]backup.Table, 0)
   270  
   271  				deps := backup.GetDependencies(connectionPool, backupSet, tables)
   272  
   273  				Expect(deps).To(HaveLen(1))
   274  				Expect(deps[compositeEntry]).To(HaveLen(1))
   275  				Expect(deps[compositeEntry]).To(HaveKey(baseEntry))
   276  			})
   277  			It("constructs dependencies correctly for a composite type dependent on multiple user-defined types", func() {
   278  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_type2")
   279  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.base_type2 CASCADE")
   280  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_fn_in2(cstring) RETURNS public.base_type2 AS 'boolin' LANGUAGE internal")
   281  				testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_fn_out2(public.base_type2) RETURNS cstring AS 'boolout' LANGUAGE internal")
   282  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_type2(INPUT=public.base_fn_in2, OUTPUT=public.base_fn_out2)")
   283  
   284  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.comp_type AS (base public.base_type, base2 public.base_type2)")
   285  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.comp_type")
   286  
   287  				base2Oid := testutils.OidFromObjectName(connectionPool, "public", "base_type2", backup.TYPE_TYPE)
   288  				base2Entry := backup.UniqueID{ClassID: backup.PG_TYPE_OID, Oid: base2Oid}
   289  				compositeOid := testutils.OidFromObjectName(connectionPool, "public", "comp_type", backup.TYPE_TYPE)
   290  				compositeEntry := backup.UniqueID{ClassID: backup.PG_TYPE_OID, Oid: compositeOid}
   291  				backupSet := map[backup.UniqueID]bool{baseEntry: true, base2Entry: true, compositeEntry: true}
   292  				tables := make([]backup.Table, 0)
   293  
   294  				deps := backup.GetDependencies(connectionPool, backupSet, tables)
   295  
   296  				Expect(deps).To(HaveLen(1))
   297  				Expect(deps[compositeEntry]).To(HaveLen(2))
   298  				Expect(deps[compositeEntry]).To(HaveKey(baseEntry))
   299  				Expect(deps[compositeEntry]).To(HaveKey(base2Entry))
   300  			})
   301  			It("constructs dependencies correctly for a composite type dependent on the same user-defined type multiple times", func() {
   302  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.comp_type AS (base public.base_type, base2 public.base_type)")
   303  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.comp_type")
   304  
   305  				compositeOid := testutils.OidFromObjectName(connectionPool, "public", "comp_type", backup.TYPE_TYPE)
   306  				compositeEntry := backup.UniqueID{ClassID: backup.PG_TYPE_OID, Oid: compositeOid}
   307  				backupSet := map[backup.UniqueID]bool{baseEntry: true, compositeEntry: true}
   308  				tables := make([]backup.Table, 0)
   309  
   310  				deps := backup.GetDependencies(connectionPool, backupSet, tables)
   311  
   312  				Expect(deps).To(HaveLen(1))
   313  				Expect(deps[compositeEntry]).To(HaveLen(1))
   314  				Expect(deps[compositeEntry]).To(HaveKey(baseEntry))
   315  			})
   316  			It("constructs dependencies correctly for a composite type dependent on a table", func() {
   317  				testhelper.AssertQueryRuns(connectionPool, "CREATE TABLE public.my_table(i int)")
   318  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TABLE public.my_table")
   319  				testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.my_type AS (type1 public.my_table)")
   320  				defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.my_type")
   321  
   322  				tableOid := testutils.OidFromObjectName(connectionPool, "public", "my_table", backup.TYPE_RELATION)
   323  				typeOid := testutils.OidFromObjectName(connectionPool, "public", "my_type", backup.TYPE_TYPE)
   324  
   325  				tableEntry := backup.UniqueID{ClassID: backup.PG_CLASS_OID, Oid: tableOid}
   326  				typeEntry := backup.UniqueID{ClassID: backup.PG_TYPE_OID, Oid: typeOid}
   327  				backupSet := map[backup.UniqueID]bool{tableEntry: true, typeEntry: true}
   328  				tables := make([]backup.Table, 0)
   329  
   330  				deps := backup.GetDependencies(connectionPool, backupSet, tables)
   331  
   332  				Expect(deps).To(HaveLen(1))
   333  				Expect(deps[typeEntry]).To(HaveLen(1))
   334  				Expect(deps[typeEntry]).To(HaveKey(tableEntry))
   335  			})
   336  		})
   337  	})
   338  })