From 18a85dd7be179d13a8557a473098d9841fe3df05 Mon Sep 17 00:00:00 2001 From: Robert Mu Date: Sat, 28 Feb 2026 17:52:56 +0800 Subject: [PATCH] fix: correct comment syntax for external tables in GPDB 7+ and Cloudberry In GPDB 7.0+ and Cloudberry Database, external tables are implemented as foreign tables under the hood. When gpbackup exports metadata for an external table with a comment, using the traditional "TABLE" object type causes an error during gprestore because the database expects "FOREIGN TABLE" syntax for these objects. This change updates the GetMetadataEntry logic to correctly identify external tables as "FOREIGN TABLE" in newer database versions. SQL Comparison: Before (Fails on GPDB 7+ / Cloudberry): -------------------------------------------------- COMMENT ON TABLE public.my_ext_table IS 'this is an external table comment'; After (Executes successfully): -------------------------------------------------- COMMENT ON FOREIGN TABLE public.my_ext_table IS 'this is an external table comment'; --- backup/predata_externals_test.go | 6 +++++- backup/queries_table_defs.go | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/backup/predata_externals_test.go b/backup/predata_externals_test.go index 2eac072f..a9515d97 100644 --- a/backup/predata_externals_test.go +++ b/backup/predata_externals_test.go @@ -95,7 +95,11 @@ var _ = Describe("backup/predata_externals tests", func() { extTableDef.URIs = []string{"file://host:port/path/file"} testTable.ExtTableDef = extTableDef backup.PrintExternalTableCreateStatement(backupfile, tocfile, testTable) - testutils.ExpectEntry(tocfile.PredataEntries, 0, "public", "", "tablename", toc.OBJ_TABLE) + expectedObjectType := toc.OBJ_TABLE + if (connectionPool.Version.IsGPDB() && connectionPool.Version.AtLeast("7")) || connectionPool.Version.IsCBDB() { + expectedObjectType = toc.OBJ_FOREIGN_TABLE + } + testutils.ExpectEntry(tocfile.PredataEntries, 0, "public", "", "tablename", expectedObjectType) testutils.AssertBufferContents(tocfile.PredataEntries, buffer, `CREATE READABLE EXTERNAL TABLE public.tablename ( ) LOCATION ( 'file://host:port/path/file' diff --git a/backup/queries_table_defs.go b/backup/queries_table_defs.go index 5edb1040..4c6bf612 100644 --- a/backup/queries_table_defs.go +++ b/backup/queries_table_defs.go @@ -32,6 +32,9 @@ func (t Table) GetMetadataEntry() (string, toc.MetadataEntry) { if (t.ForeignDef != ForeignTableDefinition{}) { objectType = toc.OBJ_FOREIGN_TABLE } + if t.IsExternal && ((connectionPool.Version.IsGPDB() && connectionPool.Version.AtLeast("7")) || connectionPool.Version.IsCBDB()) { + objectType = toc.OBJ_FOREIGN_TABLE + } referenceObject := "" if t.AttachPartitionInfo != (AttachPartitionInfo{}) { referenceObject = t.AttachPartitionInfo.Parent