version 1.0.5.
- Disable autovacuum for working tables and update logs. - Do ANALYZE automatically after reorg unless -Z, --no-analyze option is specified.
This commit is contained in:
		
							
								
								
									
										114
									
								
								bin/pgut/pgut.c
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								bin/pgut/pgut.c
									
									
									
									
									
								
							| @ -21,13 +21,14 @@ const char *host = NULL; | ||||
| const char *port = NULL; | ||||
| const char *username = NULL; | ||||
| bool		password = false; | ||||
| bool		debug = false; | ||||
|  | ||||
| /* Database connections */ | ||||
| PGconn	   *connection = NULL; | ||||
| static PGcancel *volatile cancel_conn = NULL; | ||||
|  | ||||
| /* Interrupted by SIGINT (Ctrl+C) ? */ | ||||
| static bool		interrupted = false; | ||||
| bool		interrupted = false; | ||||
|  | ||||
| /* Connection routines */ | ||||
| static void init_cancel_handler(void); | ||||
| @ -39,40 +40,19 @@ static void exit_or_abort(int exitcode); | ||||
| static void help(void); | ||||
| static const char *get_user_name(const char *PROGRAM_NAME); | ||||
|  | ||||
| const char default_optstring[] = "d:h:p:U:W"; | ||||
|  | ||||
| const struct option default_longopts[] = | ||||
| const struct option default_options[] = | ||||
| { | ||||
| 	{"dbname", required_argument, NULL, 'd'}, | ||||
| 	{"host", required_argument, NULL, 'h'}, | ||||
| 	{"port", required_argument, NULL, 'p'}, | ||||
| 	{"username", required_argument, NULL, 'U'}, | ||||
| 	{"password", no_argument, NULL, 'W'}, | ||||
| 	{"debug", no_argument, NULL, '!'}, | ||||
| 	{NULL, 0, NULL, 0} | ||||
| }; | ||||
|  | ||||
| static const char			   *optstring = NULL; | ||||
| static const struct option	   *longopts = NULL;; | ||||
|  | ||||
| static const char * | ||||
| merge_optstring(const char *opts) | ||||
| { | ||||
| 	size_t	len; | ||||
| 	char   *result; | ||||
|  | ||||
| 	if (opts == NULL) | ||||
| 		return default_optstring; | ||||
|  | ||||
| 	len = strlen(opts); | ||||
| 	if (len == 0) | ||||
| 		return default_optstring; | ||||
|  | ||||
| 	result = malloc(len + lengthof(default_optstring)); | ||||
| 	memcpy(&result[0], opts, len); | ||||
| 	memcpy(&result[len], default_optstring, lengthof(default_optstring)); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| static const struct option * | ||||
| merge_longopts(const struct option *opts) | ||||
| { | ||||
| @ -80,23 +60,46 @@ merge_longopts(const struct option *opts) | ||||
| 	struct option *result; | ||||
|  | ||||
| 	if (opts == NULL) | ||||
| 		return default_longopts; | ||||
| 		return default_options; | ||||
|  | ||||
| 	for (len = 0; opts[len].name; len++) { } | ||||
| 	if (len == 0) | ||||
| 		return default_longopts; | ||||
| 		return default_options; | ||||
|  | ||||
| 	result = (struct option *) malloc((len + lengthof(default_longopts)) * sizeof(struct option)); | ||||
| 	result = (struct option *) malloc((len + lengthof(default_options)) * sizeof(struct option)); | ||||
| 	memcpy(&result[0], opts, len * sizeof(struct option)); | ||||
| 	memcpy(&result[len], default_longopts, lengthof(default_longopts) * sizeof(struct option)); | ||||
| 	memcpy(&result[len], default_options, lengthof(default_options) * sizeof(struct option)); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| static const char * | ||||
| longopts_to_optstring(const struct option *opts) | ||||
| { | ||||
| 	size_t	len; | ||||
| 	char   *result; | ||||
| 	char   *s; | ||||
|  | ||||
| 	for (len = 0; opts[len].name; len++) { } | ||||
| 	result = malloc(len * 2 + 1); | ||||
|  | ||||
| 	s = result; | ||||
| 	for (len = 0; opts[len].name; len++) | ||||
| 	{ | ||||
| 		*s++ = opts[len].val; | ||||
| 		if (opts[len].has_arg == required_argument) | ||||
| 			*s++ = ':'; | ||||
| 	} | ||||
| 	*s = '\0'; | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| void | ||||
| parse_options(int argc, char **argv) | ||||
| { | ||||
| 	int		c; | ||||
| 	int		optindex = 0; | ||||
| 	int			c; | ||||
| 	int			optindex = 0; | ||||
| 	const char *optstring; | ||||
|  | ||||
| 	PROGRAM_NAME = get_progname(argv[0]); | ||||
| 	set_pglocale_pgservice(argv[0], "pgscripts"); | ||||
| @ -117,8 +120,8 @@ parse_options(int argc, char **argv) | ||||
| 	} | ||||
|  | ||||
| 	/* Merge default and user options. */ | ||||
| 	optstring = merge_optstring(pgut_optstring); | ||||
| 	longopts = merge_longopts(pgut_longopts); | ||||
| 	longopts = merge_longopts(pgut_options); | ||||
| 	optstring = longopts_to_optstring(longopts); | ||||
|  | ||||
| 	while ((c = getopt_long(argc, argv, optstring, longopts, &optindex)) != -1) | ||||
| 	{ | ||||
| @ -139,6 +142,9 @@ parse_options(int argc, char **argv) | ||||
| 		case 'W': | ||||
| 			password = true; | ||||
| 			break; | ||||
| 		case '!': | ||||
| 			debug = true; | ||||
| 			break; | ||||
| 		default: | ||||
| 			if (!pgut_argument(c, optarg)) | ||||
| 			{ | ||||
| @ -250,7 +256,7 @@ disconnect(void) | ||||
| } | ||||
|  | ||||
| PGresult * | ||||
| execute_nothrow(const char *query, int nParams, const char **params) | ||||
| execute_elevel(const char *query, int nParams, const char **params, int elevel) | ||||
| { | ||||
| 	PGresult   *res; | ||||
|  | ||||
| @ -260,6 +266,19 @@ execute_nothrow(const char *query, int nParams, const char **params) | ||||
| 		elog(ERROR, "%s: interrupted", PROGRAM_NAME); | ||||
| 	} | ||||
|  | ||||
| 	/* write query to elog if debug */ | ||||
| 	if (debug) | ||||
| 	{ | ||||
| 		int		i; | ||||
|  | ||||
| 		if (strchr(query, '\n')) | ||||
| 			elog(LOG, "(query)\n%s", query); | ||||
| 		else | ||||
| 			elog(LOG, "(query) %s", query); | ||||
| 		for (i = 0; i < nParams; i++) | ||||
| 			elog(LOG, "\t(param:%d) = %s", i, params[i] ? params[i] : "(null)"); | ||||
| 	} | ||||
|  | ||||
| 	on_before_exec(connection); | ||||
| 	if (nParams == 0) | ||||
| 		res = PQexec(connection, query); | ||||
| @ -267,6 +286,17 @@ execute_nothrow(const char *query, int nParams, const char **params) | ||||
| 		res = PQexecParams(connection, query, nParams, NULL, params, NULL, NULL, 0); | ||||
| 	on_after_exec(); | ||||
|  | ||||
| 	switch (PQresultStatus(res)) | ||||
| 	{ | ||||
| 		case PGRES_TUPLES_OK: | ||||
| 		case PGRES_COMMAND_OK: | ||||
| 			break; | ||||
| 		default: | ||||
| 			elog(elevel, "query failed: %squery was: %s", | ||||
| 				PQerrorMessage(connection), query); | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| @ -276,17 +306,7 @@ execute_nothrow(const char *query, int nParams, const char **params) | ||||
| PGresult * | ||||
| execute(const char *query, int nParams, const char **params) | ||||
| { | ||||
| 	PGresult   *res = execute_nothrow(query, nParams, params); | ||||
|  | ||||
| 	if (PQresultStatus(res) == PGRES_TUPLES_OK || | ||||
| 		PQresultStatus(res) == PGRES_COMMAND_OK) | ||||
| 		return res; | ||||
|  | ||||
| 	fprintf(stderr, "%s: query failed: %s", PROGRAM_NAME, PQerrorMessage(connection)); | ||||
| 	fprintf(stderr, "%s: query was: %s\n", PROGRAM_NAME, query); | ||||
| 	PQclear(res); | ||||
| 	exit_or_abort(ERROR); | ||||
| 	return NULL;	/* keep compiler quiet */ | ||||
| 	return execute_elevel(query, nParams, params, ERROR); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @ -307,6 +327,9 @@ elog(int elevel, const char *fmt, ...) | ||||
| { | ||||
| 	va_list		args; | ||||
|  | ||||
| 	if (!debug && elevel <= LOG) | ||||
| 		return; | ||||
|  | ||||
| 	switch (elevel) | ||||
| 	{ | ||||
| 	case LOG: | ||||
| @ -457,7 +480,8 @@ static void help(void) | ||||
| 	fprintf(stderr, "  -p, --port=PORT           database server port\n"); | ||||
| 	fprintf(stderr, "  -U, --username=USERNAME   user name to connect as\n"); | ||||
| 	fprintf(stderr, "  -W, --password            force password prompt\n"); | ||||
| 	fprintf(stderr, "\nGeneric Options:\n"); | ||||
| 	fprintf(stderr, "\nGeneric options:\n"); | ||||
| 	fprintf(stderr, "  --debug                   debug mode\n"); | ||||
| 	fprintf(stderr, "  --help                    show this help, then exit\n"); | ||||
| 	fprintf(stderr, "  --version                 output version information, then exit\n\n"); | ||||
| 	if (PROGRAM_URL) | ||||
|  | ||||
| @ -30,8 +30,7 @@ typedef char bool; | ||||
| /* | ||||
|  * pgut client variables and functions | ||||
|  */ | ||||
| extern const char		   *pgut_optstring; | ||||
| extern const struct option	pgut_longopts[]; | ||||
| extern const struct option	pgut_options[]; | ||||
|  | ||||
| extern bool	pgut_argument(int c, const char *arg); | ||||
| extern void	pgut_help(void); | ||||
| @ -51,15 +50,17 @@ extern const char  *host; | ||||
| extern const char  *port; | ||||
| extern const char  *username; | ||||
| extern bool			password; | ||||
| extern bool			debug; | ||||
|  | ||||
| extern PGconn	   *connection; | ||||
| extern bool			interrupted; | ||||
|  | ||||
| extern void	parse_options(int argc, char **argv); | ||||
| extern bool	assign_option(const char **value, int c, const char *arg); | ||||
|  | ||||
| extern void reconnect(void); | ||||
| extern void disconnect(void); | ||||
| extern PGresult *execute_nothrow(const char *query, int nParams, const char **params); | ||||
| extern PGresult *execute_elevel(const char *query, int nParams, const char **params, int elevel); | ||||
| extern PGresult *execute(const char *query, int nParams, const char **params); | ||||
| extern void command(const char *query, int nParams, const char **params); | ||||
|  | ||||
| @ -87,6 +88,8 @@ __attribute__((format(printf, 2, 3))); | ||||
| /* | ||||
|  * StringInfo | ||||
|  */ | ||||
| #define STRINGINFO_H | ||||
|  | ||||
| #define StringInfoData			PQExpBufferData | ||||
| #define StringInfo				PQExpBuffer | ||||
| #define makeStringInfo			createPQExpBuffer | ||||
| @ -95,12 +98,29 @@ __attribute__((format(printf, 2, 3))); | ||||
| #define termStringInfo			termPQExpBuffer | ||||
| #define resetStringInfo			resetPQExpBuffer | ||||
| #define enlargeStringInfo		enlargePQExpBuffer | ||||
| /* | ||||
| #define printfPQExpBuffer		= resetStringInfo + appendStringInfo | ||||
| */ | ||||
| #define printfStringInfo		printfPQExpBuffer	/* reset + append */ | ||||
| #define appendStringInfo		appendPQExpBuffer | ||||
| #define appendStringInfoString	appendPQExpBufferStr | ||||
| #define appendStringInfoChar	appendPQExpBufferChar | ||||
| #define appendBinaryStringInfo	appendBinaryPQExpBuffer | ||||
|  | ||||
| /* | ||||
|  * import from postgres.h and catalog/genbki.h in 8.4 | ||||
|  */ | ||||
| #if PG_VERSION_NUM < 80400 | ||||
|  | ||||
| typedef unsigned long Datum; | ||||
| typedef struct MemoryContextData *MemoryContext; | ||||
|  | ||||
| #define CATALOG(name,oid)	typedef struct CppConcat(FormData_,name) | ||||
| #define BKI_BOOTSTRAP | ||||
| #define BKI_SHARED_RELATION | ||||
| #define BKI_WITHOUT_OIDS | ||||
| #define DATA(x)   extern int no_such_variable | ||||
| #define DESCR(x)  extern int no_such_variable | ||||
| #define SHDESCR(x) extern int no_such_variable | ||||
| typedef int aclitem; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif   /* PGUT_H */ | ||||
|  | ||||
		Reference in New Issue
	
	Block a user