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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]