Hello, hackers!
When using manually created partitioned tables for pgbench, an error
occurred:
ERROR: cannot perform COPY FREEZE on a partitioned table.
Currently only pgbench_accounts can be partitioned, all others must be a
regular tables.
I wrote a patch to disable WITH (FREEZE = ON) when generating data for
non-regular tables.
See attached patch
--
With best regards,
Sergey Tatarintsev
From 9aaf2b222d6eb0c218c8a417280a8fdc0a42c296 Mon Sep 17 00:00:00 2001
From: Sergey Tatarintsev <s.tatarint...@postgrespro.ru>
Date: Thu, 30 Jan 2025 14:52:29 +0700
Subject: [PATCH-v1] Fix pgbench client-side data generation for partitioned tables
Client-side data generation cannot perform COPY WITH (FREEZE = ON) on partitioned
tables except pgbench_accounts.
Patch disables FREEZE for any non-regular tables
---
src/bin/pgbench/pgbench.c | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index b5cf3c6ed01..cac5312c4b1 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -847,6 +847,28 @@ static const PsqlScanCallbacks pgbench_callbacks = {
NULL, /* don't need get_variable functionality */
};
+static bool
+is_regular_table(PGconn *con, const char *table)
+{
+ PGresult *res;
+ char *sql = psprintf("SELECT relkind FROM pg_class WHERE oid='%s'::regclass::oid", table);
+ bool is_regular_table = true;
+
+ res = PQexec(con, sql);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ pg_log_error("query failed: %s", PQerrorMessage(con));
+ pg_log_error_detail("Query was: %s", sql);
+ exit(1);
+ }
+ if (!PQgetisnull(res, 0, 0))
+ is_regular_table = strncmp(PQgetvalue(res, 0, 0), "r", 1) == 0;
+
+ PQclear(res);
+ pfree(sql);
+ return is_regular_table;
+}
+
static inline pg_time_usec_t
pg_time_now(void)
{
@@ -4958,16 +4980,10 @@ initPopulateTable(PGconn *con, const char *table, int64 base,
initPQExpBuffer(&sql);
- /*
- * Use COPY with FREEZE on v14 and later for all the tables except
- * pgbench_accounts when it is partitioned.
- */
- if (PQserverVersion(con) >= 140000)
- {
- if (strcmp(table, "pgbench_accounts") != 0 ||
- partitions == 0)
+ /* Use COPY with FREEZE on v14 and later for all regular tables */
+ if ((PQserverVersion(con) >= 140000) && is_regular_table(con, table))
copy_statement_fmt = "copy %s from stdin with (freeze on)";
- }
+
n = pg_snprintf(copy_statement, sizeof(copy_statement), copy_statement_fmt, table);
if (n >= sizeof(copy_statement))
--
2.43.0