Skip to content

Commit d13f1b1

Browse files
committed
Merge branch 'version_check'
2 parents e028116 + deaae7d commit d13f1b1

File tree

4 files changed

+96
-18
lines changed

4 files changed

+96
-18
lines changed

bin/pg_repack.c

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ typedef struct repack_index
8383
} repack_index;
8484

8585
static void repack_all_databases(const char *order_by);
86-
static bool repack_one_database(const char *order_by, const char *table);
86+
static bool repack_one_database(const char *order_by, const char *table, char *errbuf, size_t errsize);
8787
static void repack_one_table(const repack_table *table, const char *order_by);
8888
static void repack_cleanup(bool fatal, void *userdata);
8989

@@ -152,10 +152,11 @@ main(int argc, char *argv[])
152152
}
153153
else
154154
{
155-
if (!repack_one_database(orderby, table))
155+
char errbuf[256];
156+
if (!repack_one_database(orderby, table, errbuf, sizeof(errbuf)))
156157
ereport(ERROR,
157-
(errcode(ENOENT),
158-
errmsg("%s is not installed", PROGRAM_NAME)));
158+
(errcode(ERROR),
159+
errmsg("%s", errbuf)));
159160
}
160161

161162
return 0;
@@ -178,6 +179,7 @@ repack_all_databases(const char *orderby)
178179
for (i = 0; i < PQntuples(result); i++)
179180
{
180181
bool ret;
182+
char errbuf[256];
181183

182184
dbname = PQgetvalue(result, i, 0);
183185

@@ -187,14 +189,14 @@ repack_all_databases(const char *orderby)
187189
fflush(stdout);
188190
}
189191

190-
ret = repack_one_database(orderby, NULL);
192+
ret = repack_one_database(orderby, NULL, errbuf, sizeof(errbuf));
191193

192194
if (pgut_log_level >= INFO)
193195
{
194196
if (ret)
195197
printf("\n");
196198
else
197-
printf(" ... skipped\n");
199+
printf(" ... skipped: %s\n", errbuf);
198200
fflush(stdout);
199201
}
200202
}
@@ -225,9 +227,9 @@ getoid(PGresult *res, int row, int col)
225227
* Call repack_one_table for the target table or each table in a database.
226228
*/
227229
static bool
228-
repack_one_database(const char *orderby, const char *table)
230+
repack_one_database(const char *orderby, const char *table, char *errbuf, size_t errsize)
229231
{
230-
bool ret = true;
232+
bool ret = false;
231233
PGresult *res;
232234
int i;
233235
int num;
@@ -237,6 +239,57 @@ repack_one_database(const char *orderby, const char *table)
237239

238240
reconnect(ERROR);
239241

242+
/* Query the extension version. Exit if no match */
243+
res = execute_elevel("select repack.version(), repack.version_sql()",
244+
0, NULL, DEBUG2);
245+
if (PQresultStatus(res) == PGRES_TUPLES_OK)
246+
{
247+
const char *libver;
248+
char buf[64];
249+
250+
/* the string is something like "pg_repack 1.1.7" */
251+
snprintf(buf, sizeof(buf), "%s %s", PROGRAM_NAME, PROGRAM_VERSION);
252+
253+
/* check the version of the C library */
254+
libver = getstr(res, 0, 0);
255+
if (0 != strcmp(buf, libver))
256+
{
257+
if (errbuf)
258+
snprintf(errbuf, errsize,
259+
"program '%s' does not match database library '%s'",
260+
buf, libver);
261+
goto cleanup;
262+
}
263+
264+
/* check the version of the SQL extension */
265+
libver = getstr(res, 0, 1);
266+
if (0 != strcmp(buf, libver))
267+
{
268+
if (errbuf)
269+
snprintf(errbuf, errsize,
270+
"extension '%s' required, found extension '%s'",
271+
buf, libver);
272+
goto cleanup;
273+
}
274+
}
275+
else
276+
{
277+
if (sqlstate_equals(res, SQLSTATE_INVALID_SCHEMA_NAME))
278+
{
279+
/* Schema repack does not exist. Skip the database. */
280+
if (errbuf)
281+
snprintf(errbuf, errsize,
282+
"%s is not installed in the database", PROGRAM_NAME);
283+
}
284+
else
285+
{
286+
/* Return the error message otherwise */
287+
if (errbuf)
288+
snprintf(errbuf, errsize, "%s", PQerrorMessage(connection));
289+
}
290+
goto cleanup;
291+
}
292+
240293
/* Disable statement timeout. */
241294
command("SET statement_timeout = 0", 0, NULL);
242295

@@ -261,21 +314,24 @@ repack_one_database(const char *orderby, const char *table)
261314
res = execute_elevel(sql.data, 0, NULL, DEBUG2);
262315
}
263316

