public inbox for [email protected]help / color / mirror / Atom feed
[PATCH v4 2/2] New command ALTER TABLE ALL IN TABLESPACE SET LOGGED/UNLOGGED 2+ messages / 2 participants [nested] [flat]
* [PATCH v4 2/2] New command ALTER TABLE ALL IN TABLESPACE SET LOGGED/UNLOGGED @ 2020-11-11 14:21 Kyotaro Horiguchi <[email protected]> 0 siblings, 0 replies; 2+ messages in thread From: Kyotaro Horiguchi @ 2020-11-11 14:21 UTC (permalink / raw) To ease invoking ALTER TABLE SET LOGGED/UNLOGGED, this command changes relation persistence of all tables in the specified tablespace. --- src/backend/commands/tablecmds.c | 140 +++++++++++++++++++++++++++++++ src/backend/nodes/copyfuncs.c | 16 ++++ src/backend/nodes/equalfuncs.c | 15 ++++ src/backend/parser/gram.y | 20 +++++ src/backend/tcop/utility.c | 11 +++ src/include/commands/tablecmds.h | 2 + src/include/nodes/nodes.h | 1 + src/include/nodes/parsenodes.h | 9 ++ 8 files changed, 214 insertions(+) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 37a15d31ee..2f65abb19b 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -13696,6 +13696,146 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) return new_tablespaceoid; } +/* + * Alter Table ALL ... SET LOGGED/UNLOGGED + * + * Allows a user to change persistence of all objects in a given tablespace in + * the current database. Objects can be chosen based on the owner of the + * object also, to allow users to change persistene only their objects. The + * main permissions handling is done by the lower-level change persistence + * function. + * + * All to-be-modified objects are locked first. If NOWAIT is specified and the + * lock can't be acquired then we ereport(ERROR). + */ +void +AlterTableSetLoggedAll(AlterTableSetLoggedAllStmt *stmt) +{ + List *relations = NIL; + ListCell *l; + ScanKeyData key[1]; + Relation rel; + TableScanDesc scan; + HeapTuple tuple; + Oid tablespaceoid; + List *role_oids = roleSpecsToIds(NIL); + + /* Ensure we were not asked to change something we can't */ + if (stmt->objtype != OBJECT_TABLE) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("only tables can be specified"))); + + /* Get the tablespace OID */ + tablespaceoid = get_tablespace_oid(stmt->tablespacename, false); + + /* + * Now that the checks are done, check if we should set either to + * InvalidOid because it is our database's default tablespace. + */ + if (tablespaceoid == MyDatabaseTableSpace) + tablespaceoid = InvalidOid; + + /* + * Walk the list of objects in the tablespace to pick up them. This will + * only find objects in our database, of course. + */ + ScanKeyInit(&key[0], + Anum_pg_class_reltablespace, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(tablespaceoid)); + + rel = table_open(RelationRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 1, key); + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple); + Oid relOid = relForm->oid; + + /* + * Do not pick-up objects in pg_catalog as part of this, if an admin + * really wishes to do so, they can issue the individual ALTER + * commands directly. + * + * Also, explicitly avoid any shared tables, temp tables, or TOAST + * (TOAST will be changed with the main table). + */ + if (IsCatalogNamespace(relForm->relnamespace) || + relForm->relisshared || + isAnyTempNamespace(relForm->relnamespace) || + IsToastNamespace(relForm->relnamespace)) + continue; + + /* Only pick up the object type requested */ + if (relForm->relkind != RELKIND_RELATION) + continue; + + /* Check if we are only picking-up objects owned by certain roles */ + if (role_oids != NIL && !list_member_oid(role_oids, relForm->relowner)) + continue; + + /* + * Handle permissions-checking here since we are locking the tables + * and also to avoid doing a bunch of work only to fail part-way. Note + * that permissions will also be checked by AlterTableInternal(). + * + * Caller must be considered an owner on the table of which we're going + * to change persistence. + */ + if (!pg_class_ownercheck(relOid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relOid)), + NameStr(relForm->relname)); + + if (stmt->nowait && + !ConditionalLockRelationOid(relOid, AccessExclusiveLock)) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_IN_USE), + errmsg("aborting because lock on relation \"%s.%s\" is not available", + get_namespace_name(relForm->relnamespace), + NameStr(relForm->relname)))); + else + LockRelationOid(relOid, AccessExclusiveLock); + + /* + * Add to our list of objects of which we're going to change + * persistence. + */ + relations = lappend_oid(relations, relOid); + } + + table_endscan(scan); + table_close(rel, AccessShareLock); + + if (relations == NIL) + ereport(NOTICE, + (errcode(ERRCODE_NO_DATA_FOUND), + errmsg("no matching relations in tablespace \"%s\" found", + tablespaceoid == InvalidOid ? "(database default)" : + get_tablespace_name(tablespaceoid)))); + + /* + * Everything is locked, loop through and change persistence of all of the + * relations. + */ + foreach(l, relations) + { + List *cmds = NIL; + AlterTableCmd *cmd = makeNode(AlterTableCmd); + + if (stmt->logged) + cmd->subtype = AT_SetLogged; + else + cmd->subtype = AT_SetUnLogged; + + cmds = lappend(cmds, cmd); + + EventTriggerAlterTableStart((Node *) stmt); + /* OID is set by AlterTableInternal */ + AlterTableInternal(lfirst_oid(l), cmds, false); + EventTriggerAlterTableEnd(); + } +} + static void index_copy_data(Relation rel, RelFileNode newrnode) { diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index ba3ccc712c..127da5151d 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -4138,6 +4138,19 @@ _copyAlterTableMoveAllStmt(const AlterTableMoveAllStmt *from) return newnode; } +static AlterTableSetLoggedAllStmt * +_copyAlterTableSetLoggedAllStmt(const AlterTableSetLoggedAllStmt *from) +{ + AlterTableSetLoggedAllStmt *newnode = makeNode(AlterTableSetLoggedAllStmt); + + COPY_STRING_FIELD(tablespacename); + COPY_SCALAR_FIELD(objtype); + COPY_SCALAR_FIELD(logged); + COPY_SCALAR_FIELD(nowait); + + return newnode; +} + static CreateExtensionStmt * _copyCreateExtensionStmt(const CreateExtensionStmt *from) { @@ -5441,6 +5454,9 @@ copyObjectImpl(const void *from) case T_AlterTableMoveAllStmt: retval = _copyAlterTableMoveAllStmt(from); break; + case T_AlterTableSetLoggedAllStmt: + retval = _copyAlterTableSetLoggedAllStmt(from); + break; case T_CreateExtensionStmt: retval = _copyCreateExtensionStmt(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index a2ef853dc2..4f13a1762b 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1872,6 +1872,18 @@ _equalAlterTableMoveAllStmt(const AlterTableMoveAllStmt *a, return true; } +static bool +_equalAlterTableSetLoggedAllStmt(const AlterTableSetLoggedAllStmt *a, + const AlterTableSetLoggedAllStmt *b) +{ + COMPARE_STRING_FIELD(tablespacename); + COMPARE_SCALAR_FIELD(objtype); + COMPARE_SCALAR_FIELD(logged); + COMPARE_SCALAR_FIELD(nowait); + + return true; +} + static bool _equalCreateExtensionStmt(const CreateExtensionStmt *a, const CreateExtensionStmt *b) { @@ -3494,6 +3506,9 @@ equal(const void *a, const void *b) case T_AlterTableMoveAllStmt: retval = _equalAlterTableMoveAllStmt(a, b); break; + case T_AlterTableSetLoggedAllStmt: + retval = _equalAlterTableSetLoggedAllStmt(a, b); + break; case T_CreateExtensionStmt: retval = _equalCreateExtensionStmt(a, b); break; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 31c95443a5..2222fd8fe3 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -1934,6 +1934,26 @@ AlterTableStmt: n->nowait = $13; $$ = (Node *)n; } + | ALTER TABLE ALL IN_P TABLESPACE name SET LOGGED opt_nowait + { + AlterTableSetLoggedAllStmt *n = + makeNode(AlterTableSetLoggedAllStmt); + n->tablespacename = $6; + n->objtype = OBJECT_TABLE; + n->logged = true; + n->nowait = $9; + $$ = (Node *)n; + } + | ALTER TABLE ALL IN_P TABLESPACE name SET UNLOGGED opt_nowait + { + AlterTableSetLoggedAllStmt *n = + makeNode(AlterTableSetLoggedAllStmt); + n->tablespacename = $6; + n->objtype = OBJECT_TABLE; + n->logged = false; + n->nowait = $9; + $$ = (Node *)n; + } | ALTER INDEX qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 53a511f1da..16606448bf 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -161,6 +161,7 @@ ClassifyUtilityCommandAsReadOnly(Node *parsetree) case T_AlterTSConfigurationStmt: case T_AlterTSDictionaryStmt: case T_AlterTableMoveAllStmt: + case T_AlterTableSetLoggedAllStmt: case T_AlterTableSpaceOptionsStmt: case T_AlterTableStmt: case T_AlterTypeStmt: @@ -1732,6 +1733,12 @@ ProcessUtilitySlow(ParseState *pstate, commandCollected = true; break; + case T_AlterTableSetLoggedAllStmt: + AlterTableSetLoggedAll((AlterTableSetLoggedAllStmt *) parsetree); + /* commands are stashed in AlterTableSetLoggedAll */ + commandCollected = true; + break; + case T_DropStmt: ExecDropStmt((DropStmt *) parsetree, isTopLevel); /* no commands stashed for DROP */ @@ -2619,6 +2626,10 @@ CreateCommandTag(Node *parsetree) tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype); break; + case T_AlterTableSetLoggedAllStmt: + tag = AlterObjectTypeCommandTag(((AlterTableSetLoggedAllStmt *) parsetree)->objtype); + break; + case T_AlterTableStmt: tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->objtype); break; diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index 08c463d3c4..646928466d 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -42,6 +42,8 @@ extern void AlterTableInternal(Oid relid, List *cmds, bool recurse); extern Oid AlterTableMoveAll(AlterTableMoveAllStmt *stmt); +extern void AlterTableSetLoggedAll(AlterTableSetLoggedAllStmt *stmt); + extern ObjectAddress AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index caed683ba9..16d91d3e1d 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -424,6 +424,7 @@ typedef enum NodeTag T_AlterCollationStmt, T_CallStmt, T_AlterStatsStmt, + T_AlterTableSetLoggedAllStmt, /* * TAGS FOR PARSE TREE NODES (parsenodes.h) diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index dc2bb40926..c3eab6f1ab 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2253,6 +2253,15 @@ typedef struct AlterTableMoveAllStmt bool nowait; } AlterTableMoveAllStmt; +typedef struct AlterTableSetLoggedAllStmt +{ + NodeTag type; + char *tablespacename; + ObjectType objtype; /* Object type to move */ + bool logged; + bool nowait; +} AlterTableSetLoggedAllStmt; + /* ---------------------- * Create/Alter Extension Statements * ---------------------- -- 2.27.0 ----Next_Part(Tue_Jan_12_18_58_08_2021_481)---- ^ permalink raw reply [nested|flat] 2+ messages in thread
* [PATCH] pg_dump: Do not dump statistics for excluded tables @ 2023-12-27 04:44 Rian McGuire <[email protected]> 0 siblings, 0 replies; 2+ messages in thread From: Rian McGuire @ 2023-12-27 04:44 UTC (permalink / raw) To: [email protected] Hi hackers, I've attached a patch against master that addresses a small bug in pg_dump. Previously, pg_dump would include CREATE STATISTICS statements for tables that were excluded from the dump, causing reload to fail if any excluded tables had extended statistics. The patch skips the creation of the StatsExtInfo if the associated table does not have the DUMP_COMPONENT_DEFINITION flag set. This is similar to how getPublicationTables behaves if a table is excluded. I've covered this with a regression test by altering one of the CREATE STATISTICS examples to work with the existing 'exclude_test_table' run. Without the fix, that causes the test to fail with: # Failed test 'exclude_test_table: should not dump CREATE STATISTICS extended_stats_no_options' # at t/002_pg_dump.pl line 4934. Regards, Rian From 0fe06338728981fa727e3e6b99247741deda75fb Mon Sep 17 00:00:00 2001 From: Rian McGuire <[email protected]> Date: Wed, 27 Dec 2023 13:09:31 +1100 Subject: [PATCH] pg_dump: Do not dump statistics for excluded tables Previously, pg_dump would include CREATE STATISTICS statements for tables that were excluded from the dump, causing reload to fail. --- src/bin/pg_dump/pg_dump.c | 43 +++++++++++++++++++++++--------- src/bin/pg_dump/t/002_pg_dump.pl | 5 ++-- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 8c0b5486b9..c67ed416e9 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -7288,11 +7288,13 @@ getExtendedStatistics(Archive *fout) int ntups; int i_tableoid; int i_oid; + int i_stxrelid; int i_stxname; int i_stxnamespace; int i_stxowner; int i_stattarget; - int i; + int i, + j; /* Extended statistics were new in v10 */ if (fout->remoteVersion < 100000) @@ -7301,11 +7303,11 @@ getExtendedStatistics(Archive *fout) query = createPQExpBuffer(); if (fout->remoteVersion < 130000) - appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, " + appendPQExpBufferStr(query, "SELECT tableoid, oid, stxrelid, stxname, " "stxnamespace, stxowner, (-1) AS stxstattarget " "FROM pg_catalog.pg_statistic_ext"); else - appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, " + appendPQExpBufferStr(query, "SELECT tableoid, oid, stxrelid, stxname, " "stxnamespace, stxowner, stxstattarget " "FROM pg_catalog.pg_statistic_ext"); @@ -7315,27 +7317,44 @@ getExtendedStatistics(Archive *fout) i_tableoid = PQfnumber(res, "tableoid"); i_oid = PQfnumber(res, "oid"); + i_stxrelid = PQfnumber(res, "stxrelid"); i_stxname = PQfnumber(res, "stxname"); i_stxnamespace = PQfnumber(res, "stxnamespace"); i_stxowner = PQfnumber(res, "stxowner"); i_stattarget = PQfnumber(res, "stxstattarget"); + /* this allocation may be more than we need */ statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo)); + j = 0; for (i = 0; i < ntups; i++) { - statsextinfo[i].dobj.objType = DO_STATSEXT; - statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid)); - statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid)); - AssignDumpId(&statsextinfo[i].dobj); - statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname)); - statsextinfo[i].dobj.namespace = + Oid stxrelid; + TableInfo *tbinfo; + + /* + * Only dump extended statistics if we're going to dump the definition + * of the table that they're associated with. + */ + stxrelid = atoi(PQgetvalue(res, i, i_stxrelid)); + tbinfo = findTableByOid(stxrelid); + if (tbinfo == NULL || !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)) + continue; + + statsextinfo[j].dobj.objType = DO_STATSEXT; + statsextinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid)); + statsextinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid)); + AssignDumpId(&statsextinfo[j].dobj); + statsextinfo[j].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname)); + statsextinfo[j].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace))); - statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner)); - statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget)); + statsextinfo[j].rolname = getRoleName(PQgetvalue(res, i, i_stxowner)); + statsextinfo[j].stattarget = atoi(PQgetvalue(res, i, i_stattarget)); /* Decide whether we want to dump it */ - selectDumpableObject(&(statsextinfo[i].dobj), fout); + selectDumpableObject(&(statsextinfo[j].dobj), fout); + + j++; } PQclear(res); diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index eb3ec534b4..a671603cd2 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -3742,14 +3742,15 @@ my %tests = ( 'CREATE STATISTICS extended_stats_no_options' => { create_order => 97, create_sql => 'CREATE STATISTICS dump_test.test_ext_stats_no_options - ON col1, col2 FROM dump_test.test_fifth_table', + ON col1, col2 FROM dump_test.test_table', regexp => qr/^ - \QCREATE STATISTICS dump_test.test_ext_stats_no_options ON col1, col2 FROM dump_test.test_fifth_table;\E + \QCREATE STATISTICS dump_test.test_ext_stats_no_options ON col1, col2 FROM dump_test.test_table;\E /xms, like => { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, unlike => { exclude_dump_test_schema => 1, + exclude_test_table => 1, only_dump_measurement => 1, }, }, -- 2.43.0 Attachments: [text/plain] v1-0001-pg_dump-Do-not-dump-statistics-for-excluded-tables.patch (4.6K, ../../[email protected]/2-v1-0001-pg_dump-Do-not-dump-statistics-for-excluded-tables.patch) download | inline diff: From 0fe06338728981fa727e3e6b99247741deda75fb Mon Sep 17 00:00:00 2001 From: Rian McGuire <[email protected]> Date: Wed, 27 Dec 2023 13:09:31 +1100 Subject: [PATCH] pg_dump: Do not dump statistics for excluded tables Previously, pg_dump would include CREATE STATISTICS statements for tables that were excluded from the dump, causing reload to fail. --- src/bin/pg_dump/pg_dump.c | 43 +++++++++++++++++++++++--------- src/bin/pg_dump/t/002_pg_dump.pl | 5 ++-- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 8c0b5486b9..c67ed416e9 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -7288,11 +7288,13 @@ getExtendedStatistics(Archive *fout) int ntups; int i_tableoid; int i_oid; + int i_stxrelid; int i_stxname; int i_stxnamespace; int i_stxowner; int i_stattarget; - int i; + int i, + j; /* Extended statistics were new in v10 */ if (fout->remoteVersion < 100000) @@ -7301,11 +7303,11 @@ getExtendedStatistics(Archive *fout) query = createPQExpBuffer(); if (fout->remoteVersion < 130000) - appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, " + appendPQExpBufferStr(query, "SELECT tableoid, oid, stxrelid, stxname, " "stxnamespace, stxowner, (-1) AS stxstattarget " "FROM pg_catalog.pg_statistic_ext"); else - appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, " + appendPQExpBufferStr(query, "SELECT tableoid, oid, stxrelid, stxname, " "stxnamespace, stxowner, stxstattarget " "FROM pg_catalog.pg_statistic_ext"); @@ -7315,27 +7317,44 @@ getExtendedStatistics(Archive *fout) i_tableoid = PQfnumber(res, "tableoid"); i_oid = PQfnumber(res, "oid"); + i_stxrelid = PQfnumber(res, "stxrelid"); i_stxname = PQfnumber(res, "stxname"); i_stxnamespace = PQfnumber(res, "stxnamespace"); i_stxowner = PQfnumber(res, "stxowner"); i_stattarget = PQfnumber(res, "stxstattarget"); + /* this allocation may be more than we need */ statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo)); + j = 0; for (i = 0; i < ntups; i++) { - statsextinfo[i].dobj.objType = DO_STATSEXT; - statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid)); - statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid)); - AssignDumpId(&statsextinfo[i].dobj); - statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname)); - statsextinfo[i].dobj.namespace = + Oid stxrelid; + TableInfo *tbinfo; + + /* + * Only dump extended statistics if we're going to dump the definition + * of the table that they're associated with. + */ + stxrelid = atoi(PQgetvalue(res, i, i_stxrelid)); + tbinfo = findTableByOid(stxrelid); + if (tbinfo == NULL || !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)) + continue; + + statsextinfo[j].dobj.objType = DO_STATSEXT; + statsextinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid)); + statsextinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid)); + AssignDumpId(&statsextinfo[j].dobj); + statsextinfo[j].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname)); + statsextinfo[j].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace))); - statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner)); - statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget)); + statsextinfo[j].rolname = getRoleName(PQgetvalue(res, i, i_stxowner)); + statsextinfo[j].stattarget = atoi(PQgetvalue(res, i, i_stattarget)); /* Decide whether we want to dump it */ - selectDumpableObject(&(statsextinfo[i].dobj), fout); + selectDumpableObject(&(statsextinfo[j].dobj), fout); + + j++; } PQclear(res); diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index eb3ec534b4..a671603cd2 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -3742,14 +3742,15 @@ my %tests = ( 'CREATE STATISTICS extended_stats_no_options' => { create_order => 97, create_sql => 'CREATE STATISTICS dump_test.test_ext_stats_no_options - ON col1, col2 FROM dump_test.test_fifth_table', + ON col1, col2 FROM dump_test.test_table', regexp => qr/^ - \QCREATE STATISTICS dump_test.test_ext_stats_no_options ON col1, col2 FROM dump_test.test_fifth_table;\E + \QCREATE STATISTICS dump_test.test_ext_stats_no_options ON col1, col2 FROM dump_test.test_table;\E /xms, like => { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, unlike => { exclude_dump_test_schema => 1, + exclude_test_table => 1, only_dump_measurement => 1, }, }, -- 2.43.0 ^ permalink raw reply [nested|flat] 2+ messages in thread
end of thread, other threads:[~2023-12-27 04:44 UTC | newest] Thread overview: 2+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2020-11-11 14:21 [PATCH v4 2/2] New command ALTER TABLE ALL IN TABLESPACE SET LOGGED/UNLOGGED Kyotaro Horiguchi <[email protected]> 2023-12-27 04:44 [PATCH] pg_dump: Do not dump statistics for excluded tables Rian McGuire <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox