Index: README.pgbench
===================================================================
RCS file: /projects/cvsroot/pgsql/contrib/pgbench/README.pgbench,v
retrieving revision 1.12
diff -c -r1.12 README.pgbench
*** README.pgbench	4 Oct 2005 13:40:45 -0000	1.12
--- README.pgbench	25 Jan 2006 06:14:17 -0000
***************
*** 86,91 ****
--- 86,95 ----
  	-t number_of_transactions
  		Number of transactions each client runs. default is 10.
  
+ 	-x number_of_runs
+ 		Number of runs performed. default is 1. Computes mean
+ 		and standard deviation at end of series.
+ 
  	-s scaling_factor
  		this should be used with -i (initialize) option.
  		number of tuples generated will be multiple of the
***************
*** 209,214 ****
--- 213,221 ----
  
  o History
  
+ 2006/01/26
+ 	* add -x option. contributed by Thomas F. O'Connell <tfo@sitening.com>.
+ 
  2005/09/29
  	* add -f option. contributed by Tomoaki Sato.
  
Index: pgbench.c
===================================================================
RCS file: /projects/cvsroot/pgsql/contrib/pgbench/pgbench.c,v
retrieving revision 1.49
diff -c -r1.49 pgbench.c
*** pgbench.c	10 Dec 2005 01:09:07 -0000	1.49
--- pgbench.c	25 Jan 2006 06:14:17 -0000
***************
*** 22,27 ****
--- 22,28 ----
  #include "libpq-fe.h"
  
  #include <ctype.h>
+ #include <math.h>
  
  #ifdef WIN32
  #include "win32.h"
***************
*** 53,58 ****
--- 54,60 ----
   * some configurable parameters */
  
  #define MAXCLIENTS 1024			/* max number of clients allowed */
+ #define MAXRUNS 1024		/* max number of runs allowed */
  
  int			nclients = 1;		/* default number of simulated clients */
  int			nxacts = 10;		/* default number of transactions per clients */
***************
*** 62,67 ****
--- 64,70 ----
   * accounts table.
   */
  int			tps = 1;
+ int			nruns = 1;	/* default number of runs */
  
  /*
   * end of configurable parameters
***************
*** 169,175 ****
  static void
  usage(void)
  {
! 	fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-s scaling_factor][-n][-C][-v][-S][-N][-f filename][-l][-U login][-P password][-d][dbname]\n");
  	fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor][-U login][-P password][-d][dbname]\n");
  }
  
--- 172,178 ----
  static void
  usage(void)
  {
! 	fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-x nruns][-s scaling_factor][-n][-C][-v][-S][-N][-f filename][-l][-U login][-P password][-d][dbname]\n");
  	fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor][-U login][-P password][-d][dbname]\n");
  }
  
***************
*** 990,1013 ****
  static void
  printResults(
  			 int ttype, CState * state,
! 			 struct timeval * tv1, struct timeval * tv2,
! 			 struct timeval * tv3)
  {
- 	double		t1,
- 				t2;
- 	int			i;
- 	int			normal_xacts = 0;
  	char	   *s;
  
- 	for (i = 0; i < nclients; i++)
- 		normal_xacts += state[i].cnt;
- 
- 	t1 = (tv3->tv_sec - tv1->tv_sec) * 1000000.0 + (tv3->tv_usec - tv1->tv_usec);
- 	t1 = normal_xacts * 1000000.0 / t1;
- 
- 	t2 = (tv3->tv_sec - tv2->tv_sec) * 1000000.0 + (tv3->tv_usec - tv2->tv_usec);
- 	t2 = normal_xacts * 1000000.0 / t2;
- 
  	if (ttype == 0)
  		s = "TPC-B (sort of)";
  	else if (ttype == 2)
--- 993,1003 ----
  static void
  printResults(
  			 int ttype, CState * state,
! 			 double t1, double t2,
! 			 int normal_xacts, int curr_iter)
  {
  	char	   *s;
  
  	if (ttype == 0)
  		s = "TPC-B (sort of)";
  	else if (ttype == 2)
***************
*** 1017,1029 ****
  	else
  		s = "Custom query";
  
! 	printf("transaction type: %s\n", s);
! 	printf("scaling factor: %d\n", tps);
! 	printf("number of clients: %d\n", nclients);
! 	printf("number of transactions per client: %d\n", nxacts);
  	printf("number of transactions actually processed: %d/%d\n", normal_xacts, nxacts * nclients);
  	printf("tps = %f (including connections establishing)\n", t1);
  	printf("tps = %f (excluding connections establishing)\n", t2);
  }
  
  
--- 1007,1025 ----
  	else
  		s = "Custom query";
  
! 	if(curr_iter == 0)
! 	{
! 		printf("transaction type: %s\n", s);
! 		printf("scaling factor: %d\n", tps);
! 		printf("number of clients: %d\n", nclients);
! 		printf("number of transactions per client: %d\n", nxacts);
! 		printf("\n");
! 	}
  	printf("number of transactions actually processed: %d/%d\n", normal_xacts, nxacts * nclients);
  	printf("tps = %f (including connections establishing)\n", t1);
  	printf("tps = %f (excluding connections establishing)\n", t2);
+ 	if( curr_iter < nruns - 1 )
+ 		printf("\n");
  }
  
  
***************
*** 1039,1052 ****
  								 * 2: skip update of branches and tellers */
  	char	   *filename = NULL;
  