317+
/* on error skip the database */
264318
if (PQresultStatus(res) != PGRES_TUPLES_OK)
265319
{
266320
if (sqlstate_equals(res, SQLSTATE_INVALID_SCHEMA_NAME))
267321
{
268322
/* Schema repack does not exist. Skip the database. */
269-
ret = false;
270-
goto cleanup;
323+
if (errbuf)
324+
snprintf(errbuf, errsize,
325+
"%s is not installed in the database", PROGRAM_NAME);
271326
}
272327
else
273328
{
274-
/* exit otherwise */
275-
printf("%s", PQerrorMessage(connection));
276-
PQclear(res);
277-
exit(1);
329+
/* Return the error message otherwise */
330+
if (errbuf)
331+
snprintf(errbuf, errsize, "%s", PQerrorMessage(connection));
278332
}
333+
ret = false;
334+
goto cleanup;
279335
}
280336

281337
num = PQntuples(res);
@@ -341,6 +397,7 @@ repack_one_database(const char *orderby, const char *table)
341397

342398
repack_one_table(&table, orderby);
343399
}
400+
ret = true;
344401

345402
cleanup:
346403
PQclear(res);

doc/pg_repack.rst

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ version load the script ``$SHAREDIR/contrib/uninstall_pg_repack.sql`` into the
270270
database where the error occured and then load
271271
``$SHAREDIR/contrib/pg_repack.sql`` again.
272272

273-
pg_repack: repack database "template1" ... skipped
273+
pg_repack: reorg database "template1" ... skipped: pg_repack is not installed in the database
274274
pg_repack is not installed in the database when ``--all`` option is
275275
specified.
276276

@@ -281,6 +281,22 @@ ERROR: pg_repack is not installed
281281

282282
Do register pg_repack to the database.
283283

284+
ERROR: program 'pg_repack V1' does not match database library 'pg_repack V2'
285+
There is a mismatch between the ``pg_repack`` binary and the database
286+
library (``.so`` or ``.dll``).
287+
288+
The mismatch could be due to the wrong binary in the ``$PATH`` or the
289+
wrong database being addressed. Check the program directory and the
290+
database; if they are what expected you may need to repeat pg_repack
291+
installation.
292+
293+
ERROR: extension 'pg_repack V1' required, found extension 'pg_repack V2'
294+
The SQL extension found in the database does not match the version
295+
required by the pg_repack program.
296+
297+
You should drop the extension from the database and reload it as described
298+
in the installation_ section.
299+
284300
ERROR: relation "table" has no primary key
285301
The target table doesn't have PRIMARY KEY.
286302

lib/Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ DATA_built = pg_repack.sql
3030
DATA = uninstall_pg_repack.sql
3131
endif
3232

33-
USE_PGXS = 1 # use pgxs if not in contrib directory
33+
USE_PGXS = 1
3434
PGXS := $(shell $(PG_CONFIG) --pgxs)
3535
include $(PGXS)
3636

@@ -40,11 +40,12 @@ LIBS := $(filter-out -lxslt, $(LIBS))
4040

4141
pg_repack.sql: pg_repack.sql.in
4242
echo "BEGIN;\n" > $@; \
43-
sed 's,MODULE_PATHNAME,$$libdir/$(MODULE_big),g' $< >> $@; \
43+
sed 's,MODULE_PATHNAME,$$libdir/$(MODULE_big),g' $< \
44+
| sed 's,REPACK_VERSION,$(REPACK_VERSION),g' >> $@; \
4445
echo "\nCOMMIT;" >> $@;
4546

4647
pg_repack--$(REPACK_VERSION).sql: pg_repack.sql.in
47-
cat $< > $@;
48+
sed 's,REPACK_VERSION,$(REPACK_VERSION),g' $< > $@;
4849

4950
pg_repack.control: pg_repack.control.in
5051
sed 's,REPACK_VERSION,$(REPACK_VERSION),g' $< > $@

lib/pg_repack.sql.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ CREATE FUNCTION repack.version() RETURNS text AS
1212
'MODULE_PATHNAME', 'repack_version'
1313
LANGUAGE C IMMUTABLE STRICT;
1414

15+
CREATE FUNCTION repack.version_sql() RETURNS text AS
16+
$$SELECT 'pg_repack REPACK_VERSION'::text$$
17+
LANGUAGE SQL IMMUTABLE STRICT;
18+
1519
CREATE AGGREGATE repack.array_accum (
1620
sfunc = array_append,
1721
basetype = anyelement,

0 commit comments

Comments
 (0)