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

Reply via email to