Allow multiple --table options to be specified on the command-line.
Per Issue #18. SimpleStringList code borrowed from pg_dump and a pending patch to add similar functionality to pg_restore, clusterdb, vacuumdb, and reindexdb. The error handling in reorg_one_table() could still be much improved, so that an error processing a single table doesn't cause pg_reorg to necessarily bail out and skip further tables, but I'll leave that for another day.
This commit is contained in:
parent
ad00eb181d
commit
ad75dcfbb1
@ -128,7 +128,7 @@ static bool sqlstate_equals(PGresult *res, const char *state)
|
|||||||
static bool analyze = true;
|
static bool analyze = true;
|
||||||
static bool alldb = false;
|
static bool alldb = false;
|
||||||
static bool noorder = false;
|
static bool noorder = false;
|
||||||
static char *table = NULL;
|
static SimpleStringList table_list = {NULL, NULL};
|
||||||
static char *orderby = NULL;
|
static char *orderby = NULL;
|
||||||
static int wait_timeout = 60; /* in seconds */
|
static int wait_timeout = 60; /* in seconds */
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ utoa(unsigned int value, char *buffer)
|
|||||||
static pgut_option options[] =
|
static pgut_option options[] =
|
||||||
{
|
{
|
||||||
{ 'b', 'a', "all", &alldb },
|
{ 'b', 'a', "all", &alldb },
|
||||||
{ 's', 't', "table", &table },
|
{ 'l', 't', "table", &table_list },
|
||||||
{ 'b', 'n', "no-order", &noorder },
|
{ 'b', 'n', "no-order", &noorder },
|
||||||
{ 's', 'o', "order-by", &orderby },
|
{ 's', 'o', "order-by", &orderby },
|
||||||
{ 'i', 'T', "wait-timeout", &wait_timeout },
|
{ 'i', 'T', "wait-timeout", &wait_timeout },
|
||||||
@ -155,6 +155,7 @@ int
|
|||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
SimpleStringListCell *cell;
|
||||||
|
|
||||||
i = pgut_getopt(argc, argv, options);
|
i = pgut_getopt(argc, argv, options);
|
||||||
|
|
||||||
@ -170,7 +171,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (alldb)
|
if (alldb)
|
||||||
{
|
{
|
||||||
if (table)
|
if (table_list.head != NULL)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(EINVAL),
|
(errcode(EINVAL),
|
||||||
errmsg("cannot repack a specific table in all databases")));
|
errmsg("cannot repack a specific table in all databases")));
|
||||||
@ -178,7 +179,14 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!repack_one_database(orderby, table))
|
if (table_list.head != NULL)
|
||||||
|
{
|
||||||
|
for (cell = table_list.head; cell; cell = cell->next)
|
||||||
|
{
|
||||||
|
repack_one_database(orderby, cell->val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!repack_one_database(orderby, NULL))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ENOENT),
|
(errcode(ENOENT),
|
||||||
errmsg("%s is not installed", PROGRAM_NAME)));
|
errmsg("%s is not installed", PROGRAM_NAME)));
|
||||||
|
@ -144,9 +144,12 @@ pgut_setopt(pgut_option *opt, const char *optarg, pgut_optsrc src)
|
|||||||
/* high prior value has been set already. */
|
/* high prior value has been set already. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (src >= SOURCE_CMDLINE && opt->source >= src)
|
else if (src >= SOURCE_CMDLINE && opt->source >= src && opt->type != 'l')
|
||||||
{
|
{
|
||||||
/* duplicated option in command line */
|
/* duplicated option in command line -- don't worry if the option
|
||||||
|
* type is 'l' i.e. SimpleStringList, since we are allowed to have
|
||||||
|
* multiples of these.
|
||||||
|
*/
|
||||||
message = "specified only once";
|
message = "specified only once";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -177,6 +180,10 @@ pgut_setopt(pgut_option *opt, const char *optarg, pgut_optsrc src)
|
|||||||
return;
|
return;
|
||||||
message = "a 32bit signed integer";
|
message = "a 32bit signed integer";
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
message = "a List";
|
||||||
|
simple_string_list_append(opt->var, optarg);
|
||||||
|
return;
|
||||||
case 'u':
|
case 'u':
|
||||||
if (parse_uint32(optarg, opt->var))
|
if (parse_uint32(optarg, opt->var))
|
||||||
return;
|
return;
|
||||||
|
@ -27,6 +27,7 @@ typedef enum pgut_optsrc
|
|||||||
* B: bool (false)
|
* B: bool (false)
|
||||||
* f: pgut_optfn
|
* f: pgut_optfn
|
||||||
* i: 32bit signed integer
|
* i: 32bit signed integer
|
||||||
|
* l: StringList
|
||||||
* u: 32bit unsigned integer
|
* u: 32bit unsigned integer
|
||||||
* I: 64bit signed integer
|
* I: 64bit signed integer
|
||||||
* U: 64bit unsigned integer
|
* U: 64bit unsigned integer
|
||||||
|
@ -384,6 +384,40 @@ parse_time(const char *value, time_t *time)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Append the given string `val` to the `list` */
|
||||||
|
void
|
||||||
|
simple_string_list_append(SimpleStringList *list, const char *val)
|
||||||
|
{
|
||||||
|
SimpleStringListCell *cell;
|
||||||
|
|
||||||
|
/* this calculation correctly accounts for the null trailing byte */
|
||||||
|
cell = (SimpleStringListCell *)
|
||||||
|
pgut_malloc(sizeof(SimpleStringListCell) + strlen(val));
|
||||||
|
cell->next = NULL;
|
||||||
|
strcpy(cell->val, val);
|
||||||
|
|
||||||
|
if (list->tail)
|
||||||
|
list->tail->next = cell;
|
||||||
|
else
|
||||||
|
list->head = cell;
|
||||||
|
list->tail = cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test whether `val` is in the given `list` */
|
||||||
|
bool
|
||||||
|
simple_string_list_member(SimpleStringList *list, const char *val)
|
||||||
|
{
|
||||||
|
SimpleStringListCell *cell;
|
||||||
|
|
||||||
|
for (cell = list->head; cell; cell = cell->next)
|
||||||
|
{
|
||||||
|
if (strcmp(cell->val, val) == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
prompt_for_password(void)
|
prompt_for_password(void)
|
||||||
{
|
{
|
||||||
|
@ -171,6 +171,23 @@ extern bool parse_time(const char *value, time_t *time);
|
|||||||
#define ToLower(c) (tolower((unsigned char)(c)))
|
#define ToLower(c) (tolower((unsigned char)(c)))
|
||||||
#define ToUpper(c) (toupper((unsigned char)(c)))
|
#define ToUpper(c) (toupper((unsigned char)(c)))
|
||||||
|
|
||||||
|
/* linked list of string values and helper functions, stolen from pg_dump. */
|
||||||
|
typedef struct SimpleStringListCell
|
||||||
|
{
|
||||||
|
struct SimpleStringListCell *next;
|
||||||
|
char val[1]; /* VARIABLE LENGTH FIELD */
|
||||||
|
} SimpleStringListCell;
|
||||||
|
|
||||||
|
typedef struct SimpleStringList
|
||||||
|
{
|
||||||
|
SimpleStringListCell *head;
|
||||||
|
SimpleStringListCell *tail;
|
||||||
|
} SimpleStringList;
|
||||||
|
|
||||||
|
extern void simple_string_list_append(SimpleStringList *list, const char *val);
|
||||||
|
extern bool simple_string_list_member(SimpleStringList *list, const char *val);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* socket operations
|
* socket operations
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user