This is an automated email from the ASF dual-hosted git repository.

tuhaihe pushed a commit to branch add-behave-test-ci
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 4f1588405e3b249de6e9a74acb07bed69a25c11c
Author: Dianjin Wang <[email protected]>
AuthorDate: Fri Sep 11 12:24:24 2026 +0800

    minirepro: dump the tables a view reads
    
    minirepro asks gp_dump_query_oids which objects a query touches, and for
    a query over a view the answer is the view alone. The resulting dump
    cannot reproduce the plan, because the base tables and -- more to the
    point -- their statistics are missing.
    
    Expand view dependencies through pg_rewrite so the tables behind a view
    are dumped alongside it, and build the SQL literal by doubling quotes
    instead of calling Escape(), which mangled non-ASCII query text.
---
 gpMgmt/bin/minirepro | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/gpMgmt/bin/minirepro b/gpMgmt/bin/minirepro
index 79d4c9fbb31..9a93389b14c 100755
--- a/gpMgmt/bin/minirepro
+++ b/gpMgmt/bin/minirepro
@@ -74,6 +74,11 @@ sysnslist = "('pg_toast', 'pg_bitmapindex', 'pg_catalog', 
'information_schema',
 # unset search path due to CVE-2018-1058
 pgoptions = '-c optimizer=off -c gp_role=utility -c search_path='
 
+
+def escape_sql_literal(value):
+    return value.replace("'", "''")
+
+
 class MRQuery(object):
     def __init__(self):
         self.schemas = []
@@ -136,7 +141,7 @@ def dump_query(connectionInfo, query_file):
 
     with open(query_file, 'r') as query_f:
         sql_text = query_f.read()
-    query = "select pg_catalog.gp_dump_query_oids('%s')" % Escape(sql_text)
+    query = "select pg_catalog.gp_dump_query_oids('%s')" % 
escape_sql_literal(sql_text)
 
     toolkit_sql = PATH_PREFIX + 'toolkit.sql'
     with open(toolkit_sql, 'w') as toolkit_f:
@@ -165,6 +170,27 @@ def parse_oids(cursor, json_oids):
     if len(result.funcids) == 0:
         result.funcids = '0'
 
+    # In PG16, gp_dump_query_oids may return only view OIDs without their
+    # dependent table OIDs. Expand view dependencies so pg_dump includes
+    # the tables that views reference.
+    dep_query = "SELECT DISTINCT d.refobjid FROM pg_depend d " \
+                "JOIN pg_class c ON d.classid = 'pg_rewrite'::regclass " \
+                "JOIN pg_rewrite r ON d.objid = r.oid " \
+                "WHERE r.ev_class IN (%s) AND d.refobjid != r.ev_class " \
+                "AND d.refclassid = 'pg_class'::regclass " \
+                "AND d.refobjid NOT IN (%s)" % (result.relids, result.relids)
+    try:
+        cursor.execute(dep_query)
+        dep_oids = [str(row[0]) for row in result_iter(cursor)]
+        if dep_oids:
+            result.relids = result.relids + ',' + ','.join(dep_oids)
+    except pgdb.DatabaseError as e:
+        # The dump is still usable without the view's base tables, so warn
+        # and carry on with the OIDs gp_dump_query_oids gave us.
+        sys.stderr.write('\nWarning: could not expand view dependencies; '
+                         'the dump may be missing tables referenced by 
views.\n\n'
+                         + str(e) + '\n\n')
+
     cat_query = "SELECT distinct(nspname) FROM pg_class c, pg_namespace n 
WHERE " \
                 "c.relnamespace = n.oid AND c.oid IN (%s) " \
                 "AND n.nspname NOT IN %s" % (result.relids, sysnslist)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to