! 	CState	   *state;			/* status of clients */
  
! 	struct timeval tv1;			/* start up time */
! 	struct timeval tv2;			/* after establishing all connections to the
! 								 * backend */
! 	struct timeval tv3;			/* end time */
  
! 	int			i;
  
  	fd_set		input_mask;
  	int			nsocks;			/* return from select(2) */
--- 1035,1055 ----
  								 * 2: skip update of branches and tellers */
  	char	   *filename = NULL;
  
! 	int			i;
! 	double			t1_total = 0;
! 	double			t2_total = 0;
  
! 	double			t1s[MAXRUNS];
! 	double			t2s[MAXRUNS];
  
! 	double			t1_mean = 0;
! 	double			t2_mean = 0;
! 
! 	double			t1_variance = 0;
! 	double			t2_variance = 0;
! 
! 	double			t1_stddev = 0;
! 	double			t2_stddev = 0;
  
  	fd_set		input_mask;
  	int			nsocks;			/* return from select(2) */
***************
*** 1056,1063 ****
  	struct rlimit rlim;
  #endif
  
- 	PGconn	   *con;
- 	PGresult   *res;
  	char	   *env;
  
  	if ((env = getenv("PGHOST")) != NULL && *env != '\0')
--- 1059,1064 ----
***************
*** 1067,1073 ****
  	else if ((env = getenv("PGUSER")) != NULL && *env != '\0')
  		login = env;
  
