This is an automated email from the ASF dual-hosted git repository. gfphoenix78 pushed a commit to branch sync-with-upstream in repository https://gitbox.apache.org/repos/asf/cloudberry-gpbackup.git
The following commit(s) were added to refs/heads/sync-with-upstream by this push: new 1cbdec5c Fix: Correctly handle base array type creation on Cloudberry (#32) 1cbdec5c is described below commit 1cbdec5c4f747c8b22e4af037a672bf42367bbb1 Author: Robert Mu <db...@hotmail.com> AuthorDate: Thu Aug 28 20:54:42 2025 +0800 Fix: Correctly handle base array type creation on Cloudberry (#32) The integration test for user-created array types was failing on Cloudberry. This was due to two related issues stemming from Cloudberry being based on a newer PostgreSQL version (PG14) than Greenplum 7 (PG12). First, creating a base type with an `ELEMENT` attribute on Cloudberry requires a `SUBSCRIPT` function to be provided, a stricter requirement than in Greenplum. The integration test in `predata_types_queries_test.go` is updated to add this `SUBSCRIPT` function only when running against a Cloudberry instance. Second, the `pg_type` system catalog in Cloudberry contains a `typsubscript` column which is absent in Greenplum 7. The previous metadata query was failing to retrieve this information. A dedicated query for Cloudberry has been added in `backup/queries_types.go` to fetch this field, with the `GetBaseTypes` function now using the appropriate query based on the database connection. --- backup/predata_types.go | 3 +++ backup/queries_types.go | 40 ++++++++++++++++++++++++++++++- integration/predata_types_queries_test.go | 13 ++++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/backup/predata_types.go b/backup/predata_types.go index b54c7038..bc33226c 100644 --- a/backup/predata_types.go +++ b/backup/predata_types.go @@ -117,6 +117,9 @@ func PrintCreateBaseTypeStatement(metadataFile *utils.FileWithByteCount, objToc if base.Element != "" { metadataFile.MustPrintf(",\n\tELEMENT = %s", base.Element) } + if base.Subscript != "" { + metadataFile.MustPrintf(",\n\tSUBSCRIPT = %s", base.Subscript) + } if base.Delimiter != "" { metadataFile.MustPrintf(",\n\tDELIMITER = '%s'", base.Delimiter) } diff --git a/backup/queries_types.go b/backup/queries_types.go index 257a998a..23ad23df 100644 --- a/backup/queries_types.go +++ b/backup/queries_types.go @@ -48,6 +48,7 @@ type BaseType struct { StorageOptions string Collatable bool Collation string + Subscript string } func (t BaseType) GetMetadataEntry() (string, toc.MetadataEntry) { @@ -130,9 +131,46 @@ func GetBaseTypes(connectionPool *dbconn.DBConn) []BaseType { AND ut.oid IS NULL AND %s`, SchemaFilterClause("n"), ExtensionFilterClause("t")) + cbdbQuery := fmt.Sprintf(` + SELECT t.oid, + quote_ident(n.nspname) AS schema, + quote_ident(t.typname) AS name, + t.typinput AS input, + t.typoutput AS output, + CASE WHEN t.typreceive = '-'::regproc THEN '' ELSE t.typreceive::regproc::text END AS receive, + CASE WHEN t.typsend = '-'::regproc THEN '' ELSE t.typsend::regproc::text END AS send, + CASE WHEN t.typmodin = '-'::regproc THEN '' ELSE t.typmodin::regproc::text END AS modin, + CASE WHEN t.typmodout = '-'::regproc THEN '' ELSE t.typmodout::regproc::text END AS modout, + t.typlen AS internallength, + t.typbyval AS ispassedbyvalue, + CASE WHEN t.typalign = '-' THEN '' ELSE t.typalign END AS alignment, + t.typstorage AS storage, + coalesce(t.typdefault, '') AS defaultval, + CASE WHEN t.typelem != 0::regproc THEN pg_catalog.format_type(t.typelem, NULL) ELSE '' END AS element, + t.typcategory AS category, + t.typispreferred AS preferred, + t.typdelim AS delimiter, + (t.typcollation <> 0) AS collatable, + coalesce(array_to_string(typoptions, ', '), '') AS storageoptions, + CASE WHEN t.typsubscript = '-'::regproc THEN '' ELSE t.typsubscript::regproc::text END AS subscript + FROM pg_type t + JOIN pg_namespace n ON t.typnamespace = n.oid + LEFT JOIN pg_type_encoding e ON t.oid = e.typid + /* + * Identify if this is an automatically generated array type and exclude it if so. + * In GPDB 5 and 6 we use the typearray field to identify these array types. + */ + LEFT JOIN pg_type ut ON t.oid = ut.typarray + WHERE %s + AND t.typtype = 'b' + AND ut.oid IS NULL + AND %s`, SchemaFilterClause("n"), ExtensionFilterClause("t")) + results := make([]BaseType, 0) var err error - if connectionPool.Version.IsGPDB() && connectionPool.Version.Is("5") { + if connectionPool.Version.IsCBDB() { + err = connectionPool.Select(&results, cbdbQuery) + } else if connectionPool.Version.IsGPDB() && connectionPool.Version.Is("5") { err = connectionPool.Select(&results, version5query) } else { err = connectionPool.Select(&results, atLeast6Query) diff --git a/integration/predata_types_queries_test.go b/integration/predata_types_queries_test.go index 7cc48270..ec5a3c51 100644 --- a/integration/predata_types_queries_test.go +++ b/integration/predata_types_queries_test.go @@ -154,10 +154,19 @@ var _ = Describe("backup integration tests", func() { } testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_array_type") - defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.base_array_type CASCADE") testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_array_fn_in(cstring) RETURNS public.base_array_type AS 'boolin' LANGUAGE internal") testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_array_fn_out(public.base_array_type) RETURNS cstring AS 'boolout' LANGUAGE internal") - testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_array_type(INPUT=public.base_array_fn_in, OUTPUT=public.base_array_fn_out, ELEMENT=text)") + if connectionPool.Version.IsCBDB() { + // For Cloudberry (based on PG14), creating a type with an ELEMENT requires a SUBSCRIPT function. + testhelper.AssertQueryRuns(connectionPool, "CREATE FUNCTION public.base_array_subscript_handler(internal) RETURNS internal AS 'array_subscript_handler' LANGUAGE internal") + defer testhelper.AssertQueryRuns(connectionPool, "DROP FUNCTION public.base_array_subscript_handler(internal)") + testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_array_type(INPUT=public.base_array_fn_in, OUTPUT=public.base_array_fn_out, ELEMENT=text, SUBSCRIPT=public.base_array_subscript_handler)") + arrayType.Subscript = "public.base_array_subscript_handler" + } else { + // For GPDB (based on PG12 or earlier), this is not required. + testhelper.AssertQueryRuns(connectionPool, "CREATE TYPE public.base_array_type(INPUT=public.base_array_fn_in, OUTPUT=public.base_array_fn_out, ELEMENT=text)") + } + defer testhelper.AssertQueryRuns(connectionPool, "DROP TYPE public.base_array_type CASCADE") results := backup.GetBaseTypes(connectionPool) --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cloudberry.apache.org For additional commands, e-mail: commits-h...@cloudberry.apache.org