@@ -83,7 +83,7 @@ typedef struct repack_index
83
83
} repack_index ;
84
84
85
85
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 );
87
87
static void repack_one_table (const repack_table * table , const char * order_by );
88
88
static void repack_cleanup (bool fatal , void * userdata );
89
89
@@ -152,10 +152,11 @@ main(int argc, char *argv[])
152
152
}
153
153
else
154
154
{
155
- if (!repack_one_database (orderby , table ))
155
+ char errbuf [256 ];
156
+ if (!repack_one_database (orderby , table , errbuf , sizeof (errbuf )))
156
157
ereport (ERROR ,
157
- (errcode (ENOENT ),
158
- errmsg ("%s is not installed " , PROGRAM_NAME )));
158
+ (errcode (ERROR ),
159
+ errmsg ("%s" , errbuf )));
159
160
}
160
161
161
162
return 0 ;
@@ -178,6 +179,7 @@ repack_all_databases(const char *orderby)
178
179
for (i = 0 ; i < PQntuples (result ); i ++ )
179
180
{
180
181
bool ret ;
182
+ char errbuf [256 ];
181
183
182
184
dbname = PQgetvalue (result , i , 0 );
183
185
@@ -187,14 +189,14 @@ repack_all_databases(const char *orderby)
187
189
fflush (stdout );
188
190
}
189
191
190
- ret = repack_one_database (orderby , NULL );
192
+ ret = repack_one_database (orderby , NULL , errbuf , sizeof ( errbuf ) );
191
193
192
194
if (pgut_log_level >= INFO )
193
195
{
194
196
if (ret )
195
197
printf ("\n" );
196
198
else
197
- printf (" ... skipped\n" );
199
+ printf (" ... skipped: %s \n" , errbuf );
198
200
fflush (stdout );
199
201
}
200
202
}
@@ -225,9 +227,9 @@ getoid(PGresult *res, int row, int col)
225
227
* Call repack_one_table for the target table or each table in a database.
226
228
*/
227
229
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 )
229
231
{
230
- bool ret = true ;
232
+ bool ret = false ;
231
233
PGresult * res ;
232
234
int i ;
233
235
int num ;
@@ -237,6 +239,57 @@ repack_one_database(const char *orderby, const char *table)
237
239
238
240
reconnect (ERROR );
239
241
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
+
240
293
/* Disable statement timeout. */
241
294
command ("SET statement_timeout = 0" , 0 , NULL );
242
295
@@ -261,21 +314,24 @@ repack_one_database(const char *orderby, const char *table)
261
314
res = execute_elevel (sql .data , 0 , NULL , DEBUG2 );
262
315
}
263
316
317
+ /* on error skip the database */
264
318
if (PQresultStatus (res ) != PGRES_TUPLES_OK )
265
319
{
266
320
if (sqlstate_equals (res , SQLSTATE_INVALID_SCHEMA_NAME ))
267
321
{
268
322
/* 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 );
271
326
}
272
327
else
273
328
{
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 ));
278
332
}
333
+ ret = false;
334
+ goto cleanup ;
279
335
}
280
336
281
337
num = PQntuples (res );
@@ -341,6 +397,7 @@ repack_one_database(const char *orderby, const char *table)
341
397
342
398
repack_one_table (& table , orderby );
343
399
}
400
+ ret = true;
344
401
345
402
cleanup :
346
403
PQclear (res );
0 commit comments