! 	while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:U:P:CNSlf:")) != -1)
  	{
  		switch (c)
  		{
--- 1068,1074 ----
  	else if ((env = getenv("PGUSER")) != NULL && *env != '\0')
  		login = env;
  
! 	while ((c = getopt(argc, argv, "ih:nvp:dc:x:t:s:U:P:CNSlf:")) != -1)
  	{
  		switch (c)
  		{
***************
*** 1139,1144 ****
--- 1140,1153 ----
  					exit(1);
  				}
  				break;
+ 			case 'x':
+ 				nruns = atoi(optarg);
+ 				if(nruns <= 0 || nruns > MAXRUNS)
+ 				{
+ 					fprintf(stderr, "invalid number of runs: %d\n", nruns);
+ 					exit(1);
+ 				}
+ 				break;
  			case 'U':
  				login = optarg;
  				break;
***************
*** 1179,1195 ****
  		exit(0);
  	}
  
- 	remains = nclients;
- 
- 	state = (CState *) malloc(sizeof(CState) * nclients);
- 	if (state == NULL)
- 	{
- 		fprintf(stderr, "Couldn't allocate memory for state\n");
- 		exit(1);
- 	}
- 
- 	memset(state, 0, sizeof(*state) * nclients);
- 
  	if (use_log)
  	{
  		char		logpath[64];
--- 1188,1193 ----
***************
*** 1210,1435 ****
  			   pghost, pgport, nclients, nxacts, dbName);
  	}
  
! 	/* opening connection... */
! 	con = doConnect();
! 	if (con == NULL)
! 		exit(1);
! 
! 	if (PQstatus(con) == CONNECTION_BAD)
  	{
! 		fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
! 		fprintf(stderr, "%s", PQerrorMessage(con));
! 		exit(1);
! 	}
  
! 	if (ttype != 3)
! 	{
! 		/*
! 		 * get the scaling factor that should be same as count(*) from
! 		 * branches if this is not a custom query
! 		 */
! 		res = PQexec(con, "select count(*) from branches");
! 		if (PQresultStatus(res) != PGRES_TUPLES_OK)
! 		{
! 			fprintf(stderr, "%s", PQerrorMessage(con));
! 			exit(1);
! 		}
! 		tps = atoi(PQgetvalue(res, 0, 0));
! 		if (tps < 0)
! 		{
! 			fprintf(stderr, "count(*) from branches invalid (%d)\n", tps);
! 			exit(1);
! 		}
! 		PQclear(res);
! 	}
  
! 	if (!is_no_vacuum)
! 	{
! 		fprintf(stderr, "starting vacuum...");
! 		res = PQexec(con, "vacuum branches");
! 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
! 		{
! 			fprintf(stderr, "%s", PQerrorMessage(con));
  			exit(1);
- 		}
- 		PQclear(res);
  
! 		res = PQexec(con, "vacuum tellers");
! 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
  		{
  			fprintf(stderr, "%s", PQerrorMessage(con));
  			exit(1);
  		}
- 		PQclear(res);
  
! 		res = PQexec(con, "delete from history");
! 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
  		{
! 			fprintf(stderr, "%s", PQerrorMessage(con));
! 			exit(1);
  		}
! 		PQclear(res);
! 		res = PQexec(con, "vacuum history");
! 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
  		{
! 			fprintf(stderr, "%s", PQerrorMessage(con));
! 			exit(1);
! 		}
! 		PQclear(res);
! 
! 		fprintf(stderr, "end.\n");
! 
! 		if (is_full_vacuum)
! 		{
! 			fprintf(stderr, "starting full vacuum...");
! 			res = PQexec(con, "vacuum analyze accounts");
  			if (PQresultStatus(res) != PGRES_COMMAND_OK)
  			{
  				fprintf(stderr, "%s", PQerrorMessage(con));
  				exit(1);
  			}
  			PQclear(res);
  			fprintf(stderr, "end.\n");
  		}
! 	}
! 	PQfinish(con);
! 
! 	/* set random seed */
! 	gettimeofday(&tv1, NULL);
! 	srand((unsigned int) tv1.tv_usec);
  
! 	/* get start up time */
! 	gettimeofday(&tv1, NULL);
  
! 	if (is_connect == 0)
! 	{
! 		/* make connections to the database */
! 		for (i = 0; i < nclients; i++)
  		{
! 			state[i].id = i;
! 			if ((state[i].con = doConnect()) == NULL)
! 				exit(1);
  		}
- 	}
  
! 	/* time after connections set up */
! 	gettimeofday(&tv2, NULL);
  
! 	/* process bultin SQL scripts */
! 	switch (ttype)
! 	{
  			char		buf[128];
  
! 		case 0:
! 			sql_files[0] = process_builtin(tpc_b);
! 			snprintf(buf, sizeof(buf), "%d", 100000 * tps);
! 			sql_files[0][0]->argv[3] = strdup(buf);
! 			snprintf(buf, sizeof(buf), "%d", 1 * tps);
! 			sql_files[0][1]->argv[3] = strdup(buf);
! 			snprintf(buf, sizeof(buf), "%d", 10 * tps);
! 			sql_files[0][2]->argv[3] = strdup(buf);
! 			snprintf(buf, sizeof(buf), "%d", 10000 * tps);
! 			sql_files[0][3]->argv[3] = strdup(buf);
! 			num_files = 1;
! 			break;
! 		case 1:
! 			sql_files[0] = process_builtin(select_only);
! 			snprintf(buf, sizeof(buf), "%d", 100000 * tps);
! 			sql_files[0][0]->argv[3] = strdup(buf);
! 			num_files = 1;
! 			break;
! 		case 2:
! 			sql_files[0] = process_builtin(simple_update);
! 			snprintf(buf, sizeof(buf), "%d", 100000 * tps);
! 			sql_files[0][0]->argv[3] = strdup(buf);
! 			snprintf(buf, sizeof(buf), "%d", 1 * tps);
! 			sql_files[0][1]->argv[3] = strdup(buf);
! 			snprintf(buf, sizeof(buf), "%d", 10 * tps);
! 			sql_files[0][2]->argv[3] = strdup(buf);
! 			snprintf(buf, sizeof(buf), "%d", 10000 * tps);
! 			sql_files[0][3]->argv[3] = strdup(buf);
! 			num_files = 1;
! 			break;
! 		default:
! 			break;
! 	}
! 
! 	/* send start up queries in async manner */
! 	for (i = 0; i < nclients; i++)
! 	{
! 		state[i].use_file = getrand(0, num_files - 1);
! 		doCustom(state, i, debug);
! 	}
! 
! 	for (;;)
! 	{
! 		if (remains <= 0)
! 		{						/* all done ? */
! 			disconnect_all(state);
! 			/* get end time */
! 			gettimeofday(&tv3, NULL);
! 			printResults(ttype, state, &tv1, &tv2, &tv3);
! 			if (LOGFILE)
! 				fclose(LOGFILE);
! 			exit(0);
  		}
  
! 		FD_ZERO(&input_mask);
  
! 		maxsock = -1;
! 		for (i = 0; i < nclients; i++)
! 		{
! 			Command   **commands = sql_files[state[i].use_file];
  
! 			if (state[i].con && commands[state[i].state]->type != META_COMMAND)
  			{
! 				int			sock = PQsocket(state[i].con);
! 
! 				if (sock < 0)
  				{
  					disconnect_all(state);
  					exit(1);
  				}
! 				FD_SET(sock, &input_mask);
! 				if (maxsock < sock)
! 					maxsock = sock;
  			}
- 		}
  
! 		if (maxsock != -1)
! 		{
! 			if ((nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL,
! 							  (fd_set *) NULL, (struct timeval *) NULL)) < 0)
  			{
! 				if (errno == EINTR)
! 					continue;
! 				/* must be something wrong */
! 				disconnect_all(state);
! 				fprintf(stderr, "select failed: %s\n", strerror(errno));
! 				exit(1);
! 			}
! 			else if (nsocks == 0)
! 			{					/* timeout */
! 				fprintf(stderr, "select timeout\n");
! 				for (i = 0; i < nclients; i++)
  				{
! 					fprintf(stderr, "client %d:state %d cnt %d ecnt %d listen %d\n",
! 							i, state[i].state, state[i].cnt, state[i].ecnt, state[i].listen);
  				}
- 				exit(0);
  			}
  		}
  
! 		/* ok, backend returns reply */
! 		for (i = 0; i < nclients; i++)
! 		{
! 			Command   **commands = sql_files[state[i].use_file];
  
! 			if (state[i].con && (FD_ISSET(PQsocket(state[i].con), &input_mask)
! 						  || commands[state[i].state]->type == META_COMMAND))
! 			{
! 				doCustom(state, i, debug);
! 			}
  		}
  	}
  }
