This is an automated email from the ASF dual-hosted git repository. Smyatkin-Maxim pushed a commit to branch pg-dump-rebase-REL-2 in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit a5b0f1305cb32734a775b6899eddc168887ade23 Author: Brent Doil <[email protected]> AuthorDate: Mon Sep 12 13:15:54 2022 -0400 pg_dump: Move partition def queries to getTables Move pg_get_partition_def and pg_get_partition_template_def queries from dumpTableSchema to getTables. The functions are only run for parent tables. This change reduces the number of repetitive queries and simplifies dumpTableSchema. Authored-by: Brent Doil <[email protected]> --- src/bin/pg_dump/pg_dump.c | 147 ++++++++++++---------------------------------- src/bin/pg_dump/pg_dump.h | 8 ++- 2 files changed, 44 insertions(+), 111 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 20bb7db6f80..7e47f5fa986 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -7067,6 +7067,8 @@ getTables(Archive *fout, int *numTables) int i_isivm; int i_isdynamic; int i_relstorage; + int i_partclause; + int i_parttemplate; /* * Find all the tables and table-like objects. @@ -7238,12 +7240,18 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "pg_get_partkeydef(c.oid) AS partkeydef, " "c.relispartition AS ispartition, " - "pg_get_expr(c.relpartbound, c.oid) AS partbound "); + "pg_get_expr(c.relpartbound, c.oid) AS partbound, " + "NULL as partclause, " + "NULL as parttemplate"); else appendPQExpBufferStr(query, "NULL AS partkeydef, " - "false AS ispartition, " - "NULL AS partbound "); + "0 AS ispartition," + "NULL AS partbound, " + "CASE WHEN pl.parlevel = 0 THEN " + "(SELECT pg_get_partition_def(c.oid, true, true)) END AS partclause, " + "CASE WHEN pl.parlevel = 0 THEN " + "(SELECT pg_get_partition_template_def(c.oid, true, true)) END as parttemplate "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7376,6 +7384,8 @@ getTables(Archive *fout, int *numTables) i_relstorage = PQfnumber(res, "relstorage"); i_parrelid = PQfnumber(res, "parrelid"); i_parlevel = PQfnumber(res, "parlevel"); + i_partclause = PQfnumber(res, "partclause"); + i_parttemplate = PQfnumber(res, "parttemplate"); if (dopt->lockWaitTimeout) { @@ -7459,7 +7469,17 @@ getTables(Archive *fout, int *numTables) tblinfo[i].relstorage = *(PQgetvalue(res, i, i_relstorage)); - if (tblinfo[i].parparent && tblinfo[i].parrelid != 0 && tblinfo[i].relstorage == 'x') + if (PQgetisnull(res, i, i_parlevel) || + atoi(PQgetvalue(res, i, i_parlevel)) > 0) + tblinfo[i].parparent = false; + else + { + tblinfo[i].parparent = true; + tblinfo[i].partclause = pg_strdup(PQgetvalue(res, i, i_partclause)); + tblinfo[i].parttemplate = pg_strdup(PQgetvalue(res, i, i_parttemplate)); + } + + if (!tblinfo[i].parparent && tblinfo[i].parrelid != 0 && tblinfo[i].relstorage == 'x') { /* * Length of tmpStr is bigger than the sum of NAMEDATALEN @@ -7469,11 +7489,6 @@ getTables(Archive *fout, int *numTables) snprintf(tmpStr, sizeof(tmpStr), "%s%s", tblinfo[i].dobj.name, EXT_PARTITION_NAME_POSTFIX); tblinfo[i].dobj.name = pg_strdup(tmpStr); } - if (PQgetisnull(res, i, i_parlevel) || - atoi(PQgetvalue(res, i, i_parlevel)) > 0) - tblinfo[i].parparent = false; - else - tblinfo[i].parparent = true; if (PQgetisnull(res, i, i_amoid)) tblinfo[i].amoid = InvalidOid; @@ -7547,7 +7562,7 @@ getTables(Archive *fout, int *numTables) * * We only need to lock the table for certain components; see * pg_dump.h - * + * * GPDB: Build a single LOCK TABLE statement to lock all interesting tables. * This is more performant than issuing a separate LOCK TABLE statement for each table, * with considerable savings in FE/BE overhead. It does come at the cost of some increased @@ -17606,6 +17621,9 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo) { Oid part_oid = atooid(PQgetvalue(partres, i, 0)); + if (tbinfo->relstorage == 'x') + hasExternalPartitions = true; + binary_upgrade_set_pg_class_oids(fout, q, part_oid, false); binary_upgrade_set_type_oids_by_rel_oid(fout, q, part_oid); } @@ -17906,107 +17924,18 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo) addDistributedBy(fout, q, tbinfo, actual_atts); /* - * Add the partitioning constraints to the table definition. This - * check used to look for existence of pg_partition table to make the - * decision, instead seems better to decide based on version. GPDB6 - * and below have pg_get_partition_def functions. + * Add the GPDB partitioning constraints to the table definition. + * These do not exist on GPDB7, so first check if we are dumping + * from <= GPDB6. */ - if (fout->remoteVersion <= 90400 && tbinfo->parparent) + if (fout->remoteVersion <= 90400 && + (*tbinfo->partclause && *tbinfo->partclause != '\0')) { - bool isPartitioned = false; - PQExpBuffer query = createPQExpBuffer(); - PGresult *res; - - /* does support GP partitioning. */ - resetPQExpBuffer(query); - appendPQExpBuffer(query, "SELECT " - "pg_get_partition_def('%u'::pg_catalog.oid, true, true) ", - tbinfo->dobj.catId.oid); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - { - if (PQntuples(res) < 1) - pg_log_warning("query to obtain definition of table \"%s\" returned no data", - tbinfo->dobj.name); - else - pg_log_warning("query to obtain definition of table \"%s\" returned more than one definition", - tbinfo->dobj.name); - exit_nicely(1); - } - isPartitioned = !PQgetisnull(res, 0, 0); - if (isPartitioned) - appendPQExpBuffer(q, " %s", PQgetvalue(res, 0, 0)); - - PQclear(res); - - /* - * MPP-6095: dump ALTER TABLE statements for subpartition - * templates - */ - resetPQExpBuffer(query); - - appendPQExpBuffer( - query, "SELECT " - "pg_get_partition_template_def('%u'::pg_catalog.oid, true, true) ", - tbinfo->dobj.catId.oid); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - { - if (PQntuples(res) < 1) - pg_log_warning("query to obtain definition of table \"%s\" returned no data", - tbinfo->dobj.name); - else - pg_log_warning("query to obtain definition of table \"%s\" returned more than one definition", - tbinfo->dobj.name); - exit_nicely(1); - } - - /* - * MPP-9537: terminate (with semicolon) the previous - * statement, and dump the template definitions - */ - if (!PQgetisnull(res, 0, 0) && - PQgetlength(res, 0, 0)) - appendPQExpBuffer(q, ";\n %s", PQgetvalue(res, 0, 0)); - - PQclear(res); - - /* - * If GP partitioning is supported and table is a parent partition - * add the partitioning constraints to the table definition. - */ - if (isPartitioned && tbinfo->parparent) - { - /* - * Find out if there are any external partitions. - * - * In GPDB 6.X and below, external tables have - * relkind=RELKIND_RELATION and relstorage=RELSTORAGE_EXTERNAL. - * In later versions, they are just foreign tables. This query - * works on all server versions. - */ - resetPQExpBuffer(query); - appendPQExpBuffer(query, "SELECT EXISTS (SELECT 1 " - " FROM pg_class part " - " JOIN pg_partition_rule pr ON (part.oid = pr.parchildrelid) " - " JOIN pg_partition p ON (pr.paroid = p.oid) " - "WHERE p.parrelid = '%u'::pg_catalog.oid " - " AND (part.relstorage = '%c' OR part.relkind = '%c')) " - "AS has_external_partitions;", - tbinfo->dobj.catId.oid, - RELSTORAGE_EXTERNAL, - RELKIND_FOREIGN_TABLE); - - res = ExecuteSqlQueryForSingleRow(fout, query->data); - hasExternalPartitions = (PQgetvalue(res, 0, 0)[0] == 't'); - PQclear(res); - } - - destroyPQExpBuffer(query); + /* partition by clause */ + appendPQExpBuffer(q, " %s", tbinfo->partclause); + /* subpartition template */ + if (tbinfo->parttemplate) + appendPQExpBuffer(q, ";\n %s", tbinfo->parttemplate); } /* END MPP ADDITION */ /* Dump generic options if any */ diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index f1a309d20b8..71cf6866ebf 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -394,8 +394,12 @@ typedef struct _tableInfo struct _tableDataInfo *dataObj; /* TableDataInfo, if dumping its data */ int numTriggers; /* number of triggers for table */ struct _triggerInfo *triggers; /* array of TriggerInfo structs */ - bool isivm; /* is incrementally maintainable materialized view? */ - bool isdynamic; /* is dynamic table? */ + + /* GPDB */ + bool isivm; /* is incrementally maintainable materialized view? */ + bool isdynamic; /* is dynamic table? */ + char *partclause; /* partition definition, if table is partition parent */ + char *parttemplate; /* subpartition template */ } TableInfo; typedef struct _tableAttachInfo --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
