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]