--- 1208,1493 ----
  			   pghost, pgport, nclients, nxacts, dbName);
  	}
  
! 	for (i = 0; i < nruns; i++)
  	{
! 		int j;
  
! 		PGconn		*con;
! 		PGresult	*res;
  
! 		static CState	*state;		/* status of clients */
! 
! 		struct timeval	tv1;		/* start up time */
! 		struct timeval	tv2;		/* after establishing all connections to the backend */
! 		struct timeval	tv3;		/* end time */
! 
! 		remains = nclients;
! 
! 		state = (CState *) malloc(sizeof(*state) * nclients);
! 		memset(state, 0, sizeof(*state) * nclients);
! 
! 		/* opening connection... */
! 		con = doConnect();
! 		if (con == NULL)
  			exit(1);
  
! 		if (PQstatus(con) == CONNECTION_BAD)
  		{
+ 			fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
  			fprintf(stderr, "%s", PQerrorMessage(con));
  			exit(1);
  		}
  
! 		if (ttype != 3)
  		{
! 			/*
! 			 * get the scaling factor that should be same as count(*) from
! 			 * branches if this is not a custom query
! 			 */
! 			res = PQexec(con, "select count(*) from branches");
! 			if (PQresultStatus(res) != PGRES_TUPLES_OK)
! 			{
! 				fprintf(stderr, "%s", PQerrorMessage(con));
! 				exit(1);
! 			}
! 			tps = atoi(PQgetvalue(res, 0, 0));
! 			if (tps < 0)
! 			{
! 				fprintf(stderr, "count(*) from branches invalid (%d)\n", tps);
! 				exit(1);
! 			}
! 			PQclear(res);
  		}
! 	
! 		if (!is_no_vacuum)
  		{
! 			fprintf(stderr, "starting vacuum...");
! 			res = PQexec(con, "vacuum branches");
! 			if (PQresultStatus(res) != PGRES_COMMAND_OK)
! 			{
! 				fprintf(stderr, "%s", PQerrorMessage(con));
! 				exit(1);
! 			}
! 			PQclear(res);
! 	
! 			res = PQexec(con, "vacuum tellers");
  			if (PQresultStatus(res) != PGRES_COMMAND_OK)
  			{
  				fprintf(stderr, "%s", PQerrorMessage(con));
  				exit(1);
  			}
  			PQclear(res);
+ 	
+ 			res = PQexec(con, "delete from history");
+ 			if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ 			{
+ 				fprintf(stderr, "%s", PQerrorMessage(con));
+ 				exit(1);
+ 			}
+ 			PQclear(res);
+ 			res = PQexec(con, "vacuum history");
+ 			if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ 			{
+ 				fprintf(stderr, "%s", PQerrorMessage(con));
+ 				exit(1);
+ 			}
+ 			PQclear(res);
+ 	
  			fprintf(stderr, "end.\n");
+ 	
+ 			if (is_full_vacuum)
+ 			{
+ 				fprintf(stderr, "starting full vacuum...");
+ 				res = PQexec(con, "vacuum analyze accounts");
+ 				if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ 				{
+ 					fprintf(stderr, "%s", PQerrorMessage(con));
+ 					exit(1);
+ 				}
+ 				PQclear(res);
+ 				fprintf(stderr, "end.\n");
+ 			}
  		}
! 		PQfinish(con);
! 	
! 		/* set random seed */
! 		gettimeofday(&tv1, NULL);
! 		srand((unsigned int) tv1.tv_usec);
  
! 		/* get start up time */
! 		gettimeofday(&tv1, NULL);
  
! 		if (is_connect == 0)
  		{
! 			/* make connections to the database */
! 			for (j = 0; j < nclients; j++)
! 			{
! 				state[j].id = j;
! 				if ((state[j].con = doConnect()) == NULL)
! 					exit(1);
! 			}
  		}
  
! 		/* time after connections set up */
! 		gettimeofday(&tv2, NULL);
  
! 		/* process bultin SQL scripts */
! 		switch (ttype)
! 		{
  			char		buf[128];
  
! 			case 0:
! 				sql_files[0] = process_builtin(tpc_b);
! 				snprintf(buf, sizeof(buf), "%d", 100000 * tps);
! 				sql_files[0][0]->argv[3] = strdup(buf);
! 				snprintf(buf, sizeof(buf), "%d", 1 * tps);
! 				sql_files[0][1]->argv[3] = strdup(buf);
! 				snprintf(buf, sizeof(buf), "%d", 10 * tps);
! 				sql_files[0][2]->argv[3] = strdup(buf);
! 				snprintf(buf, sizeof(buf), "%d", 10000 * tps);
! 				sql_files[0][3]->argv[3] = strdup(buf);
! 				num_files = 1;
! 				break;
! 			case 1:
! 				sql_files[0] = process_builtin(select_only);
! 				snprintf(buf, sizeof(buf), "%d", 100000 * tps);
! 				sql_files[0][0]->argv[3] = strdup(buf);
! 				num_files = 1;
! 				break;
! 			case 2:
! 				sql_files[0] = process_builtin(simple_update);
! 				snprintf(buf, sizeof(buf), "%d", 100000 * tps);
! 				sql_files[0][0]->argv[3] = strdup(buf);
! 				snprintf(buf, sizeof(buf), "%d", 1 * tps);
! 				sql_files[0][1]->argv[3] = strdup(buf);
! 				snprintf(buf, sizeof(buf), "%d", 10 * tps);
! 				sql_files[0][2]->argv[3] = strdup(buf);
! 				snprintf(buf, sizeof(buf), "%d", 10000 * tps);
! 				sql_files[0][3]->argv[3] = strdup(buf);
! 				num_files = 1;
! 				break;
! 			default:
! 				break;
  		}
+ 	
+ 		/* send start up queries in async manner */
+ 		for (j = 0; j < nclients; j++)
+ 		{
+ 			state[j].use_file = getrand(0, num_files - 1);
+ 			doCustom(state, j, debug);
+ 		}
+ 	
+ 		for (;;)
+ 		{
+ 			if (remains <= 0)
+ 			{						/* all done ? */
+ 				int k;
+ 				double t1;
+ 				double t2;
+ 				int normal_xacts = 0;
  
! 				disconnect_all(state);
! 				/* get end time */
! 				gettimeofday(&tv3, NULL);
  
! 				for (k = 0; k < nclients; k++)
! 					normal_xacts += state[k].cnt;
! 				t1 = (tv3.tv_sec - tv1.tv_sec) * 1000000.0 + (tv3.tv_usec - tv1.tv_usec);
! 				t1 = normal_xacts * 1000000.0 / t1;
! 				t1s[i] = t1;
! 				t1_total += t1;
! 
! 				t2 = (tv3.tv_sec - tv2.tv_sec) * 1000000.0 + (tv3.tv_usec - tv2.tv_usec);
! 				t2 = normal_xacts * 1000000.0 / t2;
! 				t2s[i] = t2;
! 				t2_total += t2;
! 
! 				printResults(ttype, state, t1, t2, normal_xacts, i);
! 				if (LOGFILE)
! 					fclose(LOGFILE);
! 				break;
! 			}
! 	
! 			FD_ZERO(&input_mask);
! 	
! 			maxsock = -1;
! 			for (j = 0; j < nclients; j++)
! 			{
! 				Command   **commands = sql_files[state[j].use_file];
! 	
! 				if (state[j].con && commands[state[j].state]->type != META_COMMAND)
! 				{
! 					int			sock = PQsocket(state[j].con);
! 	
! 					if (sock < 0)
! 					{
! 						disconnect_all(state);
! 						exit(1);
! 					}
! 					FD_SET(sock, &input_mask);
! 					if (maxsock < sock)
! 						maxsock = sock;
! 				}
! 			}
  
! 			if (maxsock != -1)
  			{
! 				if ((nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL,
! 								  (fd_set *) NULL, (struct timeval *) NULL)) < 0)
  				{
+ 					if (errno == EINTR)
+ 						continue;
+ 					/* must be something wrong */
  					disconnect_all(state);
+ 					fprintf(stderr, "select failed: %s\n", strerror(errno));
  					exit(1);
  				}
! 				else if (nsocks == 0)
! 				{					/* timeout */
! 					fprintf(stderr, "select timeout\n");
! 					for (j = 0; j < nclients; j++)
! 					{
! 						fprintf(stderr, "client %d:state %d cnt %d ecnt %d listen %d\n",
! 								j, state[j].state, state[j].cnt, state[j].ecnt, state[j].listen);
! 					}
! 					exit(0);
! 				}
  			}
  
! 			/* ok, backend returns reply */
! 			for (j = 0; j < nclients; j++)
  			{
! 				Command   **commands = sql_files[state[j].use_file];
! 	
! 				if (state[j].con && (FD_ISSET(PQsocket(state[j].con), &input_mask)
! 							  || commands[state[j].state]->type == META_COMMAND))
  				{
! 					doCustom(state, j, debug);
  				}
  			}
  		}
+ 	}
  
! 	if( nruns > 1 ) {
! 		t1_mean = t1_total / nruns;
! 		for (i = 0; i < nruns; i++) {
! 			t1_variance += (t1s[i] - t1_mean) * (t1s[i] - t1_mean);
! 		}
! 		t1_stddev = sqrt(t1_variance/nruns);
  
! 		t2_mean = t2_total /nruns;
! 		for (i = 0; i < nruns; i++) {
! 			t2_variance += (t2s[i] - t2_mean) * (t2s[i] - t2_mean);
  		}
+ 		t2_stddev = sqrt(t2_variance/nruns);
+ 
+ 		printf("\n");
+ 		printf("mean tps = %f (including connections establishing)\n", t1_mean);
+ 		printf("standard deviation = %f\n", t1_stddev);
+ 		printf("\n");
+ 		printf("mean tps = %f (excluding connections establishing)\n", t2_mean);
+ 		printf("standard deviation = %f\n", t2_stddev);
  	}
+ 
+ 	exit(0);
  }
