/* * derived from testlibpq3.c */ #include #include #include #include #include "libpq-fe.h" #define TABLESIZE 1000000 /* rows in table */ #define ITERS 10 static void exit_nicely(PGconn *conn) { PQfinish(conn); exit(1); } static char * elapsed_time(struct timeval start_t, struct timeval elapse_t) { static char buf[64]; if (elapse_t.tv_usec < start_t.tv_usec) { elapse_t.tv_sec--; elapse_t.tv_usec += 1000000; } sprintf(buf, "%3ld.%06ld", (long) (elapse_t.tv_sec - start_t.tv_sec), (long) (elapse_t.tv_usec - start_t.tv_usec)); return buf; } static void do_cmd(PGconn *conn, const char *cmd) { PGresult *res; struct timeval start_t; struct timeval elapse_t; gettimeofday(&start_t, NULL); res = PQexec(conn, cmd); gettimeofday(&elapse_t, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "%s\nCommand failed: %s", cmd, PQerrorMessage(conn)); PQclear(res); exit_nicely(conn); } printf("executed %-.6s in %s sec\n", cmd, elapsed_time(start_t, elapse_t)); fflush(stdout); PQclear(res); } static void do_select(PGconn *conn, const char *cmd) { PGresult *res; struct timeval start_t; struct timeval elapse_t; gettimeofday(&start_t, NULL); res = PQexec(conn, cmd); gettimeofday(&elapse_t, NULL); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "%s\nCommand failed: %s", cmd, PQerrorMessage(conn)); PQclear(res); exit_nicely(conn); } printf("retrieved %4s tuples in %s sec\n", PQgetvalue(res, 0, 0), elapsed_time(start_t, elapse_t)); fflush(stdout); PQclear(res); } int main(int argc, char **argv) { const char *conninfo; PGconn *conn; PGresult *res; char cmd[1024]; int i; /* * If the user supplies a parameter on the command line, use it as the * conninfo string; otherwise default to setting dbname=postgres and using * environment variables or defaults for all other connection parameters. */ if (argc > 1) conninfo = argv[1]; else conninfo = "dbname = postgres"; /* Make a connection to the database */ conn = PQconnectdb(conninfo); /* Check to see that the backend connection was successfully made */ if (PQstatus(conn) != CONNECTION_OK) { fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn)); exit_nicely(conn); } /* Ignore any error while dropping old table */ res = PQexec(conn, "DROP TABLE testtab"); PQclear(res); /* Set up test table */ do_cmd(conn, "CREATE TABLE testtab(k int, d text)"); sprintf(cmd, "INSERT INTO testtab " "SELECT x, repeat('x',350) FROM generate_series(1,%d) x", TABLESIZE); do_cmd(conn, cmd); do_cmd(conn, "CREATE INDEX testtabi ON testtab(k)"); do_cmd(conn, "CLUSTER testtab USING testtabi"); do_cmd(conn, "VACUUM ANALYZE testtab"); for (i = 0; i < ITERS; i++) { int st; sprintf(cmd, "DELETE FROM testtab WHERE random() < 1.0/50"); do_cmd(conn, cmd); do_cmd(conn, "VACUUM testtab"); sprintf(cmd, "INSERT INTO testtab " "SELECT (random() * %d)::int, repeat('x',350) " "FROM generate_series(1,%d)", TABLESIZE, TABLESIZE/50); do_cmd(conn, cmd); st = ((double) random() * (TABLESIZE - 1000)) / 0x7FFFFFFF; sprintf(cmd, "SELECT count(*) FROM testtab " "WHERE k BETWEEN %d AND %d", st, st + 1000); do_select(conn, cmd); do_select(conn, "SELECT count(*) FROM testtab"); } /* close the connection to the database and cleanup */ PQfinish(conn); return 0; }